Mercurial > projects > ddmd
annotate dmd/TypeAArray.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 | 2cc604139636 |
children | f708f0452e81 |
rev | line source |
---|---|
0 | 1 module dmd.TypeAArray; |
2 | |
3 import dmd.TypeArray; | |
4 import dmd.MOD; | |
5 import dmd.ArrayTypes; | |
6 import dmd.TypeInfoDeclaration; | |
7 import dmd.Expression; | |
8 import dmd.Scope; | |
9 import dmd.Loc; | |
10 import dmd.Dsymbol; | |
11 import dmd.Type; | |
12 import dmd.TypeSArray; | |
13 import dmd.OutBuffer; | |
14 import dmd.HdrGenState; | |
15 import dmd.Identifier; | |
16 import dmd.MATCH; | |
17 import dmd.TY; | |
18 import dmd.Id; | |
19 import dmd.CallExp; | |
20 import dmd.IntegerExp; | |
21 import dmd.FuncDeclaration; | |
22 import dmd.VarExp; | |
23 import dmd.TypeFunction; | |
24 import dmd.NullExp; | |
25 import dmd.Array; | |
26 | |
27 import dmd.backend.Symbol; | |
28 import dmd.backend.TYPE; | |
29 import dmd.backend.Util; | |
30 import dmd.backend.SC; | |
31 import dmd.backend.LIST; | |
32 import dmd.backend.TYM; | |
33 import dmd.backend.TF; | |
34 import dmd.backend.mTYman; | |
35 | |
36 import core.stdc.stdio; | |
37 import core.stdc.stdlib; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
38 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
39 import core.memory; |
0 | 40 class TypeAArray : TypeArray |
41 { | |
42 Type index; // key type | |
43 | |
44 this(Type t, Type index) | |
45 { | |
46 super(Taarray, t); | |
47 this.index = index; | |
48 } | |
49 | |
50 Type syntaxCopy() | |
51 { | |
51 | 52 Type t = next.syntaxCopy(); |
53 Type ti = index.syntaxCopy(); | |
54 if (t == next && ti == index) | |
55 t = this; | |
56 else | |
57 { | |
58 t = new TypeAArray(t, ti); | |
59 t.mod = mod; | |
60 } | |
61 return t; | |
0 | 62 } |
63 | |
64 version (DumbClone) { | |
65 } else { | |
66 Type clone() | |
67 { | |
68 assert(false); | |
69 } | |
70 } | |
71 ulong size(Loc loc) | |
72 { | |
73 return PTRSIZE /* * 2*/; | |
74 } | |
75 | |
76 Type semantic(Loc loc, Scope sc) | |
77 { | |
78 //printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty); | |
79 | |
80 // Deal with the case where we thought the index was a type, but | |
81 // in reality it was an expression. | |
82 if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) | |
83 { | |
84 Expression e; | |
85 Type t; | |
86 Dsymbol s; | |
87 | |
88 index.resolve(loc, sc, &e, &t, &s); | |
89 if (e) | |
90 { // It was an expression - | |
91 // Rewrite as a static array | |
92 TypeSArray tsa = new TypeSArray(next, e); | |
93 return tsa.semantic(loc,sc); | |
94 } | |
95 else if (t) | |
96 index = t; | |
97 else | |
98 index.error(loc, "index is not a type or an expression"); | |
99 } | |
100 else | |
101 index = index.semantic(loc,sc); | |
102 | |
103 if (index.nextOf() && !index.nextOf().isInvariant()) | |
104 { | |
105 index = index.constOf().mutableOf(); | |
106 static if (false) { | |
107 printf("index is %p %s\n", index, index.toChars()); | |
108 index.check(); | |
109 printf("index.mod = x%x\n", index.mod); | |
110 printf("index.ito = x%x\n", index.ito); | |
111 if (index.ito) { | |
112 printf("index.ito.mod = x%x\n", index.ito.mod); | |
113 printf("index.ito.ito = x%x\n", index.ito.ito); | |
114 } | |
115 } | |
116 } | |
117 | |
118 switch (index.toBasetype().ty) | |
119 { | |
120 case Tbool: | |
121 case Tfunction: | |
122 case Tvoid: | |
123 case Tnone: | |
124 error(loc, "can't have associative array key of %s", index.toBasetype().toChars()); | |
125 break; | |
126 default: | |
127 break; /// | |
128 } | |
129 next = next.semantic(loc,sc); | |
130 transitive(); | |
131 | |
132 switch (next.toBasetype().ty) | |
133 { | |
134 case Tfunction: | |
135 case Tnone: | |
136 error(loc, "can't have associative array of %s", next.toChars()); | |
137 break; | |
138 default: | |
139 break; /// | |
140 } | |
141 if (next.isauto()) | |
142 error(loc, "cannot have array of auto %s", next.toChars()); | |
143 | |
144 return merge(); | |
145 } | |
146 | |
147 void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) | |
148 { | |
51 | 149 //printf("TypeAArray.resolve() %s\n", toChars()); |
150 | |
151 // Deal with the case where we thought the index was a type, but | |
152 // in reality it was an expression. | |
153 if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) | |
154 { | |
155 Expression e; | |
156 Type t; | |
157 Dsymbol s; | |
158 | |
159 index.resolve(loc, sc, &e, &t, &s); | |
160 if (e) | |
161 { // It was an expression - | |
162 // Rewrite as a static array | |
163 | |
164 TypeSArray tsa = new TypeSArray(next, e); | |
165 return tsa.resolve(loc, sc, pe, pt, ps); | |
166 } | |
167 else if (t) | |
168 index = t; | |
169 else | |
170 index.error(loc, "index is not a type or an expression"); | |
171 } | |
172 Type.resolve(loc, sc, pe, pt, ps); | |
0 | 173 } |
174 | |
175 void toDecoBuffer(OutBuffer buf, int flag) | |
176 { | |
177 Type.toDecoBuffer(buf, flag); | |
178 index.toDecoBuffer(buf); | |
179 next.toDecoBuffer(buf, (flag & 0x100) ? MOD.MODundefined : mod); | |
180 } | |
181 | |
182 void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) | |
183 { | |
184 assert(false); | |
185 } | |
186 | |
187 Expression dotExp(Scope sc, Expression e, Identifier ident) | |
188 { | |
189 version (LOGDOTEXP) { | |
190 printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); | |
191 } | |
192 if (ident == Id.length) | |
193 { | |
194 Expression ec; | |
195 FuncDeclaration fd; | |
196 Expressions arguments; | |
197 | |
198 fd = FuncDeclaration.genCfunc(Type.tsize_t, Id.aaLen); | |
199 ec = new VarExp(Loc(0), fd); | |
200 arguments = new Expressions(); | |
201 arguments.push(cast(void*)e); | |
202 e = new CallExp(e.loc, ec, arguments); | |
203 e.type = (cast(TypeFunction)fd.type).next; | |
204 } | |
205 else if (ident == Id.keys) | |
206 { | |
207 Expression ec; | |
208 FuncDeclaration fd; | |
209 Expressions arguments; | |
210 int size = cast(int)index.size(e.loc); | |
211 | |
212 assert(size); | |
213 fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaKeys); | |
214 ec = new VarExp(Loc(0), fd); | |
215 arguments = new Expressions(); | |
216 arguments.push(cast(void*)e); | |
217 arguments.push(cast(void*)new IntegerExp(Loc(0), size, Type.tsize_t)); | |
218 e = new CallExp(e.loc, ec, arguments); | |
219 e.type = index.arrayOf(); | |
220 } | |
221 else if (ident == Id.values) | |
222 { | |
223 Expression ec; | |
224 FuncDeclaration fd; | |
225 Expressions arguments; | |
226 | |
227 fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaValues); | |
228 ec = new VarExp(Loc(0), fd); | |
229 arguments = new Expressions(); | |
230 arguments.push(cast(void*)e); | |
231 size_t keysize = cast(size_t)index.size(e.loc); | |
232 keysize = (keysize + PTRSIZE - 1) & ~(PTRSIZE - 1); | |
233 arguments.push(cast(void*)new IntegerExp(Loc(0), keysize, Type.tsize_t)); | |
234 arguments.push(cast(void*)new IntegerExp(Loc(0), next.size(e.loc), Type.tsize_t)); | |
235 e = new CallExp(e.loc, ec, arguments); | |
236 e.type = next.arrayOf(); | |
237 } | |
238 else if (ident == Id.rehash) | |
239 { | |
240 Expression ec; | |
241 FuncDeclaration fd; | |
242 Expressions arguments; | |
243 | |
244 fd = FuncDeclaration.genCfunc(Type.tint64, Id.aaRehash); | |
245 ec = new VarExp(Loc(0), fd); | |
246 arguments = new Expressions(); | |
247 arguments.push(cast(void*)e.addressOf(sc)); | |
248 arguments.push(cast(void*)index.getInternalTypeInfo(sc)); | |
249 e = new CallExp(e.loc, ec, arguments); | |
250 e.type = this; | |
251 } | |
252 else | |
253 { | |
254 e = Type.dotExp(sc, e, ident); | |
255 } | |
256 return e; | |
257 } | |
258 | |
259 Expression defaultInit(Loc loc) | |
260 { | |
261 version (LOGDEFAULTINIT) { | |
262 printf("TypeAArray.defaultInit() '%s'\n", toChars()); | |
263 } | |
264 Expression e = new NullExp(loc); | |
265 e.type = this; | |
266 return e; | |
267 } | |
268 | |
269 MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) | |
270 { | |
51 | 271 static if (false) { |
272 printf("TypeAArray.deduceType()\n"); | |
273 printf("\tthis = %d, ", ty); print(); | |
274 printf("\ttparam = %d, ", tparam.ty); tparam.print(); | |
275 } | |
276 | |
277 // Extra check that index type must match | |
278 if (tparam && tparam.ty == Taarray) | |
279 { | |
280 TypeAArray tp = cast(TypeAArray)tparam; | |
281 if (!index.deduceType(sc, tp.index, parameters, dedtypes)) | |
282 { | |
283 return MATCHnomatch; | |
284 } | |
285 } | |
286 return Type.deduceType(sc, tparam, parameters, dedtypes); | |
0 | 287 } |
288 | |
289 bool isZeroInit(Loc loc) | |
290 { | |
291 assert(false); | |
292 } | |
293 | |
294 bool checkBoolean() | |
295 { | |
296 assert(false); | |
297 } | |
298 | |
299 TypeInfoDeclaration getTypeInfoDeclaration() | |
300 { | |
301 assert(false); | |
302 } | |
303 | |
304 bool hasPointers() | |
305 { | |
306 return true; | |
307 } | |
308 | |
309 MATCH implicitConvTo(Type to) | |
310 { | |
51 | 311 //printf("TypeAArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); |
312 if (equals(to)) | |
313 return MATCHexact; | |
314 | |
315 if (to.ty == Taarray) | |
316 { | |
317 TypeAArray ta = cast(TypeAArray)to; | |
318 | |
319 if (!(next.mod == ta.next.mod || ta.next.mod == MODconst)) | |
320 return MATCHnomatch; // not const-compatible | |
321 | |
322 if (!(index.mod == ta.index.mod || ta.index.mod == MODconst)) | |
323 return MATCHnomatch; // not const-compatible | |
324 | |
325 MATCH m = next.constConv(ta.next); | |
326 MATCH mi = index.constConv(ta.index); | |
327 if (m != MATCHnomatch && mi != MATCHnomatch) | |
328 { | |
329 if (m == MATCHexact && mod != to.mod) | |
330 m = MATCHconst; | |
331 if (mi < m) | |
332 m = mi; | |
333 return m; | |
334 } | |
335 } | |
336 return Type.implicitConvTo(to); | |
0 | 337 } |
338 | |
339 MATCH constConv(Type to) | |
340 { | |
341 assert(false); | |
342 } | |
343 | |
344 version (CPP_MANGLE) { | |
345 void toCppMangle(OutBuffer buf, CppMangleState* cms) | |
346 { | |
347 assert(false); | |
348 } | |
349 } | |
350 | |
351 // Back end | |
352 /******************************************** | |
353 * Determine the right symbol to look up | |
354 * an associative array element. | |
355 * Input: | |
356 * flags 0 don't add value signature | |
357 * 1 add value signature | |
358 */ | |
359 Symbol* aaGetSymbol(const(char)* func, int flags) | |
360 in | |
361 { | |
362 assert(func); | |
363 assert((flags & ~1) == 0); | |
364 } | |
365 out (result) | |
366 { | |
367 assert(result); | |
368 } | |
369 body | |
370 { | |
371 int sz; | |
372 char* id; | |
373 type* t; | |
374 Symbol* s; | |
375 int i; | |
376 | |
377 // Dumb linear symbol table - should use associative array! | |
378 static Array sarray = null; | |
379 | |
380 //printf("aaGetSymbol(func = '%s', flags = %d, key = %p)\n", func, flags, key); | |
381 static if (false) { | |
382 scope OutBuffer buf = new OutBuffer(); | |
383 key.toKeyBuffer(buf); | |
384 | |
385 sz = next.size(); // it's just data, so we only care about the size | |
386 sz = (sz + 3) & ~3; // reduce proliferation of library routines | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
387 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
388 id = cast(char*)GC.malloc(3 + strlen(func) + buf.offset + sizeof(sz) * 3 + 1); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
389 else |
0 | 390 id = cast(char*)alloca(3 + strlen(func) + buf.offset + sizeof(sz) * 3 + 1); |
391 buf.writeByte(0); | |
392 if (flags & 1) | |
393 sprintf(id, "_aa%s%s%d", func, buf.data, sz); | |
394 else | |
395 sprintf(id, "_aa%s%s", func, buf.data); | |
396 } else { | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
397 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
398 id = cast(char*)GC.malloc(3 + strlen(func) + 1); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
399 else |
0 | 400 id = cast(char*)alloca(3 + strlen(func) + 1); |
401 sprintf(id, "_aa%s", func); | |
402 } | |
403 if (!sarray) | |
404 sarray = new Array(); | |
405 | |
406 // See if symbol is already in sarray | |
407 for (i = 0; i < sarray.dim; i++) | |
408 { | |
409 s = cast(Symbol*)sarray.data[i]; | |
410 if (strcmp(id, s.Sident.ptr) == 0) | |
411 return s; // use existing Symbol | |
412 } | |
413 | |
414 // Create new Symbol | |
415 | |
416 s = symbol_calloc(id); | |
417 slist_add(s); | |
418 s.Sclass = SCextern; | |
419 s.Ssymnum = -1; | |
420 symbol_func(s); | |
421 | |
422 t = type_alloc(TYnfunc); | |
423 t.Tflags = TFprototype | TFfixed; | |
424 t.Tmangle = mTYman_c; | |
425 t.Tparamtypes = null; | |
426 t.Tnext = next.toCtype(); | |
427 t.Tnext.Tcount++; | |
428 t.Tcount++; | |
429 s.Stype = t; | |
430 | |
431 sarray.push(s); // remember it | |
432 return s; | |
433 } | |
434 | |
435 type* toCtype() | |
436 { | |
437 assert(false); | |
438 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
439 } |