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