Mercurial > projects > ddmd
annotate dmd/TypeSArray.d @ 94:3a0b150c9841
Objects -> Vector!Object iteration 1
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 23:00:34 +0100 |
parents | 2e2a5c3f943a |
children | 12c0c84d13fd |
rev | line source |
---|---|
0 | 1 module dmd.TypeSArray; |
2 | |
3 import dmd.TypeArray; | |
64 | 4 import dmd.TypeInfoStaticArrayDeclaration; |
51 | 5 import dmd.TypeAArray; |
0 | 6 import dmd.MOD; |
7 import dmd.Argument; | |
51 | 8 import dmd.TypeIdentifier; |
9 import dmd.TemplateParameter; | |
10 import dmd.TemplateValueParameter; | |
0 | 11 import dmd.TypeStruct; |
12 import dmd.TypeTuple; | |
13 import dmd.VarExp; | |
14 import dmd.IntegerExp; | |
15 import dmd.Expression; | |
16 import dmd.Type; | |
17 import dmd.TupleDeclaration; | |
18 import dmd.TOK; | |
19 import dmd.Loc; | |
20 import dmd.STC; | |
21 import dmd.Scope; | |
22 import dmd.Dsymbol; | |
23 import dmd.OutBuffer; | |
24 import dmd.HdrGenState; | |
25 import dmd.Identifier; | |
26 import dmd.MATCH; | |
27 import dmd.TypeDArray; | |
28 import dmd.TypePointer; | |
29 import dmd.ArrayTypes; | |
30 import dmd.WANT; | |
31 import dmd.TypeInfoDeclaration; | |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
32 import dmd.ScopeDsymbol; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
33 import dmd.ArrayScopeSymbol; |
0 | 34 import dmd.TY; |
35 import dmd.Util; | |
36 import dmd.Id; | |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
37 import dmd.IndexExp; |
0 | 38 |
39 import dmd.type.Util; | |
40 | |
41 import dmd.backend.dt_t; | |
42 import dmd.backend.TYPE; | |
43 import dmd.backend.Util; | |
44 import dmd.backend.TYM; | |
45 import dmd.backend.DT; | |
46 | |
47 // Static array, one with a fixed dimension | |
48 class TypeSArray : TypeArray | |
49 { | |
50 Expression dim; | |
51 | |
52 this(Type t, Expression dim) | |
53 { | |
54 super(TY.Tsarray, t); | |
55 //printf("TypeSArray(%s)\n", dim.toChars()); | |
56 this.dim = dim; | |
57 } | |
58 | |
59 version (DumbClone) { | |
60 } else { | |
61 Type clone() | |
62 { | |
63 assert(false); | |
64 } | |
65 } | |
66 | |
72 | 67 override Type syntaxCopy() |
0 | 68 { |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
69 Type t = next.syntaxCopy(); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
70 Expression e = dim.syntaxCopy(); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
71 t = new TypeSArray(t, e); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
72 t.mod = mod; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
73 return t; |
0 | 74 } |
75 | |
72 | 76 override ulong size(Loc loc) |
0 | 77 { |
78 if (!dim) | |
79 return Type.size(loc); | |
80 | |
81 long sz = dim.toInteger(); | |
82 | |
83 { | |
84 long n, n2; | |
85 n = next.size(); | |
86 n2 = n * sz; | |
87 if (n && (n2 / n) != sz) | |
88 goto Loverflow; | |
89 | |
90 sz = n2; | |
91 } | |
92 return sz; | |
93 | |
94 Loverflow: | |
95 error(loc, "index %jd overflow for static array", sz); | |
96 return 1; | |
97 } | |
98 | |
72 | 99 override uint alignsize() |
0 | 100 { |
101 return next.alignsize(); | |
102 } | |
103 | |
72 | 104 override Type semantic(Loc loc, Scope sc) |
0 | 105 { |
106 //printf("TypeSArray.semantic() %s\n", toChars()); | |
107 | |
108 Type t; | |
109 Expression e; | |
110 Dsymbol s; | |
111 next.resolve(loc, sc, &e, &t, &s); | |
112 if (dim && s && s.isTupleDeclaration()) | |
113 { | |
114 TupleDeclaration sd = s.isTupleDeclaration(); | |
115 | |
116 dim = semanticLength(sc, sd, dim); | |
117 dim = dim.optimize(WANT.WANTvalue | WANT.WANTinterpret); | |
118 ulong d = dim.toUInteger(); | |
119 | |
120 if (d >= sd.objects.dim) | |
121 { error(loc, "tuple index %ju exceeds %u", d, sd.objects.dim); | |
122 return Type.terror; | |
123 } | |
124 ///Object o = cast(Object)sd.objects.data[(size_t)d]; | |
125 ///if (o.dyncast() != DYNCAST_TYPE) | |
126 ///{ | |
127 /// error(loc, "%s is not a type", toChars()); | |
128 /// return Type.terror; | |
129 ///} | |
130 ///t = cast(Type)o; | |
131 | |
132 t = cast(Type)sd.objects.data[cast(size_t)d]; | |
133 if (t is null) { | |
134 error(loc, "%s is not a type", toChars()); | |
135 return Type.terror; | |
136 } | |
137 return t; | |
138 } | |
139 | |
140 next = next.semantic(loc,sc); | |
141 transitive(); | |
142 | |
143 Type tbn = next.toBasetype(); | |
144 | |
145 if (dim) | |
146 { | |
147 long n, n2; | |
148 | |
149 dim = semanticLength(sc, tbn, dim); | |
150 | |
151 dim = dim.optimize(WANT.WANTvalue | WANT.WANTinterpret); | |
152 if (sc && sc.parameterSpecialization && dim.op == TOK.TOKvar && | |
153 (cast(VarExp)dim).var.storage_class & STC.STCtemplateparameter) | |
154 { | |
155 /* It could be a template parameter N which has no value yet: | |
156 * template Foo(T : T[N], size_t N); | |
157 */ | |
158 return this; | |
159 } | |
160 long d1 = dim.toInteger(); | |
161 dim = dim.castTo(sc, tsize_t); | |
162 dim = dim.optimize(WANT.WANTvalue); | |
163 long d2 = dim.toInteger(); | |
164 | |
165 if (d1 != d2) | |
166 goto Loverflow; | |
167 | |
168 if (tbn.isintegral() || | |
169 tbn.isfloating() || | |
170 tbn.ty == TY.Tpointer || | |
171 tbn.ty == TY.Tarray || | |
172 tbn.ty == TY.Tsarray || | |
173 tbn.ty == TY.Taarray || | |
174 tbn.ty == TY.Tclass) | |
175 { | |
176 /* Only do this for types that don't need to have semantic() | |
177 * run on them for the size, since they may be forward referenced. | |
178 */ | |
179 n = tbn.size(loc); | |
180 n2 = n * d2; | |
181 if (cast(int)n2 < 0) | |
182 goto Loverflow; | |
183 if (n2 >= 0x1000000) // put a 'reasonable' limit on it | |
184 goto Loverflow; | |
185 if (n && n2 / n != d2) | |
186 { | |
187 Loverflow: | |
188 error(loc, "index %jd overflow for static array", d1); | |
189 dim = new IntegerExp(Loc(0), 1, tsize_t); | |
190 } | |
191 } | |
192 } | |
193 switch (tbn.ty) | |
194 { | |
195 case TY.Ttuple: | |
196 { // Index the tuple to get the type | |
197 assert(dim); | |
198 TypeTuple tt = cast(TypeTuple)tbn; | |
199 ulong d = dim.toUInteger(); | |
200 | |
201 if (d >= tt.arguments.dim) | |
202 { | |
203 error(loc, "tuple index %ju exceeds %u", d, tt.arguments.dim); | |
204 return Type.terror; | |
205 } | |
206 Argument arg = cast(Argument)tt.arguments.data[cast(size_t)d]; | |
207 return arg.type; | |
208 } | |
209 case TY.Tstruct: | |
210 { TypeStruct ts = cast(TypeStruct)tbn; | |
211 if (ts.sym.isnested) | |
212 error(loc, "cannot have array of inner structs %s", ts.toChars()); | |
213 break; | |
214 } | |
215 case TY.Tfunction: | |
216 case TY.Tnone: | |
217 error(loc, "can't have array of %s", tbn.toChars()); | |
218 tbn = next = tint32; | |
219 break; | |
220 default: /// | |
221 break; | |
222 } | |
223 if (tbn.isauto()) | |
224 error(loc, "cannot have array of auto %s", tbn.toChars()); | |
225 return merge(); | |
226 } | |
227 | |
72 | 228 override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) |
0 | 229 { |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
230 //printf("TypeSArray.resolve() %s\n", toChars()); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
231 next.resolve(loc, sc, pe, pt, ps); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
232 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
233 if (*pe) |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
234 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
235 // It's really an index expression |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
236 Expression e = new IndexExp(loc, *pe, dim); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
237 *pe = e; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
238 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
239 else if (*ps) |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
240 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
241 Dsymbol s = *ps; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
242 TupleDeclaration td = s.isTupleDeclaration(); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
243 if (td) |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
244 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
245 ScopeDsymbol sym = new ArrayScopeSymbol(sc, td); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
246 sym.parent = sc.scopesym; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
247 sc = sc.push(sym); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
248 |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
249 dim = dim.semantic(sc); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
250 dim = dim.optimize(WANTvalue | WANTinterpret); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
251 ulong d = dim.toUInteger(); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
252 |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
253 sc = sc.pop(); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
254 |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
255 if (d >= td.objects.dim) |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
256 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
257 error(loc, "tuple index %ju exceeds %u", d, td.objects.dim); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
258 goto Ldefault; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
259 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
260 Object o = cast(Object)td.objects.data[cast(size_t)d]; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
261 if ((*ps = isDsymbol(o)) !is null) /// ! |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
262 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
263 return; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
264 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
265 if ((*pe = isExpression(o)) !is null) /// ! |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
266 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
267 return; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
268 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
269 |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
270 /* Create a new TupleDeclaration which |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
271 * is a slice [d..d+1] out of the old one. |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
272 * Do it this way because TemplateInstance.semanticTiargs() |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
273 * can handle unresolved Objects this way. |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
274 */ |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
275 auto objects = new Objects; |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
276 objects.setDim(1); |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
277 objects[0] = o; |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
278 |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
279 auto tds = new TupleDeclaration(loc, td.ident, objects); |
41
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
280 *ps = tds; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
281 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
282 else |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
283 goto Ldefault; |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
284 } |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
285 else |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
286 { |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
287 Ldefault: |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
288 Type.resolve(loc, sc, pe, pt, ps); |
f23312cb6f2e
TypeSArray.syntaxCopy & TypeSArray.resolve implemented
korDen
parents:
12
diff
changeset
|
289 } |
0 | 290 } |
291 | |
72 | 292 override void toDecoBuffer(OutBuffer buf, int flag) |
0 | 293 { |
294 Type.toDecoBuffer(buf, flag); | |
295 if (dim) | |
296 //buf.printf("%ju", dim.toInteger()); /// | |
297 buf.printf("%s", dim.toInteger()); | |
298 if (next) | |
299 /* Note that static arrays are value types, so | |
300 * for a parameter, propagate the 0x100 to the next | |
301 * level, since for T[4][3], any const should apply to the T, | |
302 * not the [4]. | |
303 */ | |
304 next.toDecoBuffer(buf, (flag & 0x100) ? flag : mod); | |
305 } | |
306 | |
72 | 307 override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) |
0 | 308 { |
67 | 309 if (mod != this.mod) |
310 { | |
311 toCBuffer3(buf, hgs, mod); | |
312 return; | |
313 } | |
314 next.toCBuffer2(buf, hgs, this.mod); | |
315 buf.printf("[%s]", dim.toChars()); | |
0 | 316 } |
317 | |
72 | 318 override Expression dotExp(Scope sc, Expression e, Identifier ident) |
0 | 319 { |
320 version (LOGDOTEXP) { | |
321 printf("TypeSArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); | |
322 } | |
323 if (ident == Id.length) | |
324 { | |
325 e = dim; | |
326 } | |
327 else if (ident == Id.ptr) | |
328 { | |
329 e = e.castTo(sc, next.pointerTo()); | |
330 } | |
331 else | |
332 { | |
333 e = TypeArray.dotExp(sc, e, ident); | |
334 } | |
335 return e; | |
336 } | |
337 | |
72 | 338 override bool isString() |
0 | 339 { |
64 | 340 TY nty = next.toBasetype().ty; |
341 return nty == Tchar || nty == Twchar || nty == Tdchar; | |
0 | 342 } |
343 | |
72 | 344 override bool isZeroInit(Loc loc) |
0 | 345 { |
346 return next.isZeroInit(loc); | |
347 } | |
348 | |
72 | 349 override uint memalign(uint salign) |
0 | 350 { |
351 return next.memalign(salign); | |
352 } | |
353 | |
72 | 354 override MATCH constConv(Type to) |
0 | 355 { |
356 assert(false); | |
357 } | |
358 | |
72 | 359 override MATCH implicitConvTo(Type to) |
0 | 360 { |
361 //printf("TypeSArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); | |
362 | |
363 // Allow implicit conversion of static array to pointer or dynamic array | |
364 if (IMPLICIT_ARRAY_TO_PTR && to.ty == Tpointer) | |
365 { | |
366 TypePointer tp = cast(TypePointer)to; | |
367 | |
368 if (next.mod != tp.next.mod && tp.next.mod != MODconst) | |
369 return MATCHnomatch; | |
370 | |
371 if (tp.next.ty == Tvoid || next.constConv(tp.next) != MATCHnomatch) | |
372 { | |
373 return MATCHconvert; | |
374 } | |
375 return MATCHnomatch; | |
376 } | |
377 if (to.ty == Tarray) | |
378 { | |
379 int offset = 0; | |
380 TypeDArray ta = cast(TypeDArray)to; | |
381 | |
382 if (next.mod != ta.next.mod && ta.next.mod != MODconst) | |
383 return MATCHnomatch; | |
384 | |
385 if (next.equals(ta.next) || | |
386 next.implicitConvTo(ta.next) >= MATCHconst || | |
387 (ta.next.isBaseOf(next, &offset) && offset == 0) || | |
388 ta.next.ty == Tvoid | |
389 ) | |
390 return MATCHconvert; | |
391 | |
392 return MATCHnomatch; | |
393 } | |
394 if (to.ty == Tsarray) | |
395 { | |
396 if (this == to) | |
397 return MATCHexact; | |
398 | |
399 TypeSArray tsa = cast(TypeSArray)to; | |
400 | |
401 if (dim.equals(tsa.dim)) | |
402 { | |
403 /* Since static arrays are value types, allow | |
404 * conversions from const elements to non-const | |
405 * ones, just like we allow conversion from const int | |
406 * to int. | |
407 */ | |
408 MATCH m = next.implicitConvTo(tsa.next); | |
409 if (m >= MATCHconst) | |
410 { | |
411 if (mod != to.mod) | |
412 m = MATCHconst; | |
413 return m; | |
414 } | |
415 } | |
416 } | |
417 return MATCHnomatch; | |
418 } | |
419 | |
72 | 420 override Expression defaultInit(Loc loc) |
0 | 421 { |
422 version (LOGDEFAULTINIT) { | |
423 printf("TypeSArray.defaultInit() '%s'\n", toChars()); | |
424 } | |
425 return next.defaultInit(loc); | |
426 } | |
427 | |
72 | 428 override dt_t** toDt(dt_t** pdt) |
0 | 429 { |
430 return toDtElem(pdt, null); | |
431 } | |
432 | |
433 dt_t** toDtElem(dt_t** pdt, Expression e) | |
434 { | |
435 int i; | |
436 | |
437 //printf("TypeSArray::toDtElem()\n"); | |
438 uint len = cast(uint)dim.toInteger(); | |
439 if (len) | |
440 { | |
441 while (*pdt) | |
442 pdt = &((*pdt).DTnext); | |
443 Type tnext = next; | |
444 Type tbn = tnext.toBasetype(); | |
445 while (tbn.ty == Tsarray) | |
446 { | |
447 TypeSArray tsa = cast(TypeSArray)tbn; | |
448 | |
449 len *= tsa.dim.toInteger(); | |
450 tnext = tbn.nextOf(); | |
451 tbn = tnext.toBasetype(); | |
452 } | |
453 if (!e) // if not already supplied | |
454 e = tnext.defaultInit(Loc(0)); // use default initializer | |
455 if (tbn.ty == Tstruct) | |
456 tnext.toDt(pdt); | |
457 else | |
458 e.toDt(pdt); | |
459 dt_optimize(*pdt); | |
460 if ((*pdt).dt == DT_azeros && !(*pdt).DTnext) | |
461 { | |
462 (*pdt).DTazeros *= len; | |
463 pdt = &((*pdt).DTnext); | |
464 } | |
465 else if ((*pdt).dt == DT_1byte && (*pdt).DTonebyte == 0 && !(*pdt).DTnext) | |
466 { | |
467 (*pdt).dt = DT_azeros; | |
468 (*pdt).DTazeros = len; | |
469 pdt = &((*pdt).DTnext); | |
470 } | |
471 else if (e.op != TOKstring) | |
472 { | |
473 for (i = 1; i < len; i++) | |
474 { | |
475 if (tbn.ty == Tstruct) | |
476 { | |
477 pdt = tnext.toDt(pdt); | |
478 while (*pdt) | |
479 pdt = &((*pdt).DTnext); | |
480 } | |
481 else | |
482 pdt = e.toDt(pdt); | |
483 } | |
484 } | |
485 } | |
486 return pdt; | |
487 } | |
488 | |
72 | 489 override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) |
0 | 490 { |
51 | 491 static if (false) { |
492 printf("TypeSArray.deduceType()\n"); | |
493 printf("\tthis = %d, ", ty); print(); | |
494 printf("\ttparam = %d, ", tparam.ty); tparam.print(); | |
495 } | |
496 | |
497 // Extra check that array dimensions must match | |
498 if (tparam) | |
499 { | |
500 if (tparam.ty == Tsarray) | |
501 { | |
502 TypeSArray tp = cast(TypeSArray)tparam; | |
503 | |
504 if (tp.dim.op == TOKvar && (cast(VarExp)tp.dim).var.storage_class & STCtemplateparameter) | |
505 { | |
506 int i = templateIdentifierLookup((cast(VarExp)tp.dim).var.ident, parameters); | |
507 // This code matches code in TypeInstance.deduceType() | |
508 if (i == -1) | |
509 goto Lnomatch; | |
510 TemplateParameter tp2 = cast(TemplateParameter)parameters.data[i]; | |
511 TemplateValueParameter tvp = tp2.isTemplateValueParameter(); | |
512 if (!tvp) | |
513 goto Lnomatch; | |
514 Expression e = cast(Expression)dedtypes.data[i]; | |
515 if (e) | |
516 { | |
517 if (!dim.equals(e)) | |
518 goto Lnomatch; | |
519 } | |
520 else | |
521 { | |
522 Type vt = tvp.valType.semantic(Loc(0), sc); | |
523 MATCH m = cast(MATCH)dim.implicitConvTo(vt); | |
524 if (!m) | |
525 goto Lnomatch; | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
526 dedtypes[i] = dim; |
51 | 527 } |
528 } | |
529 else if (dim.toInteger() != tp.dim.toInteger()) | |
530 return MATCHnomatch; | |
531 } | |
532 else if (tparam.ty == Taarray) | |
533 { | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
534 auto tp = cast(TypeAArray)tparam; |
51 | 535 if (tp.index.ty == Tident) |
536 { | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
537 auto tident = cast(TypeIdentifier)tp.index; |
51 | 538 |
539 if (tident.idents.dim == 0) | |
540 { | |
541 Identifier id = tident.ident; | |
542 | |
543 for (size_t i = 0; i < parameters.dim; i++) | |
544 { | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
545 auto tp2 = cast(TemplateParameter)parameters.data[i]; |
51 | 546 |
547 if (tp2.ident.equals(id)) | |
548 { | |
549 // Found the corresponding template parameter | |
550 TemplateValueParameter tvp = tp2.isTemplateValueParameter(); | |
551 if (!tvp || !tvp.valType.isintegral()) | |
552 goto Lnomatch; | |
553 | |
554 if (dedtypes.data[i]) | |
555 { | |
556 if (!dim.equals(cast(Object)dedtypes.data[i])) | |
557 goto Lnomatch; | |
558 } | |
559 else | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
560 { dedtypes[i] = dim; |
51 | 561 } |
562 return next.deduceType(sc, tparam.nextOf(), parameters, dedtypes); | |
563 } | |
564 } | |
565 } | |
566 } | |
567 } | |
568 else if (tparam.ty == Tarray) | |
569 { | |
570 MATCH m; | |
571 | |
572 m = next.deduceType(sc, tparam.nextOf(), parameters, dedtypes); | |
573 if (m == MATCHexact) | |
574 m = MATCHconvert; | |
575 return m; | |
576 } | |
577 } | |
578 return Type.deduceType(sc, tparam, parameters, dedtypes); | |
579 | |
580 Lnomatch: | |
581 return MATCHnomatch; | |
0 | 582 } |
583 | |
72 | 584 override TypeInfoDeclaration getTypeInfoDeclaration() |
0 | 585 { |
64 | 586 return new TypeInfoStaticArrayDeclaration(this); |
0 | 587 } |
588 | |
72 | 589 override Expression toExpression() |
0 | 590 { |
591 assert(false); | |
592 } | |
593 | |
72 | 594 override bool hasPointers() |
0 | 595 { |
596 return next.hasPointers(); | |
597 } | |
598 | |
599 version (CPP_MANGLE) { | |
600 void toCppMangle(OutBuffer buf, CppMangleState* cms) | |
601 { | |
602 assert(false); | |
603 } | |
604 } | |
605 | |
72 | 606 override type* toCtype() |
0 | 607 { |
608 if (!ctype) | |
609 { | |
610 type* tn = next.toCtype(); | |
611 ctype = type_allocn(TYarray, tn); | |
612 ctype.Tdim = cast(uint)dim.toInteger(); | |
613 } | |
614 | |
615 return ctype; | |
616 } | |
617 | |
72 | 618 override type* toCParamtype() |
0 | 619 { |
620 // arrays are passed as pointers | |
621 return next.pointerTo().toCtype(); | |
622 } | |
72 | 623 } |