| 2110 | 2110 | { |
|---|
| 2111 | 2111 | arg->type = arg->type->semantic(loc, sc); |
|---|
| 2112 | 2112 | lwr = lwr->implicitCastTo(sc, arg->type); |
|---|
| 2113 | 2113 | upr = upr->implicitCastTo(sc, arg->type); |
|---|
| 2114 | 2114 | } |
|---|
| 2115 | 2115 | else |
|---|
| 2116 | 2116 | { |
|---|
| 2117 | 2117 | /* Must infer types from lwr and upr |
|---|
| 2118 | 2118 | */ |
|---|
| 2119 | 2119 | Type *tlwr = lwr->type->toBasetype(); |
|---|
| 2120 | 2120 | if (tlwr->ty == Tstruct || tlwr->ty == Tclass) |
|---|
| 2121 | 2121 | { |
|---|
| 2122 | 2122 | /* Just picking the first really isn't good enough. |
|---|
| 2123 | 2123 | */ |
|---|
| 2124 | 2124 | arg->type = lwr->type->mutableOf(); |
|---|
| 2125 | 2125 | } |
|---|
| 2126 | 2126 | else |
|---|
| 2127 | 2127 | { |
|---|
| 2128 | 2128 | AddExp ea(loc, lwr, upr); |
|---|
| 2129 | 2129 | Expression *e = ea.typeCombine(sc); |
|---|
| 2132 | 2130 | arg->type = ea.type->mutableOf(); |
|---|
| 2133 | 2131 | lwr = ea.e1; |
|---|
| 2134 | 2132 | upr = ea.e2; |
|---|
| 2135 | 2133 | } |
|---|
| 2136 | 2134 | } |
|---|
| 2137 | 2135 | #if 1 |
|---|
| 2138 | 2136 | /* Convert to a for loop: |
|---|
| 2139 | 2137 | * foreach (key; lwr .. upr) => |
|---|
| 2140 | 2138 | * for (auto key = lwr, auto tmp = upr; key < tmp; ++key) |
|---|
| 2141 | 2139 | * |
|---|
| 2142 | 2140 | * foreach_reverse (key; lwr .. upr) => |
|---|
| 2143 | 2141 | * for (auto tmp = lwr, auto key = upr; key-- > tmp;) |
|---|
| 2144 | 2142 | */ |
|---|
| 2145 | 2143 | |
|---|
| 2146 | 2144 | ExpInitializer *ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr); |
|---|
| 2147 | 2145 | key = new VarDeclaration(loc, arg->type, arg->ident, ie); |
|---|
| 2148 | 2146 | |
|---|
| 2149 | 2147 | Identifier *id = Lexer::uniqueId("__limit"); |
|---|
| 2150 | 2148 | ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr); |
|---|
| 2151 | 2149 | VarDeclaration *tmp = new VarDeclaration(loc, arg->type, id, ie); |
|---|