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