Mercurial > projects > ddmd
annotate dmd/TypeAArray.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | fa9a71a9f5a8 |
children | cd48cb899aee |
rev | line source |
---|---|
0 | 1 module dmd.TypeAArray; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.TypeArray; |
5 import dmd.MOD; | |
6 import dmd.ArrayTypes; | |
7 import dmd.TypeInfoDeclaration; | |
68
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
8 import dmd.TypeInfoAssociativeArrayDeclaration; |
0 | 9 import dmd.Expression; |
10 import dmd.Scope; | |
96 | 11 import dmd.StructDeclaration; |
0 | 12 import dmd.Loc; |
67 | 13 import dmd.Global; |
0 | 14 import dmd.Dsymbol; |
15 import dmd.Type; | |
16 import dmd.TypeSArray; | |
17 import dmd.OutBuffer; | |
18 import dmd.HdrGenState; | |
19 import dmd.Identifier; | |
20 import dmd.MATCH; | |
21 import dmd.TY; | |
96 | 22 import dmd.TemplateInstance; |
0 | 23 import dmd.Id; |
24 import dmd.CallExp; | |
25 import dmd.IntegerExp; | |
26 import dmd.FuncDeclaration; | |
27 import dmd.VarExp; | |
28 import dmd.TypeFunction; | |
29 import dmd.NullExp; | |
30 import dmd.Array; | |
31 | |
32 import dmd.backend.Symbol; | |
33 import dmd.backend.TYPE; | |
34 import dmd.backend.Util; | |
35 import dmd.backend.SC; | |
36 import dmd.backend.LIST; | |
37 import dmd.backend.TYM; | |
38 import dmd.backend.TF; | |
67 | 39 import dmd.backend.Classsym; |
0 | 40 import dmd.backend.mTYman; |
41 | |
42 import core.stdc.stdio; | |
43 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
|
44 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
|
45 import core.memory; |
0 | 46 class TypeAArray : TypeArray |
47 { | |
96 | 48 Type index; // key type |
49 Loc loc; | |
50 Scope sc; | |
51 StructDeclaration impl; // implementation | |
0 | 52 |
53 this(Type t, Type index) | |
54 { | |
178 | 55 register(); |
0 | 56 super(Taarray, t); |
57 this.index = index; | |
58 } | |
59 | |
72 | 60 override Type syntaxCopy() |
0 | 61 { |
51 | 62 Type t = next.syntaxCopy(); |
63 Type ti = index.syntaxCopy(); | |
64 if (t == next && ti == index) | |
65 t = this; | |
66 else | |
67 { | |
68 t = new TypeAArray(t, ti); | |
69 t.mod = mod; | |
70 } | |
71 return t; | |
0 | 72 } |
73 | |
72 | 74 override ulong size(Loc loc) |
0 | 75 { |
76 return PTRSIZE /* * 2*/; | |
77 } | |
78 | |
72 | 79 override Type semantic(Loc loc, Scope sc) |
0 | 80 { |
81 //printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty); | |
96 | 82 this.loc = loc; |
83 this.sc = sc; | |
84 if (sc) | |
85 sc.setNoFree(); | |
86 | |
0 | 87 // Deal with the case where we thought the index was a type, but |
88 // in reality it was an expression. | |
89 if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) | |
90 { | |
91 Expression e; | |
92 Type t; | |
93 Dsymbol s; | |
94 | |
95 index.resolve(loc, sc, &e, &t, &s); | |
96 if (e) | |
97 { // It was an expression - | |
98 // Rewrite as a static array | |
99 TypeSArray tsa = new TypeSArray(next, e); | |
100 return tsa.semantic(loc,sc); | |
101 } | |
102 else if (t) | |
103 index = t; | |
104 else | |
96 | 105 { |
0 | 106 index.error(loc, "index is not a type or an expression"); |
96 | 107 return Type.terror; |
108 } | |
0 | 109 } |
110 else | |
111 index = index.semantic(loc,sc); | |
112 | |
135 | 113 if (index.nextOf() && !index.nextOf().isImmutable()) |
0 | 114 { |
115 index = index.constOf().mutableOf(); | |
96 | 116 static if (false) |
117 { | |
0 | 118 printf("index is %p %s\n", index, index.toChars()); |
119 index.check(); | |
120 printf("index.mod = x%x\n", index.mod); | |
121 printf("index.ito = x%x\n", index.ito); | |
122 if (index.ito) { | |
123 printf("index.ito.mod = x%x\n", index.ito.mod); | |
124 printf("index.ito.ito = x%x\n", index.ito.ito); | |
125 } | |
126 } | |
127 } | |
128 | |
129 switch (index.toBasetype().ty) | |
130 { | |
131 case Tbool: | |
132 case Tfunction: | |
133 case Tvoid: | |
134 case Tnone: | |
73 | 135 case Ttuple: |
0 | 136 error(loc, "can't have associative array key of %s", index.toBasetype().toChars()); |
96 | 137 return Type.terror; |
0 | 138 default: |
139 break; /// | |
140 } | |
141 next = next.semantic(loc,sc); | |
142 transitive(); | |
143 | |
144 switch (next.toBasetype().ty) | |
145 { | |
146 case Tfunction: | |
147 case Tnone: | |
148 error(loc, "can't have associative array of %s", next.toChars()); | |
96 | 149 return Type.terror; |
0 | 150 default: |
151 break; /// | |
152 } | |
153 if (next.isauto()) | |
96 | 154 { |
0 | 155 error(loc, "cannot have array of auto %s", next.toChars()); |
96 | 156 return Type.terror; |
157 } | |
0 | 158 return merge(); |
159 } | |
160 | |
96 | 161 StructDeclaration getImpl() |
162 { | |
163 // Do it lazily | |
164 if (!impl) | |
165 { | |
166 if (!index.reliesOnTident() && !next.reliesOnTident()) | |
167 { | |
168 /* This is really a proxy for the template instance AssocArray!(index, next) | |
169 * But the instantiation can fail if it is a template specialization field | |
170 * which has Tident's instead of real types. | |
171 */ | |
172 TemplateInstance ti = new TemplateInstance(loc, Id.AssociativeArray); | |
173 Objects tiargs = new Objects(); | |
111 | 174 tiargs.push(index); |
175 tiargs.push(next); | |
96 | 176 ti.tiargs = tiargs; |
177 | |
178 ti.semantic(sc); | |
179 ti.semantic2(sc); | |
180 ti.semantic3(sc); | |
181 impl = ti.toAlias().isStructDeclaration(); | |
182 debug | |
183 { | |
184 if (!impl) | |
185 { | |
186 Dsymbol s = ti.toAlias(); | |
187 writef("%s %s\n", s.kind(), s.toChars()); | |
188 } | |
189 } | |
190 assert(impl); | |
191 } | |
192 } | |
193 return impl; | |
194 | |
195 } | |
196 | |
72 | 197 override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) |
0 | 198 { |
51 | 199 //printf("TypeAArray.resolve() %s\n", toChars()); |
200 | |
201 // Deal with the case where we thought the index was a type, but | |
202 // in reality it was an expression. | |
203 if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) | |
204 { | |
205 Expression e; | |
206 Type t; | |
207 Dsymbol s; | |
208 | |
209 index.resolve(loc, sc, &e, &t, &s); | |
210 if (e) | |
211 { // It was an expression - | |
212 // Rewrite as a static array | |
213 | |
214 TypeSArray tsa = new TypeSArray(next, e); | |
215 return tsa.resolve(loc, sc, pe, pt, ps); | |
216 } | |
217 else if (t) | |
218 index = t; | |
219 else | |
220 index.error(loc, "index is not a type or an expression"); | |
221 } | |
222 Type.resolve(loc, sc, pe, pt, ps); | |
0 | 223 } |
224 | |
72 | 225 override void toDecoBuffer(OutBuffer buf, int flag) |
0 | 226 { |
227 Type.toDecoBuffer(buf, flag); | |
228 index.toDecoBuffer(buf); | |
229 next.toDecoBuffer(buf, (flag & 0x100) ? MOD.MODundefined : mod); | |
230 } | |
231 | |
72 | 232 override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) |
0 | 233 { |
68
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
234 if (mod != this.mod) |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
235 { |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
236 toCBuffer3(buf, hgs, mod); |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
237 return; |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
238 } |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
239 next.toCBuffer2(buf, hgs, this.mod); |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
240 buf.writeByte('['); |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
241 index.toCBuffer2(buf, hgs, MODundefined); |
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
242 buf.writeByte(']'); |
0 | 243 } |
244 | |
72 | 245 override Expression dotExp(Scope sc, Expression e, Identifier ident) |
0 | 246 { |
247 version (LOGDOTEXP) { | |
248 printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); | |
249 } | |
96 | 250 static if (false) |
251 { | |
0 | 252 if (ident == Id.length) |
253 { | |
254 Expression ec; | |
255 FuncDeclaration fd; | |
256 Expressions arguments; | |
257 | |
258 fd = FuncDeclaration.genCfunc(Type.tsize_t, Id.aaLen); | |
259 ec = new VarExp(Loc(0), fd); | |
260 arguments = new Expressions(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
261 arguments.push(e); |
0 | 262 e = new CallExp(e.loc, ec, arguments); |
263 e.type = (cast(TypeFunction)fd.type).next; | |
264 } | |
265 else if (ident == Id.keys) | |
266 { | |
267 Expression ec; | |
268 FuncDeclaration fd; | |
269 Expressions arguments; | |
270 int size = cast(int)index.size(e.loc); | |
271 | |
272 assert(size); | |
273 fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaKeys); | |
274 ec = new VarExp(Loc(0), fd); | |
275 arguments = new Expressions(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
276 arguments.push(e); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
277 arguments.push(new IntegerExp(Loc(0), size, Type.tsize_t)); |
0 | 278 e = new CallExp(e.loc, ec, arguments); |
279 e.type = index.arrayOf(); | |
280 } | |
281 else if (ident == Id.values) | |
282 { | |
283 Expression ec; | |
284 FuncDeclaration fd; | |
285 Expressions arguments; | |
286 | |
287 fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaValues); | |
288 ec = new VarExp(Loc(0), fd); | |
289 arguments = new Expressions(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
290 arguments.push(e); |
0 | 291 size_t keysize = cast(size_t)index.size(e.loc); |
292 keysize = (keysize + PTRSIZE - 1) & ~(PTRSIZE - 1); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
293 arguments.push(new IntegerExp(Loc(0), keysize, Type.tsize_t)); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
294 arguments.push(new IntegerExp(Loc(0), next.size(e.loc), Type.tsize_t)); |
0 | 295 e = new CallExp(e.loc, ec, arguments); |
296 e.type = next.arrayOf(); | |
297 } | |
298 else if (ident == Id.rehash) | |
299 { | |
300 Expression ec; | |
301 FuncDeclaration fd; | |
302 Expressions arguments; | |
303 | |
304 fd = FuncDeclaration.genCfunc(Type.tint64, Id.aaRehash); | |
305 ec = new VarExp(Loc(0), fd); | |
306 arguments = new Expressions(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
307 arguments.push(e.addressOf(sc)); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
308 arguments.push(index.getInternalTypeInfo(sc)); |
0 | 309 e = new CallExp(e.loc, ec, arguments); |
310 e.type = this; | |
311 } | |
96 | 312 // else |
313 } // of static if (false) | |
0 | 314 { |
96 | 315 e.type = getImpl().type; |
316 e = e.type.dotExp(sc, e, ident); | |
317 //e = Type.dotExp(sc, e, ident); | |
0 | 318 } |
319 return e; | |
320 } | |
321 | |
72 | 322 override Expression defaultInit(Loc loc) |
0 | 323 { |
324 version (LOGDEFAULTINIT) { | |
325 printf("TypeAArray.defaultInit() '%s'\n", toChars()); | |
326 } | |
135 | 327 return new NullExp(loc, this); |
0 | 328 } |
329 | |
72 | 330 override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) |
0 | 331 { |
51 | 332 static if (false) { |
333 printf("TypeAArray.deduceType()\n"); | |
334 printf("\tthis = %d, ", ty); print(); | |
335 printf("\ttparam = %d, ", tparam.ty); tparam.print(); | |
336 } | |
337 | |
338 // Extra check that index type must match | |
339 if (tparam && tparam.ty == Taarray) | |
340 { | |
341 TypeAArray tp = cast(TypeAArray)tparam; | |
342 if (!index.deduceType(sc, tp.index, parameters, dedtypes)) | |
343 { | |
344 return MATCHnomatch; | |
345 } | |
346 } | |
347 return Type.deduceType(sc, tparam, parameters, dedtypes); | |
0 | 348 } |
349 | |
72 | 350 override bool isZeroInit(Loc loc) |
0 | 351 { |
129 | 352 return true; |
0 | 353 } |
354 | |
72 | 355 override bool checkBoolean() |
0 | 356 { |
129 | 357 return true; |
0 | 358 } |
359 | |
72 | 360 override TypeInfoDeclaration getTypeInfoDeclaration() |
0 | 361 { |
68
ee3a9f34dc48
final bits of codegen implementation to compile Phobos
korDen
parents:
67
diff
changeset
|
362 return new TypeInfoAssociativeArrayDeclaration(this); |
0 | 363 } |
364 | |
72 | 365 override bool hasPointers() |
0 | 366 { |
367 return true; | |
368 } | |
369 | |
72 | 370 override MATCH implicitConvTo(Type to) |
0 | 371 { |
51 | 372 //printf("TypeAArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); |
373 if (equals(to)) | |
374 return MATCHexact; | |
375 | |
376 if (to.ty == Taarray) | |
377 { | |
378 TypeAArray ta = cast(TypeAArray)to; | |
379 | |
135 | 380 if (!MODimplicitConv(next.mod, ta.next.mod)) |
51 | 381 return MATCHnomatch; // not const-compatible |
382 | |
135 | 383 if (!MODimplicitConv(index.mod, ta.index.mod)) |
51 | 384 return MATCHnomatch; // not const-compatible |
385 | |
386 MATCH m = next.constConv(ta.next); | |
387 MATCH mi = index.constConv(ta.index); | |
388 if (m != MATCHnomatch && mi != MATCHnomatch) | |
389 { | |
390 if (m == MATCHexact && mod != to.mod) | |
391 m = MATCHconst; | |
392 if (mi < m) | |
393 m = mi; | |
394 return m; | |
395 } | |
396 } | |
397 return Type.implicitConvTo(to); | |
0 | 398 } |
399 | |
72 | 400 override MATCH constConv(Type to) |
0 | 401 { |
402 assert(false); | |
403 } | |
404 | |
405 version (CPP_MANGLE) { | |
406 void toCppMangle(OutBuffer buf, CppMangleState* cms) | |
407 { | |
408 assert(false); | |
409 } | |
410 } | |
411 | |
412 // Back end | |
413 /******************************************** | |
414 * Determine the right symbol to look up | |
415 * an associative array element. | |
416 * Input: | |
417 * flags 0 don't add value signature | |
418 * 1 add value signature | |
419 */ | |
420 Symbol* aaGetSymbol(const(char)* func, int flags) | |
421 in | |
422 { | |
423 assert(func); | |
424 assert((flags & ~1) == 0); | |
425 } | |
426 out (result) | |
427 { | |
428 assert(result); | |
429 } | |
430 body | |
431 { | |
432 int sz; | |
433 char* id; | |
434 type* t; | |
435 Symbol* s; | |
436 int i; | |
437 | |
438 //printf("aaGetSymbol(func = '%s', flags = %d, key = %p)\n", func, flags, key); | |
439 static if (false) { | |
440 scope OutBuffer buf = new OutBuffer(); | |
441 key.toKeyBuffer(buf); | |
442 | |
443 sz = next.size(); // it's just data, so we only care about the size | |
444 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
|
445 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
|
446 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
|
447 else |
0 | 448 id = cast(char*)alloca(3 + strlen(func) + buf.offset + sizeof(sz) * 3 + 1); |
449 buf.writeByte(0); | |
450 if (flags & 1) | |
451 sprintf(id, "_aa%s%s%d", func, buf.data, sz); | |
452 else | |
453 sprintf(id, "_aa%s%s", func, buf.data); | |
454 } 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
|
455 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
|
456 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
|
457 else |
0 | 458 id = cast(char*)alloca(3 + strlen(func) + 1); |
459 sprintf(id, "_aa%s", func); | |
460 } | |
461 | |
462 // See if symbol is already in sarray | |
176 | 463 for (i = 0; i < global.sarray.dim; i++) |
0 | 464 { |
176 | 465 s = cast(Symbol*)global.sarray.data[i]; |
0 | 466 if (strcmp(id, s.Sident.ptr) == 0) |
467 return s; // use existing Symbol | |
468 } | |
469 | |
470 // Create new Symbol | |
471 | |
472 s = symbol_calloc(id); | |
473 slist_add(s); | |
474 s.Sclass = SCextern; | |
475 s.Ssymnum = -1; | |
476 symbol_func(s); | |
477 | |
478 t = type_alloc(TYnfunc); | |
479 t.Tflags = TFprototype | TFfixed; | |
480 t.Tmangle = mTYman_c; | |
481 t.Tparamtypes = null; | |
482 t.Tnext = next.toCtype(); | |
483 t.Tnext.Tcount++; | |
484 t.Tcount++; | |
485 s.Stype = t; | |
486 | |
176 | 487 global.sarray.push(s); // remember it |
0 | 488 return s; |
489 } | |
490 | |
72 | 491 override type* toCtype() |
0 | 492 { |
67 | 493 type* t; |
494 | |
495 if (ctype) | |
496 return ctype; | |
497 | |
498 if (0 && global.params.symdebug) | |
499 { | |
500 /* An associative array is represented by: | |
501 * struct AArray { size_t length; void* ptr; } | |
502 */ | |
503 | |
176 | 504 auto s = global.AArray_s; |
67 | 505 if (!s) |
506 { | |
176 | 507 global.AArray_s = s = symbol_calloc("_AArray"); |
67 | 508 s.Sclass = SCstruct; |
509 s.Sstruct = struct_calloc(); | |
510 s.Sstruct.Sflags |= 0; | |
511 s.Sstruct.Salignsize = alignsize(); | |
512 s.Sstruct.Sstructalign = cast(ubyte)global.structalign; | |
513 s.Sstruct.Sstructsize = cast(uint)size(Loc(0)); | |
514 slist_add(s); | |
515 | |
516 Symbol* s1 = symbol_name("length", SCmember, Type.tsize_t.toCtype()); | |
517 list_append(&s.Sstruct.Sfldlst, s1); | |
518 | |
176 | 519 Symbol* s2 = symbol_name("data", SCmember, global.tvoidptr.toCtype()); |
67 | 520 s2.Smemoff = cast(uint)Type.tsize_t.size(); |
521 list_append(&s.Sstruct.Sfldlst, s2); | |
522 } | |
523 | |
524 t = type_alloc(TYstruct); | |
525 t.Ttag = cast(Classsym*)s; // structure tag name | |
526 t.Tcount++; | |
527 s.Stype = t; | |
528 } | |
529 else | |
530 { | |
531 if (global.params.symdebug == 1) | |
532 { | |
533 /* Generate D symbolic debug info, rather than C | |
534 * Tnext: element type | |
535 * Tkey: key type | |
536 */ | |
537 t = type_allocn(TYaarray, next.toCtype()); | |
538 t.Tkey = index.toCtype(); | |
539 t.Tkey.Tcount++; | |
540 } | |
541 else | |
542 t = type_fake(TYaarray); | |
543 } | |
544 t.Tcount++; | |
545 ctype = t; | |
546 return t; | |
0 | 547 } |
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
|
548 } |