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