Mercurial > projects > ddmd
annotate dmd/ArrayInitializer.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 |
---|---|
0 | 1 module dmd.ArrayInitializer; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.ArrayTypes; |
5 import dmd.Type; | |
79 | 6 import dmd.TypeAArray; |
0 | 7 import dmd.TypeNext; |
8 import dmd.Array; | |
9 import dmd.Loc; | |
10 import dmd.Initializer; | |
11 import dmd.WANT; | |
12 import dmd.Util; | |
13 import dmd.TY; | |
14 import dmd.TypeSArray; | |
15 import dmd.IntegerExp; | |
16 import dmd.Expression; | |
17 import dmd.ArrayLiteralExp; | |
156 | 18 import dmd.AssocArrayLiteralExp; |
0 | 19 import dmd.Scope; |
20 import dmd.ErrorExp; | |
21 import dmd.OutBuffer; | |
22 import dmd.HdrGenState; | |
23 | |
24 import dmd.backend.dt_t; | |
25 import dmd.backend.Util; | |
26 import dmd.codegen.Util; | |
27 import dmd.backend.TYM; | |
28 import dmd.backend.Symbol; | |
29 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 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
|
31 |
0 | 32 class ArrayInitializer : Initializer |
33 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 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
|
35 |
0 | 36 Expressions index; // indices |
37 Initializers value; // of Initializer *'s | |
38 uint dim = 0; // length of array being initialized | |
39 Type type = null; // type that array will be used to initialize | |
40 int sem = 0; // !=0 if semantic() is run | |
41 | |
42 this(Loc loc) | |
43 { | |
178 | 44 register(); |
0 | 45 super(loc); |
46 index = new Expressions(); | |
47 value = new Initializers(); | |
48 } | |
49 | |
72 | 50 override Initializer syntaxCopy() |
0 | 51 { |
52 //printf("ArrayInitializer.syntaxCopy()\n"); | |
53 | |
54 ArrayInitializer ai = new ArrayInitializer(loc); | |
55 | |
56 assert(index.dim == value.dim); | |
57 ai.index.setDim(index.dim); | |
58 ai.value.setDim(value.dim); | |
59 for (int i = 0; i < ai.value.dim; i++) | |
60 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
61 Expression e = index[i]; |
0 | 62 if (e) |
63 e = e.syntaxCopy(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
64 ai.index[i] = e; |
0 | 65 |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
66 auto init = value[i]; |
0 | 67 init = init.syntaxCopy(); |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
68 ai.value[i] = init; |
0 | 69 } |
70 return ai; | |
71 } | |
72 | |
73 void addInit(Expression index, Initializer value) | |
74 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
75 this.index.push(index); |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
76 this.value.push(value); |
0 | 77 dim = 0; |
78 type = null; | |
79 } | |
80 | |
72 | 81 override Initializer semantic(Scope sc, Type t) |
0 | 82 { |
83 uint length; | |
84 | |
85 //printf("ArrayInitializer.semantic(%s)\n", t.toChars()); | |
86 if (sem) // if semantic() already run | |
87 return this; | |
88 | |
89 sem = 1; | |
90 type = t; | |
91 t = t.toBasetype(); | |
92 switch (t.ty) | |
93 { | |
94 case Tpointer: | |
95 case Tsarray: | |
96 case Tarray: | |
97 break; | |
98 | |
99 default: | |
100 error(loc, "cannot use array to initialize %s", type.toChars()); | |
101 return this; | |
102 } | |
103 | |
104 length = 0; | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
105 foreach (size_t i, Expression idx; index) |
0 | 106 { |
107 if (idx) | |
108 { | |
109 idx = idx.semantic(sc); | |
110 idx = idx.optimize(WANTvalue | WANTinterpret); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
111 index[i] = idx; |
0 | 112 length = cast(uint)idx.toInteger(); |
113 } | |
114 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
115 Initializer val = value[i]; |
0 | 116 val = val.semantic(sc, t.nextOf()); |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
117 value[i] = val; |
0 | 118 length++; |
119 if (length == 0) | |
120 error(loc, "array dimension overflow"); | |
121 if (length > dim) | |
122 dim = length; | |
123 } | |
124 uint amax = 0x80000000; | |
125 if (cast(uint) (dim * t.nextOf().size()) >= amax) | |
126 error(loc, "array dimension %u exceeds max of %ju", dim, amax / t.nextOf().size()); | |
127 | |
128 return this; | |
129 } | |
130 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
131 int isAssociativeArray() |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
132 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
133 for (size_t i = 0; i < value.dim; i++) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
134 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
135 if (index[i]) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
136 return 1; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
137 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
138 return 0; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
139 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
140 |
72 | 141 override Type inferType(Scope sc) |
0 | 142 { |
143 //printf("ArrayInitializer.inferType() %s\n", toChars()); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
144 assert(0); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
145 return null; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
146 static if (false) { |
0 | 147 type = Type.terror; |
148 for (size_t i = 0; i < value.dim; i++) | |
149 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
150 if (index[i]) |
79 | 151 goto Laa; |
0 | 152 } |
153 | |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
154 foreach (size_t i, Initializer iz; value) |
0 | 155 { |
156 if (iz) | |
157 { | |
158 Type t = iz.inferType(sc); | |
159 if (i == 0) | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
160 { /* BUG: This gets the type from the first element. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
161 * Fix to use all the elements to figure out the type. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
162 */ |
0 | 163 t = new TypeSArray(t, new IntegerExp(value.dim)); |
164 t = t.semantic(loc, sc); | |
165 type = t; | |
166 } | |
167 } | |
168 } | |
169 return type; | |
170 | |
79 | 171 Laa: |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
172 /* It's possibly an associative array initializer. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
173 * BUG: inferring type from first member. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
174 */ |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
175 Initializer iz = value[0]; |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
176 Expression indexinit = index[0]; |
79 | 177 if (iz && indexinit) |
178 { | |
179 Type t = iz.inferType(sc); | |
180 indexinit = indexinit.semantic(sc); | |
181 Type indext = indexinit.type; | |
182 t = new TypeAArray(t, indext); | |
183 type = t.semantic(loc, sc); | |
184 } | |
185 else | |
186 error(loc, "cannot infer type from this array initializer"); | |
187 return type; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
188 } |
0 | 189 } |
190 | |
191 /******************************** | |
192 * If possible, convert array initializer to array literal. | |
73 | 193 * Otherwise return null. |
0 | 194 */ |
72 | 195 override Expression toExpression() |
0 | 196 { |
197 Expression e; | |
198 | |
199 //printf("ArrayInitializer.toExpression(), dim = %d\n", dim); | |
200 //static int i; if (++i == 2) halt(); | |
201 | |
202 size_t edim; | |
203 Type t = null; | |
204 if (type) | |
205 { | |
79 | 206 if (type == Type.terror) |
207 return new ErrorExp(); | |
208 | |
0 | 209 t = type.toBasetype(); |
210 switch (t.ty) | |
211 { | |
212 case Tsarray: | |
213 edim = cast(uint)(cast(TypeSArray)t).dim.toInteger(); | |
214 break; | |
215 | |
216 case Tpointer: | |
217 case Tarray: | |
218 edim = dim; | |
219 break; | |
220 | |
221 default: | |
222 assert(0); | |
223 } | |
224 } | |
225 else | |
226 { | |
227 edim = value.dim; | |
228 for (size_t i = 0, j = 0; i < value.dim; i++, j++) | |
229 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
230 if (index[i]) |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
231 j = cast(uint)(index[i].toInteger()); |
0 | 232 if (j >= edim) |
233 edim = j + 1; | |
234 } | |
235 } | |
236 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
237 auto elements = new Expressions(); |
0 | 238 elements.setDim(edim); |
239 for (size_t i = 0, j = 0; i < value.dim; i++, j++) | |
240 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
241 if (index[i]) |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
242 j = cast(uint)(index[i].toInteger()); |
0 | 243 assert(j < edim); |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
244 Initializer iz = value[i]; |
0 | 245 if (!iz) |
246 goto Lno; | |
247 Expression ex = iz.toExpression(); | |
248 if (!ex) | |
249 { | |
250 goto Lno; | |
251 } | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
252 elements[j] = ex; |
0 | 253 } |
254 | |
255 /* Fill in any missing elements with the default initializer | |
256 */ | |
257 { | |
258 Expression init = null; | |
259 for (size_t i = 0; i < edim; i++) | |
260 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
261 if (!elements[i]) |
0 | 262 { |
263 if (!type) | |
264 goto Lno; | |
265 if (!init) | |
266 init = (cast(TypeNext)t).next.defaultInit(Loc(0)); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
267 elements[i] = init; |
0 | 268 } |
269 } | |
270 | |
271 Expression e2 = new ArrayLiteralExp(loc, elements); | |
272 e2.type = type; | |
273 return e2; | |
274 } | |
275 | |
276 Lno: | |
73 | 277 return null; |
0 | 278 } |
156 | 279 |
280 /******************************** | |
281 * If possible, convert array initializer to associative array initializer. | |
282 */ | |
283 Expression toAssocArrayLiteral() | |
0 | 284 { |
156 | 285 Expression e; |
286 | |
287 // writef("ArrayInitializer::toAssocArrayInitializer()\n"); | |
288 // static int i; if (++i == 2) halt(); | |
289 Expressions keys = new Expressions(); | |
290 keys.setDim(value.dim); | |
291 Expressions values = new Expressions(); | |
292 values.setDim(value.dim); | |
293 | |
294 foreach (size_t i, Initializer iz; value) | |
295 { | |
296 e = index[i]; | |
297 if (!e) | |
298 goto Lno; | |
299 keys[i] = e; | |
300 | |
301 if (!iz) | |
302 goto Lno; | |
303 e = iz.toExpression(); | |
304 if (!e) | |
305 goto Lno; | |
306 values[i] = e; | |
307 } | |
308 e = new AssocArrayLiteralExp(loc, keys, values); | |
309 return e; | |
310 | |
311 Lno: | |
312 delete keys; | |
313 delete values; | |
314 error(loc, "not an associative array initializer"); | |
315 return new ErrorExp(); | |
0 | 316 } |
317 | |
156 | 318 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 319 { |
320 assert(false); | |
321 } | |
322 | |
72 | 323 override dt_t* toDt() |
0 | 324 { |
325 //printf("ArrayInitializer.toDt('%s')\n", toChars()); | |
326 Type tb = type.toBasetype(); | |
327 Type tn = tb.nextOf().toBasetype(); | |
328 | |
128
e6e542f37b94
Some more Array -> Vector conversions
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
127
diff
changeset
|
329 scope dts = new Vector!(dt_t*)(); |
0 | 330 uint size; |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
331 uint length_; |
0 | 332 uint i; |
333 dt_t* dt; | |
334 dt_t* d; | |
335 dt_t** pdtend; | |
336 | |
337 //printf("\tdim = %d\n", dim); | |
338 dts.setDim(dim); | |
339 dts.zero(); | |
340 | |
341 size = cast(uint)tn.size(); | |
342 | |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
343 length_ = 0; |
0 | 344 for (i = 0; i < index.dim; i++) |
345 { | |
346 Expression idx; | |
347 Initializer val; | |
348 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
349 idx = index[i]; |
0 | 350 if (idx) |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
351 length_ = cast(uint)idx.toInteger(); |
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
352 //printf("\tindex[%d] = %p, length_ = %u, dim = %u\n", i, idx, length_, dim); |
0 | 353 |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
354 assert(length_ < dim); |
127
9ee9b55452cb
Identifiers, Initializers -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
355 val = value[i]; |
0 | 356 dt = val.toDt(); |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
357 if (dts[length_]) |
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
358 error(loc, "duplicate initializations for index %d", length_); |
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
359 dts[length_] = dt; |
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
360 length_++; |
0 | 361 } |
362 | |
363 Expression edefault = tb.nextOf().defaultInit(Loc(0)); | |
364 | |
365 uint n = 1; | |
366 for (Type tbn = tn; tbn.ty == Tsarray; tbn = tbn.nextOf().toBasetype()) | |
367 { | |
368 TypeSArray tsa = cast(TypeSArray)tbn; | |
369 n *= tsa.dim.toInteger(); | |
370 } | |
371 | |
372 d = null; | |
373 pdtend = &d; | |
374 for (i = 0; i < dim; i++) | |
375 { | |
128
e6e542f37b94
Some more Array -> Vector conversions
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
127
diff
changeset
|
376 dt = dts[i]; |
0 | 377 if (dt) |
378 pdtend = dtcat(pdtend, dt); | |
379 else | |
380 { | |
381 for (int j = 0; j < n; j++) | |
382 pdtend = edefault.toDt(pdtend); | |
383 } | |
384 } | |
385 switch (tb.ty) | |
386 { | |
387 case Tsarray: | |
388 { | |
389 uint tadim; | |
390 TypeSArray ta = cast(TypeSArray)tb; | |
391 | |
392 tadim = cast(uint)ta.dim.toInteger(); | |
393 if (dim < tadim) | |
394 { | |
395 if (edefault.isBool(false)) | |
396 // pad out end of array | |
397 pdtend = dtnzeros(pdtend, size * (tadim - dim)); | |
398 else | |
399 { | |
400 for (i = dim; i < tadim; i++) | |
401 { | |
402 for (int j = 0; j < n; j++) | |
403 pdtend = edefault.toDt(pdtend); | |
404 } | |
405 } | |
406 } | |
407 else if (dim > tadim) | |
408 { | |
409 debug writef("1: "); | |
410 error(loc, "too many initializers, %d, for array[%d]", dim, tadim); | |
411 } | |
412 break; | |
413 } | |
414 | |
415 case Tpointer: | |
416 case Tarray: | |
417 // Create symbol, and then refer to it | |
418 Symbol* s = static_sym(); | |
419 s.Sdt = d; | |
420 outdata(s); | |
421 | |
422 d = null; | |
423 if (tb.ty == Tarray) | |
424 dtdword(&d, dim); | |
425 dtxoff(&d, s, 0, TYnptr); | |
426 break; | |
427 | |
428 default: | |
429 assert(0); | |
430 } | |
431 return d; | |
432 } | |
433 | |
434 dt_t* toDtBit() // for bit arrays | |
435 { | |
436 assert(false); | |
437 } | |
438 | |
72 | 439 override ArrayInitializer isArrayInitializer() { return this; } |
440 } |