Mercurial > projects > ddmd
annotate dmd/SliceExp.d @ 191:52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
Also changed Array allocation policy:
Now doesn't reallocate but malloc's, followed by a memcpy (no free).
(this fixes a crash while compiling druntime. Same bug in dmd)
author | korDen@korDen-pc |
---|---|
date | Sun, 25 Mar 2012 03:11:12 +0400 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
72 | 1 module dmd.SliceExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.expression.ArrayLength; | |
6 import dmd.backend.elem; | |
7 import dmd.UnaExp; | |
8 import dmd.Identifier; | |
9 import dmd.IdentifierExp; | |
10 import dmd.ArrayExp; | |
11 import dmd.STC; | |
0 | 12 import dmd.InterState; |
13 import dmd.ScopeDsymbol; | |
14 import dmd.WANT; | |
178 | 15 import dmd.Util; |
0 | 16 import dmd.ArrayScopeSymbol; |
17 import dmd.CallExp; | |
18 import dmd.DotIdExp; | |
19 import dmd.Id; | |
20 import dmd.expression.Util; | |
21 import dmd.TypeTuple; | |
22 import dmd.TupleExp; | |
23 import dmd.TypeStruct; | |
24 import dmd.TypeClass; | |
25 import dmd.TY; | |
26 import dmd.Type; | |
72 | 27 import dmd.AggregateDeclaration; |
28 import dmd.OutBuffer; | |
29 import dmd.Loc; | |
30 import dmd.Scope; | |
31 import dmd.InlineCostState; | |
0 | 32 import dmd.VarDeclaration; |
33 import dmd.ErrorExp; | |
34 import dmd.TypeExp; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
35 import dmd.Parameter; |
72 | 36 import dmd.ExpInitializer; |
37 import dmd.IRState; | |
38 import dmd.InlineDoState; | |
39 import dmd.ArrayTypes; | |
40 import dmd.HdrGenState; | |
41 import dmd.InlineScanState; | |
0 | 42 import dmd.TOK; |
43 import dmd.TypeSArray; | |
44 import dmd.GlobalExpressions; | |
45 import dmd.Global; | |
46 import dmd.PREC; | |
47 | |
48 import dmd.expression.Slice; | |
49 import dmd.expression.Util; | |
50 | |
51 import dmd.backend.Util; | |
52 import dmd.backend.Symbol; | |
53 import dmd.backend.OPER; | |
54 import dmd.backend.TYM; | |
55 import dmd.codegen.Util; | |
56 | |
72 | 57 import core.stdc.string; |
58 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
59 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
60 |
0 | 61 class SliceExp : UnaExp |
62 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
63 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
64 |
0 | 65 Expression upr; // null if implicit 0 |
66 Expression lwr; // null if implicit [length - 1] | |
67 | |
68 VarDeclaration lengthVar = null; | |
69 | |
70 this(Loc loc, Expression e1, Expression lwr, Expression upr) | |
72 | 71 { |
178 | 72 register(); |
0 | 73 super(loc, TOK.TOKslice, SliceExp.sizeof, e1); |
74 this.upr = upr; | |
75 this.lwr = lwr; | |
76 } | |
77 | |
72 | 78 override Expression syntaxCopy() |
0 | 79 { |
72 | 80 Expression lwr = null; |
81 if (this.lwr) | |
82 lwr = this.lwr.syntaxCopy(); | |
83 | |
84 Expression upr = null; | |
85 if (this.upr) | |
86 upr = this.upr.syntaxCopy(); | |
87 | |
53 | 88 return new SliceExp(loc, e1.syntaxCopy(), lwr, upr); |
0 | 89 } |
90 | |
72 | 91 override Expression semantic(Scope sc) |
0 | 92 { |
93 Expression e; | |
94 AggregateDeclaration ad; | |
95 //FuncDeclaration fd; | |
96 ScopeDsymbol sym; | |
97 | |
98 version (LOGSEMANTIC) { | |
99 printf("SliceExp.semantic('%s')\n", toChars()); | |
100 } | |
101 if (type) | |
102 return this; | |
103 | |
104 UnaExp.semantic(sc); | |
105 e1 = resolveProperties(sc, e1); | |
106 | |
107 e = this; | |
108 | |
109 Type t = e1.type.toBasetype(); | |
110 if (t.ty == Tpointer) | |
111 { | |
112 if (!lwr || !upr) | |
113 error("need upper and lower bound to slice pointer"); | |
114 } | |
115 else if (t.ty == Tarray) | |
116 { | |
117 } | |
118 else if (t.ty == Tsarray) | |
119 { | |
120 } | |
121 else if (t.ty == Tclass) | |
122 { | |
123 ad = (cast(TypeClass)t).sym; | |
124 goto L1; | |
125 } | |
126 else if (t.ty == Tstruct) | |
127 { | |
128 ad = (cast(TypeStruct)t).sym; | |
129 | |
130 L1: | |
131 if (search_function(ad, Id.slice)) | |
132 { | |
133 // Rewrite as e1.slice(lwr, upr) | |
134 e = new DotIdExp(loc, e1, Id.slice); | |
135 | |
136 if (lwr) | |
137 { | |
138 assert(upr); | |
139 e = new CallExp(loc, e, lwr, upr); | |
140 } | |
141 else | |
178 | 142 { |
0 | 143 assert(!upr); |
144 e = new CallExp(loc, e); | |
145 } | |
146 e = e.semantic(sc); | |
147 return e; | |
148 } | |
149 goto Lerror; | |
150 } | |
151 else if (t.ty == Ttuple) | |
152 { | |
153 if (!lwr && !upr) | |
154 return e1; | |
155 if (!lwr || !upr) | |
156 { error("need upper and lower bound to slice tuple"); | |
157 goto Lerror; | |
158 } | |
159 } | |
160 else | |
161 goto Lerror; | |
162 | |
163 { | |
164 Scope sc2 = sc; | |
165 if (t.ty == Tsarray || t.ty == Tarray || t.ty == Ttuple) | |
166 { | |
167 sym = new ArrayScopeSymbol(sc, this); | |
168 sym.loc = loc; | |
169 sym.parent = sc.scopesym; | |
170 sc2 = sc.push(sym); | |
171 } | |
172 | |
173 if (lwr) | |
178 | 174 { |
0 | 175 lwr = lwr.semantic(sc2); |
176 lwr = resolveProperties(sc2, lwr); | |
177 lwr = lwr.implicitCastTo(sc2, Type.tsize_t); | |
178 } | |
179 if (upr) | |
178 | 180 { |
0 | 181 upr = upr.semantic(sc2); |
182 upr = resolveProperties(sc2, upr); | |
183 upr = upr.implicitCastTo(sc2, Type.tsize_t); | |
184 } | |
185 | |
186 if (sc2 != sc) | |
187 sc2.pop(); | |
188 } | |
189 | |
190 if (t.ty == Ttuple) | |
191 { | |
192 lwr = lwr.optimize(WANTvalue); | |
193 upr = upr.optimize(WANTvalue); | |
194 ulong i1 = lwr.toUInteger(); | |
195 ulong i2 = upr.toUInteger(); | |
196 | |
197 size_t length; | |
198 TupleExp te; | |
199 TypeTuple tup; | |
200 | |
201 if (e1.op == TOKtuple) // slicing an expression tuple | |
178 | 202 { |
0 | 203 te = cast(TupleExp)e1; |
204 length = te.exps.dim; | |
205 } | |
206 else if (e1.op == TOKtype) // slicing a type tuple | |
178 | 207 { |
0 | 208 tup = cast(TypeTuple)t; |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
209 length = Parameter.dim(tup.arguments); |
0 | 210 } |
211 else | |
212 assert(0); | |
213 | |
214 if (i1 <= i2 && i2 <= length) | |
178 | 215 { |
0 | 216 size_t j1 = cast(size_t) i1; |
217 size_t j2 = cast(size_t) i2; | |
218 | |
219 if (e1.op == TOKtuple) | |
178 | 220 { |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
221 auto exps = new Expressions; |
0 | 222 exps.setDim(j2 - j1); |
223 for (size_t i = 0; i < j2 - j1; i++) | |
178 | 224 { |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
225 auto e2 = te.exps[j1 + i]; |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
226 exps[i] = e2; |
0 | 227 } |
228 e = new TupleExp(loc, exps); | |
229 } | |
230 else | |
178 | 231 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
232 auto args = new Parameters; |
0 | 233 args.reserve(j2 - j1); |
234 for (size_t i = j1; i < j2; i++) | |
178 | 235 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
236 auto arg = Parameter.getNth(tup.arguments, i); |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
237 args.push(arg); |
0 | 238 } |
239 e = new TypeExp(e1.loc, new TypeTuple(args)); | |
240 } | |
241 e = e.semantic(sc); | |
242 } | |
243 else | |
244 { | |
245 error("string slice [%ju .. %ju] is out of bounds", i1, i2); | |
246 e = new ErrorExp(); | |
247 } | |
248 return e; | |
249 } | |
250 | |
251 if (t.ty == Tarray) | |
252 { | |
253 type = e1.type; | |
254 } | |
255 else | |
256 type = t.nextOf().arrayOf(); | |
257 return e; | |
258 | |
259 Lerror: | |
260 string s; | |
261 if (t.ty == Tvoid) | |
262 s = e1.toChars(); | |
263 else | |
264 s = t.toChars(); | |
265 error("%s cannot be sliced with []", s); | |
266 e = new ErrorExp(); | |
267 return e; | |
268 } | |
269 | |
72 | 270 override void checkEscape() |
0 | 271 { |
272 e1.checkEscape(); | |
273 } | |
178 | 274 |
135 | 275 override void checkEscapeRef() |
276 { | |
277 e1.checkEscapeRef(); | |
278 } | |
0 | 279 |
280 version (DMDV2) { | |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
281 override bool isLvalue() |
0 | 282 { |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
283 return true; |
0 | 284 } |
285 } | |
72 | 286 override Expression toLvalue(Scope sc, Expression e) |
0 | 287 { |
288 return this; | |
289 } | |
290 | |
72 | 291 override Expression modifiableLvalue(Scope sc, Expression e) |
0 | 292 { |
293 error("slice expression %s is not a modifiable lvalue", toChars()); | |
294 return this; | |
295 } | |
296 | |
72 | 297 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 298 { |
299 expToCBuffer(buf, hgs, e1, precedence[op]); | |
300 buf.writeByte('['); | |
301 if (upr || lwr) | |
302 { | |
303 if (lwr) | |
304 expToCBuffer(buf, hgs, lwr, PREC.PREC_assign); | |
305 else | |
306 buf.writeByte('0'); | |
307 buf.writestring(".."); | |
308 if (upr) | |
309 expToCBuffer(buf, hgs, upr, PREC.PREC_assign); | |
310 else | |
311 buf.writestring("length"); // BUG: should be array.length | |
312 } | |
313 buf.writeByte(']'); | |
314 } | |
315 | |
72 | 316 override Expression optimize(int result) |
0 | 317 { |
318 Expression e; | |
319 | |
320 //printf("SliceExp::optimize(result = %d) %s\n", result, toChars()); | |
321 e = this; | |
322 e1 = e1.optimize(WANTvalue | (result & WANTinterpret)); | |
323 if (!lwr) | |
178 | 324 { |
0 | 325 if (e1.op == TOKstring) |
178 | 326 { |
0 | 327 // Convert slice of string literal into dynamic array |
328 Type t = e1.type.toBasetype(); | |
329 if (t.nextOf()) | |
330 e = e1.castTo(null, t.nextOf().arrayOf()); | |
331 } | |
332 return e; | |
333 } | |
334 e1 = fromConstInitializer(result, e1); | |
335 lwr = lwr.optimize(WANTvalue | (result & WANTinterpret)); | |
336 upr = upr.optimize(WANTvalue | (result & WANTinterpret)); | |
337 e = Slice(type, e1, lwr, upr); | |
338 if (e is EXP_CANT_INTERPRET) | |
339 e = this; | |
340 //printf("-SliceExp::optimize() %s\n", e->toChars()); | |
341 return e; | |
342 } | |
343 | |
72 | 344 override Expression interpret(InterState istate) |
0 | 345 { |
72 | 346 Expression e; |
347 Expression e1; | |
348 Expression lwr; | |
349 Expression upr; | |
350 | |
351 version (LOG) { | |
352 printf("SliceExp.interpret() %s\n", toChars()); | |
353 } | |
354 e1 = this.e1.interpret(istate); | |
355 if (e1 is EXP_CANT_INTERPRET) | |
356 goto Lcant; | |
357 if (!this.lwr) | |
358 { | |
359 e = e1.castTo(null, type); | |
360 return e.interpret(istate); | |
361 } | |
362 | |
363 /* Set the $ variable | |
364 */ | |
365 e = ArrayLength(Type.tsize_t, e1); | |
366 if (e is EXP_CANT_INTERPRET) | |
367 goto Lcant; | |
368 if (lengthVar) | |
369 lengthVar.value = e; | |
370 | |
371 /* Evaluate lower and upper bounds of slice | |
372 */ | |
373 lwr = this.lwr.interpret(istate); | |
374 if (lwr is EXP_CANT_INTERPRET) | |
375 goto Lcant; | |
376 upr = this.upr.interpret(istate); | |
377 if (upr is EXP_CANT_INTERPRET) | |
378 goto Lcant; | |
379 | |
380 return Slice(type, e1, lwr, upr); | |
381 | |
382 Lcant: | |
63 | 383 return EXP_CANT_INTERPRET; |
0 | 384 } |
385 | |
72 | 386 override void dump(int indent) |
0 | 387 { |
388 assert(false); | |
389 } | |
390 | |
72 | 391 override elem* toElem(IRState* irs) |
0 | 392 { |
393 //printf("SliceExp.toElem()\n"); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
394 auto t1 = e1.type.toBasetype(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
395 auto e = e1.toElem(irs); |
0 | 396 if (lwr) |
397 { | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
398 auto einit = resolveLengthVar(lengthVar, &e, t1); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
399 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
400 int sz = cast(uint)t1.nextOf().size(); |
0 | 401 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
402 auto elwr = lwr.toElem(irs); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
403 auto eupr = upr.toElem(irs); |
0 | 404 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
405 auto elwr2 = el_same(&elwr); |
0 | 406 |
407 // Create an array reference where: | |
408 // length is (upr - lwr) | |
409 // pointer is (ptr + lwr*sz) | |
410 // Combine as (length pair ptr) | |
411 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
412 if (irs.arrayBoundsCheck()) |
0 | 413 { |
414 // Checks (unsigned compares): | |
415 // upr <= array.length | |
416 // lwr <= upr | |
417 | |
418 elem *c1; | |
419 elem *c2; | |
420 elem *ea; | |
421 elem *eb; | |
422 elem *eupr2; | |
423 elem *elength; | |
424 | |
425 if (t1.ty == Tpointer) | |
426 { | |
427 // Just do lwr <= upr check | |
428 | |
429 eupr2 = el_same(&eupr); | |
430 eupr2.Ety = TYuint; // make sure unsigned comparison | |
431 c1 = el_bin(OPle, TYint, elwr2, eupr2); | |
432 c1 = el_combine(eupr, c1); | |
433 goto L2; | |
434 } | |
435 else if (t1.ty == Tsarray) | |
178 | 436 { |
0 | 437 TypeSArray tsa = cast(TypeSArray)t1; |
438 ulong length = tsa.dim.toInteger(); | |
439 | |
440 elength = el_long(TYuint, length); | |
441 goto L1; | |
442 } | |
443 else if (t1.ty == Tarray) | |
444 { | |
445 if (lengthVar) | |
446 elength = el_var(lengthVar.toSymbol()); | |
447 else | |
448 { | |
449 elength = e; | |
450 e = el_same(&elength); | |
451 elength = el_una(OP64_32, TYuint, elength); | |
452 } | |
453 L1: | |
454 eupr2 = el_same(&eupr); | |
455 c1 = el_bin(OPle, TYint, eupr, elength); | |
456 eupr2.Ety = TYuint; // make sure unsigned comparison | |
457 c2 = el_bin(OPle, TYint, elwr2, eupr2); | |
458 c1 = el_bin(OPandand, TYint, c1, c2); // (c1 && c2) | |
459 | |
460 L2: | |
461 // Construct: (c1 || ModuleArray(line)) | |
462 Symbol* sassert; | |
463 | |
464 sassert = irs.blx.module_.toModuleArray(); | |
465 ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); | |
466 eb = el_bin(OPoror,TYvoid,c1,ea); | |
467 elwr = el_combine(elwr, eb); | |
468 | |
469 elwr2 = el_copytree(elwr2); | |
470 eupr = el_copytree(eupr2); | |
471 } | |
472 } | |
473 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
474 auto eptr = array_toPtr(e1.type, e); |
0 | 475 |
476 elem *elength = el_bin(OPmin, TYint, eupr, elwr2); | |
477 eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz))); | |
478 | |
479 e = el_pair(TYullong, elength, eptr); | |
480 e = el_combine(elwr, e); | |
481 e = el_combine(einit, e); | |
482 } | |
483 else if (t1.ty == Tsarray) | |
484 { | |
485 e = sarray_toDarray(loc, t1, null, e); | |
486 } | |
487 | |
488 el_setLoc(e,loc); | |
489 return e; | |
490 } | |
491 | |
72 | 492 override void scanForNestedRef(Scope sc) |
0 | 493 { |
72 | 494 e1.scanForNestedRef(sc); |
495 | |
496 if (lengthVar) | |
178 | 497 { |
72 | 498 //printf("lengthVar\n"); |
499 lengthVar.parent = sc.parent; | |
500 } | |
501 if (lwr) | |
502 lwr.scanForNestedRef(sc); | |
503 if (upr) | |
64 | 504 upr.scanForNestedRef(sc); |
0 | 505 } |
506 | |
72 | 507 override void buildArrayIdent(OutBuffer buf, Expressions arguments) |
0 | 508 { |
72 | 509 buf.writestring("Slice"); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
510 arguments.shift(this); |
0 | 511 } |
512 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
513 override Expression buildArrayLoop(Parameters fparams) |
0 | 514 { |
72 | 515 Identifier id = Identifier.generateId("p", fparams.dim); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
516 auto param = new Parameter(STCconst, type, id, null); |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
517 fparams.shift(param); |
72 | 518 Expression e = new IdentifierExp(Loc(0), id); |
519 Expressions arguments = new Expressions(); | |
520 Expression index = new IdentifierExp(Loc(0), Id.p); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
521 arguments.push(index); |
72 | 522 e = new ArrayExp(Loc(0), e, arguments); |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
523 return e; |
0 | 524 } |
525 | |
72 | 526 override int inlineCost(InlineCostState* ics) |
0 | 527 { |
528 int cost = 1 + e1.inlineCost(ics); | |
529 if (lwr) | |
530 cost += lwr.inlineCost(ics); | |
531 if (upr) | |
532 cost += upr.inlineCost(ics); | |
533 return cost; | |
534 } | |
535 | |
72 | 536 override Expression doInline(InlineDoState ids) |
0 | 537 { |
538 SliceExp are = cast(SliceExp)copy(); | |
539 | |
540 are.e1 = e1.doInline(ids); | |
541 | |
542 if (lengthVar) | |
178 | 543 { |
0 | 544 //printf("lengthVar\n"); |
545 VarDeclaration vd = lengthVar; | |
546 ExpInitializer ie; | |
547 ExpInitializer ieto; | |
548 VarDeclaration vto; | |
549 | |
178 | 550 vto = cloneThis(vd); |
551 | |
0 | 552 vto.parent = ids.parent; |
553 vto.csym = null; | |
554 vto.isym = null; | |
555 | |
556 ids.from.push(cast(void*)vd); | |
557 ids.to.push(cast(void*)vto); | |
558 | |
559 if (vd.init) | |
560 { | |
561 ie = vd.init.isExpInitializer(); | |
562 assert(ie); | |
563 ieto = new ExpInitializer(ie.loc, ie.exp.doInline(ids)); | |
564 vto.init = ieto; | |
565 } | |
566 | |
567 are.lengthVar = vto; | |
568 } | |
569 | |
570 if (lwr) | |
571 are.lwr = lwr.doInline(ids); | |
572 if (upr) | |
573 are.upr = upr.doInline(ids); | |
574 return are; | |
575 } | |
576 | |
72 | 577 override Expression inlineScan(InlineScanState* iss) |
0 | 578 { |
579 e1 = e1.inlineScan(iss); | |
580 if (lwr) | |
581 lwr = lwr.inlineScan(iss); | |
582 if (upr) | |
583 upr = upr.inlineScan(iss); | |
584 return this; | |
585 } | |
586 } | |
587 |