1:
2: // Compiler implementation of the D programming language
3: // Copyright (c) 1999-2010 by Digital Mars
4: // All Rights Reserved
5: // written by Walter Bright
6: // http://www.digitalmars.com
7: // License for redistribution is by either the Artistic License
8: // in artistic.txt, or the GNU General Public License in gnu.txt.
9: // See the included readme.txt for details.
10:
11: #include <stdio.h>
12: static char __file__[] = __FILE__; /* for tassert.h */
13: #include "tassert.h"
14:
15: //#include "mem.h"
16:
17: #include "mars.h"
18: #include "module.h"
19: #include "mtype.h"
20: #include "scope.h"
21: #include "init.h"
22: #include "expression.h"
23: #include "attrib.h"
24: #include "declaration.h"
25: #include "template.h"
26: #include "id.h"
27: #include "enum.h"
28: #include "import.h"
29: #include "aggregate.h"
30:
31: #ifndef TARGET_NET
32: #include "rmem.h"
33: #include "cc.h"
34: #include "global.h"
35: #include "oper.h"
36: #include "code.h"
37: #include "type.h"
38: #include "dt.h"
39: #include "cgcv.h"
40: #include "outbuf.h"
41: #include "irstate.h"
42: #endif
43:
44: extern Symbol *static_sym();
45:
46: /*******************************************
47: * Get a canonicalized form of the TypeInfo for use with the internal
48: * runtime library routines. Canonicalized in that static arrays are
49: * represented as dynamic arrays, enums are represented by their
50: * underlying type, etc. This reduces the number of TypeInfo's needed,
51: * so we can use the custom internal ones more.
52: */
53:
54: Expression *Type::getInternalTypeInfo(Scope *sc)
55: { TypeInfoDeclaration *tid;
56: Expression *e;
57: Type *t;
58: static TypeInfoDeclaration *internalTI[TMAX];
59:
60: //printf("Type::getInternalTypeInfo() %s\n", toChars());
61: t = toBasetype();
62: switch (t->ty)
63: {
64: case Tsarray:
65: #if 0
66: // convert to corresponding dynamic array type
67: t = t->nextOf()->mutableOf()->arrayOf();
68: #endif
69: break;
70:
71: case Tclass:
72: if (((TypeClass *)t)->sym->isInterfaceDeclaration())
73: break;
74: goto Linternal;
75:
76: case Tarray:
77: // convert to corresponding dynamic array type
78: t = t->nextOf()->mutableOf()->arrayOf();
79: if (t->nextOf()->ty != Tclass)
80: break;
81: goto Linternal;
82:
83: case Tfunction:
84: case Tdelegate:
85: case Tpointer:
86: Linternal:
87: tid = internalTI[t->ty];
88: if (!tid)
89: { tid = new TypeInfoDeclaration(t, 1);
90: internalTI[t->ty] = tid;
91: }
92: e = new VarExp(0, tid);
93: e = e->addressOf(sc);
94: e->type = tid->type; // do this so we don't get redundant dereference
95: return e;
96:
97: default:
98: break;
99: }
100: //printf("\tcalling getTypeInfo() %s\n", t->toChars());
101: return t->getTypeInfo(sc);
102: }
103:
104:
105: /****************************************************
106: * Get the exact TypeInfo.
107: */
108:
109: Expression *Type::getTypeInfo(Scope *sc)
110: {
111: //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
112: if (!Type::typeinfo)
113: {
114: error(0, "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
115: fatal();
116: }
117:
118: Type *t = merge2(); // do this since not all Type's are merge'd
119: if (!t->vtinfo)
120: {
121: #if DMDV2
122: if (t->isShared()) // does both 'shared' and 'shared const'
123: t->vtinfo = new TypeInfoSharedDeclaration(t);
124: else if (t->isConst())
125: t->vtinfo = new TypeInfoConstDeclaration(t);
126: else if (t->isImmutable())
127: t->vtinfo = new TypeInfoInvariantDeclaration(t);
128: else if (t->isWild())
129: t->vtinfo = new TypeInfoWildDeclaration(t);
130: else
131: #endif
132: t->vtinfo = t->getTypeInfoDeclaration();
133: assert(t->vtinfo);
134: vtinfo = t->vtinfo;
135:
136: /* If this has a custom implementation in std/typeinfo, then
137: * do not generate a COMDAT for it.
138: */
139: if (!t->builtinTypeInfo())
140: { // Generate COMDAT
141: if (sc) // if in semantic() pass
142: { // Find module that will go all the way to an object file
143: Module *m = sc->module->importedFrom;
144: m->members->push(t->vtinfo);
145: }
146: else // if in obj generation pass
147: {
148: t->vtinfo->toObjFile(global.params.multiobj);
149: }
150: }
151: }
152: if (!vtinfo)
153: vtinfo = t->vtinfo; // Types aren't merged, but we can share the vtinfo's
154: Expression *e = new VarExp(0, t->vtinfo);
155: e = e->addressOf(sc);
156: e->type = t->vtinfo->type; // do this so we don't get redundant dereference
157: return e;
158: }
159:
160: TypeInfoDeclaration *Type::getTypeInfoDeclaration()
161: {
162: //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
163: return new TypeInfoDeclaration(this, 0);
164: }
165:
166: TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
167: {
168: return new TypeInfoTypedefDeclaration(this);
169: }
170:
171: TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
172: {
173: return new TypeInfoPointerDeclaration(this);
174: }
175:
176: TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
177: {
178: return new TypeInfoArrayDeclaration(this);
179: }
180:
181: TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
182: {
183: return new TypeInfoStaticArrayDeclaration(this);
184: }
185:
186: TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
187: {
188: return new TypeInfoAssociativeArrayDeclaration(this);
189: }
190:
191: TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
192: {
193: return new TypeInfoStructDeclaration(this);
194: }
195:
196: TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
197: {
198: if (sym->isInterfaceDeclaration())
199: return new TypeInfoInterfaceDeclaration(this);
200: else
201: return new TypeInfoClassDeclaration(this);
202: }
203:
204: TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
205: {
206: return new TypeInfoEnumDeclaration(this);
207: }
208:
209: TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
210: {
211: return new TypeInfoFunctionDeclaration(this);
212: }
213:
214: TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
215: {
216: return new TypeInfoDelegateDeclaration(this);
217: }
218:
219: TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
220: {
221: return new TypeInfoTupleDeclaration(this);
222: }
223:
224: #ifndef TARGET_NET
225: /****************************************************
226: */
227:
228: #if 1
229:
230: void TypeInfoDeclaration::toDt(dt_t **pdt)
231: {
232: //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
233: dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
234: dtsize_t(pdt, 0); // monitor
235: }
236:
237: #if DMDV2
238: void TypeInfoConstDeclaration::toDt(dt_t **pdt)
239: {
240: //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
241: dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const
242: dtsize_t(pdt, 0); // monitor
243: Type *tm = tinfo->mutableOf();
244: tm = tm->merge();
245: tm->getTypeInfo(NULL);
246: dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
247: }
248:
249: void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
250: {
251: //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
252: dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
253: dtsize_t(pdt, 0); // monitor
254: Type *tm = tinfo->mutableOf();
255: tm = tm->merge();
256: tm->getTypeInfo(NULL);
257: dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
258: }
259:
260: void TypeInfoSharedDeclaration::toDt(dt_t **pdt)
261: {
262: //printf("TypeInfoSharedDeclaration::toDt() %s\n", toChars());
263: dtxoff(pdt, Type::typeinfoshared->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared
264: dtsize_t(pdt, 0); // monitor
265: Type *tm = tinfo->unSharedOf();
266: tm = tm->merge();
267: tm->getTypeInfo(NULL);
268: dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
269: }
270:
271: void TypeInfoWildDeclaration::toDt(dt_t **pdt)
272: {
273: //printf("TypeInfoWildDeclaration::toDt() %s\n", toChars());
274: dtxoff(pdt, Type::typeinfowild->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Wild
275: dtsize_t(pdt, 0); // monitor
276: Type *tm = tinfo->mutableOf();
277: tm = tm->merge();
278: tm->getTypeInfo(NULL);
279: dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
280: }
281:
282: #endif
283:
284: void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
285: {
286: //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
287:
288: dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
289: dtsize_t(pdt, 0); // monitor
290:
291: assert(tinfo->ty == Ttypedef);
292:
293: TypeTypedef *tc = (TypeTypedef *)tinfo;
294: TypedefDeclaration *sd = tc->sym;
295: //printf("basetype = %s\n", sd->basetype->toChars());
296:
297: /* Put out:
298: * TypeInfo base;
299: * char[] name;
300: * void[] m_init;
301: */
302:
303: sd->basetype = sd->basetype->merge();
304: sd->basetype->getTypeInfo(NULL); // generate vtinfo
305: assert(sd->basetype->vtinfo);
306: dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
307:
308: const char *name = sd->toPrettyChars();
309: size_t namelen = strlen(name);
310: dtsize_t(pdt, namelen);
311: dtabytes(pdt, TYnptr, 0, namelen + 1, name);
312:
313: // void[] init;
314: if (tinfo->isZeroInit() || !sd->init)
315: { // 0 initializer, or the same as the base type
316: dtsize_t(pdt, 0); // init.length
317: dtsize_t(pdt, 0); // init.ptr
318: }
319: else
320: {
321: dtsize_t(pdt, sd->type->size()); // init.length
warning C4244: 'argument' : conversion from 'd_uns64' to 'targ_size_t', possible loss of data
322: dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
323: }
324: }
325:
326: void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
327: {
328: //printf("TypeInfoEnumDeclaration::toDt()\n");
329: dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
330: dtsize_t(pdt, 0); // monitor
331:
332: assert(tinfo->ty == Tenum);
333:
334: TypeEnum *tc = (TypeEnum *)tinfo;
335: EnumDeclaration *sd = tc->sym;
336:
337: /* Put out:
338: * TypeInfo base;
339: * char[] name;
340: * void[] m_init;
341: */
342:
343: if (sd->memtype)
344: { sd->memtype->getTypeInfo(NULL);
345: dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
346: }
347: else
348: dtsize_t(pdt, 0);
349:
350: const char *name = sd->toPrettyChars();
351: size_t namelen = strlen(name);
352: dtsize_t(pdt, namelen);
353: dtabytes(pdt, TYnptr, 0, namelen + 1, name);
354:
355: // void[] init;
356: if (!sd->defaultval || tinfo->isZeroInit())
357: { // 0 initializer, or the same as the base type
358: dtsize_t(pdt, 0); // init.length
359: dtsize_t(pdt, 0); // init.ptr
360: }
361: else
362: {
363: dtsize_t(pdt, sd->type->size()); // init.length
warning C4244: 'argument' : conversion from 'd_uns64' to 'targ_size_t', possible loss of data
364: dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
365: }
366: }
367:
368: void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
369: {
370: //printf("TypeInfoPointerDeclaration::toDt()\n");
371: dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
372: dtsize_t(pdt, 0); // monitor
373:
374: assert(tinfo->ty == Tpointer);
375:
376: TypePointer *tc = (TypePointer *)tinfo;
377:
378: tc->next->getTypeInfo(NULL);
379: dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
380: }
381:
382: void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
383: {
384: //printf("TypeInfoArrayDeclaration::toDt()\n");
385: dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
386: dtsize_t(pdt, 0); // monitor
387:
388: assert(tinfo->ty == Tarray);
389:
390: TypeDArray *tc = (TypeDArray *)tinfo;
391:
392: tc->next->getTypeInfo(NULL);
393: dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
394: }
395:
396: void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
397: {
398: //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
399: dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
400: dtsize_t(pdt, 0); // monitor
401:
402: assert(tinfo->ty == Tsarray);
403:
404: TypeSArray *tc = (TypeSArray *)tinfo;
405:
406: tc->next->getTypeInfo(NULL);
407: dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
408:
409: dtsize_t(pdt, tc->dim->toInteger()); // length
warning C4244: 'argument' : conversion from 'dinteger_t' to 'targ_size_t', possible loss of data
410: }
411:
412: void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
413: {
414: //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
415: dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
416: dtsize_t(pdt, 0); // monitor
417:
418: assert(tinfo->ty == Taarray);
419:
420: TypeAArray *tc = (TypeAArray *)tinfo;
421:
422: tc->next->getTypeInfo(NULL);
423: dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
424:
425: tc->index->getTypeInfo(NULL);
426: dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
427:
428: #if DMDV2
429: tc->getImpl()->type->getTypeInfo(NULL);
430: dtxoff(pdt, tc->getImpl()->type->vtinfo->toSymbol(), 0, TYnptr); // impl
431: #endif
432: }
433:
434: void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
435: {
436: //printf("TypeInfoFunctionDeclaration::toDt()\n");
437: dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
438: dtsize_t(pdt, 0); // monitor
439:
440: assert(tinfo->ty == Tfunction);
441:
442: TypeFunction *tc = (TypeFunction *)tinfo;
443:
444: tc->next->getTypeInfo(NULL);
445: dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
446:
447: const char *name = tinfo->deco;
448: assert(name);
449: size_t namelen = strlen(name);
450: dtsize_t(pdt, namelen);
451: dtabytes(pdt, TYnptr, 0, namelen + 1, name);
452: }
453:
454: void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
455: {
456: //printf("TypeInfoDelegateDeclaration::toDt()\n");
457: dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
458: dtsize_t(pdt, 0); // monitor
459:
460: assert(tinfo->ty == Tdelegate);
461:
462: TypeDelegate *tc = (TypeDelegate *)tinfo;
463:
464: tc->next->nextOf()->getTypeInfo(NULL);
465: dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
466:
467: const char *name = tinfo->deco;
468: assert(name);
469: size_t namelen = strlen(name);
470: dtsize_t(pdt, namelen);
471: dtabytes(pdt, TYnptr, 0, namelen + 1, name);
472: }
473:
474: void TypeInfoStructDeclaration::toDt(dt_t **pdt)
475: {
476: //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
477:
478: unsigned offset = Type::typeinfostruct->structsize;
479:
480: dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
481: dtsize_t(pdt, 0); // monitor
482:
483: assert(tinfo->ty == Tstruct);
484:
485: TypeStruct *tc = (TypeStruct *)tinfo;
486: StructDeclaration *sd = tc->sym;
487:
488: /* Put out:
489: * char[] name;
490: * void[] init;
491: * hash_t function(in void*) xtoHash;
492: * bool function(in void*, in void*) xopEquals;
493: * int function(in void*, in void*) xopCmp;
494: * string function(const(void)*) xtoString;
495: * uint m_flags;
496: * xgetMembers;
497: * xdtor;
498: * xpostblit;
499: * uint m_align;
500: * version (X86_64)
501: * TypeInfo m_arg1;
502: * TypeInfo m_arg2;
503: *
504: * name[]
505: */
506:
507: const char *name = sd->toPrettyChars();
508: size_t namelen = strlen(name);
509: dtsize_t(pdt, namelen);
510: //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
511: dtxoff(pdt, toSymbol(), offset, TYnptr);
512: offset += namelen + 1;
513:
514: // void[] init;
515: dtsize_t(pdt, sd->structsize); // init.length
516: if (sd->zeroInit)
517: dtsize_t(pdt, 0); // NULL for 0 initialization
518: else
519: dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
520:
521: FuncDeclaration *fd;
522: FuncDeclaration *fdx;
523: TypeFunction *tf;
warning C4101: 'tf' : unreferenced local variable
524: Type *ta;
warning C4101: 'ta' : unreferenced local variable
525: Dsymbol *s;
526:
527: static TypeFunction *tftohash;
528: static TypeFunction *tftostring;
529:
530: if (!tftohash)
531: {
532: Scope sc;
533:
534: tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
535: tftohash->mod = MODconst;
536: tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
537:
538: tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
539: tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
540: }
541:
542: TypeFunction *tfcmpptr;
543: {
544: Scope sc;
545: Parameters *arguments = new Parameters;
warning C6211: Leaking memory 'arguments' due to an exception. Consider using a local catch block to clean up memory: Lines: 478, 480, 481, 483, 485, 486, 507, 508, 509, 511, 512, 515, 516, 517, 521, 522, 523, 524, 525, 527, 528, 530, 532, 534, 535, 536, 538, 539, 542, 544, 545, 548
546: #if STRUCTTHISREF
547: // arg type is ref const T
548: Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
549: #else
550: // arg type is const T*
551: Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
552: #endif
553:
554: arguments->push(arg);
555: tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
556: tfcmpptr->mod = MODconst;
557: tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc);
558: }
559:
560: s = search_function(sd, Id::tohash);
561: fdx = s ? s->isFuncDeclaration() : NULL;
562: if (fdx)
563: { fd = fdx->overloadExactMatch(tftohash);
564: if (fd)
565: dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
566: else
567: //fdx->error("must be declared as extern (D) uint toHash()");
568: dtsize_t(pdt, 0);
569: }
570: else
571: dtsize_t(pdt, 0);
572:
573: if (sd->eq)
574: dtxoff(pdt, sd->eq->toSymbol(), 0, TYnptr);
575: else
576: dtsize_t(pdt, 0);
577:
578: s = search_function(sd, Id::cmp);
579: fdx = s ? s->isFuncDeclaration() : NULL;
580: if (fdx)
581: {
582: //printf("test1 %s, %s, %s\n", fdx->toChars(), fdx->type->toChars(), tfeqptr->toChars());
583: fd = fdx->overloadExactMatch(tfcmpptr);
584: if (fd)
585: { dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
586: //printf("test2\n");
587: }
588: else
589: //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
590: dtsize_t(pdt, 0);
591: }
592: else
593: dtsize_t(pdt, 0);
594:
595: s = search_function(sd, Id::tostring);
596: fdx = s ? s->isFuncDeclaration() : NULL;
597: if (fdx)
598: { fd = fdx->overloadExactMatch(tftostring);
599: if (fd)
600: dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
601: else
602: //fdx->error("must be declared as extern (D) char[] toString()");
603: dtsize_t(pdt, 0);
604: }
605: else
606: dtsize_t(pdt, 0);
607:
608: // uint m_flags;
609: dtsize_t(pdt, tc->hasPointers());
610:
611: #if DMDV2
612: // xgetMembers
613: FuncDeclaration *sgetmembers = sd->findGetMembers();
614: if (sgetmembers)
615: dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
616: else
617: dtsize_t(pdt, 0); // xgetMembers
618:
619: // xdtor
620: FuncDeclaration *sdtor = sd->dtor;
621: if (sdtor)
622: dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
623: else
624: dtsize_t(pdt, 0); // xdtor
625:
626: // xpostblit
627: FuncDeclaration *spostblit = sd->postblit;
628: if (spostblit && !(spostblit->storage_class & STCdisable))
629: dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
630: else
631: dtsize_t(pdt, 0); // xpostblit
632: #endif
633:
634: // uint m_align;
635: dtsize_t(pdt, tc->alignsize());
636:
637: if (global.params.is64bit)
638: {
639: TypeTuple *tup = tc->toArgTypes();
640: assert(tup->arguments->dim <= 2);
641: for (int i = 0; i < 2; i++)
642: {
643: if (i < tup->arguments->dim)
warning C4018: '<' : signed/unsigned mismatch
644: {
645: Type *targ = (tup->arguments->tdata()[i])->type;
646: targ = targ->merge();
647: targ->getTypeInfo(NULL);
648: dtxoff(pdt, targ->vtinfo->toSymbol(), 0, TYnptr); // m_argi
649: }
650: else
651: dtsize_t(pdt, 0); // m_argi
652: }
653: }
654:
655: // name[]
656: dtnbytes(pdt, namelen + 1, name);
657: }
658:
659: void TypeInfoClassDeclaration::toDt(dt_t **pdt)
660: {
661: //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
662: #if DMDV1
663: dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
664: dtsize_t(pdt, 0); // monitor
665:
666: assert(tinfo->ty == Tclass);
667:
668: TypeClass *tc = (TypeClass *)tinfo;
669: Symbol *s;
670:
671: if (!tc->sym->vclassinfo)
672: tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
673: s = tc->sym->vclassinfo->toSymbol();
674: dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
675: #else
676: assert(0);
677: #endif
678: }
679:
680: void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
681: {
682: //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
683: dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
684: dtsize_t(pdt, 0); // monitor
685:
686: assert(tinfo->ty == Tclass);
687:
688: TypeClass *tc = (TypeClass *)tinfo;
689: Symbol *s;
690:
691: if (!tc->sym->vclassinfo)
692: #if DMDV1
693: tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
694: #else
695: tc->sym->vclassinfo = new TypeInfoClassDeclaration(tc);
696: #endif
697: s = tc->sym->vclassinfo->toSymbol();
698: dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
699: }
700:
701: void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
702: {
703: //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
704: dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
705: dtsize_t(pdt, 0); // monitor
706:
707: assert(tinfo->ty == Ttuple);
708:
709: TypeTuple *tu = (TypeTuple *)tinfo;
710:
711: size_t dim = tu->arguments->dim;
712: dtsize_t(pdt, dim); // elements.length
713:
714: dt_t *d = NULL;
715: for (size_t i = 0; i < dim; i++)
716: { Parameter *arg = tu->arguments->tdata()[i];
717: Expression *e = arg->type->getTypeInfo(NULL);
718: e = e->optimize(WANTvalue);
719: e->toDt(&d);
720: }
721:
722: Symbol *s;
723: s = static_sym();
724: s->Sdt = d;
725: outdata(s);
726:
727: dtxoff(pdt, s, 0, TYnptr); // elements.ptr
728: }
729:
730: void TypeInfoDeclaration::toObjFile(int multiobj)
731: {
732: Symbol *s;
733: unsigned sz;
734: Dsymbol *parent;
735:
736: //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
737:
738: if (multiobj)
739: {
740: obj_append(this);
741: return;
742: }
743:
744: s = toSymbol();
745: sz = type->size();
warning C4244: '=' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
746:
747: parent = this->toParent();
748: s->Sclass = SCcomdat;
749: s->Sfl = FLdata;
750:
751: toDt(&s->Sdt);
752:
753: dt_optimize(s->Sdt);
754:
755: // See if we can convert a comdat to a comdef,
756: // which saves on exe file space.
757: if (s->Sclass == SCcomdat &&
758: s->Sdt->dt == DT_azeros &&
759: s->Sdt->DTnext == NULL)
760: {
761: s->Sclass = SCglobal;
762: s->Sdt->dt = DT_common;
763: }
764:
765: #if ELFOBJ || MACHOBJ // Burton
766: if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
767: s->Sseg = UDATA;
768: else
769: s->Sseg = DATA;
770: #endif
771: outdata(s);
772: if (isExport())
773: obj_export(s,0);
774: }
775:
776: #endif
777: #endif // TARGET_NET
778:
779: /* ========================================================================= */
780:
781: /* These decide if there's an instance for them already in std.typeinfo,
782: * because then the compiler doesn't need to build one.
783: */
784:
785: int Type::builtinTypeInfo()
786: {
787: return 0;
788: }
789:
790: int TypeBasic::builtinTypeInfo()
791: {
792: #if DMDV2
793: return mod ? 0 : 1;
794: #else
795: return 1;
796: #endif
797: }
798:
799: int TypeDArray::builtinTypeInfo()
800: {
801: #if DMDV2
802: return !mod && (next->isTypeBasic() != NULL && !next->mod ||
803: // strings are so common, make them builtin
804: next->ty == Tchar && next->mod == MODimmutable);
805: #else
806: return next->isTypeBasic() != NULL;
807: #endif
808: }
809:
810: int TypeClass::builtinTypeInfo()
811: {
812: /* This is statically put out with the ClassInfo, so
813: * claim it is built in so it isn't regenerated by each module.
814: */
815: #if DMDV2
816: return mod ? 0 : 1;
817: #else
818: return 1;
819: #endif
820: }
821:
822: /* ========================================================================= */
823:
824: /***************************************
825: * Create a static array of TypeInfo references
826: * corresponding to an array of Expression's.
827: * Used to supply hidden _arguments[] value for variadic D functions.
828: */
829:
830: Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
831: {
832: #if 1
833: /* Get the corresponding TypeInfo_Tuple and
834: * point at its elements[].
835: */
836:
837: /* Create the TypeTuple corresponding to the types of args[]
838: */
839: Parameters *args = new Parameters;
warning C6211: Leaking memory 'args' due to an exception. Consider using a local catch block to clean up memory: Lines: 839, 840, 841, 842
840: args->setDim(dim);
841: for (size_t i = 0; i < dim; i++)
warning C4018: '<' : signed/unsigned mismatch
842: { Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL);
843: args->tdata()[i] = arg;
844: }
845: TypeTuple *tup = new TypeTuple(args);
846: Expression *e = tup->getTypeInfo(sc);
847: e = e->optimize(WANTvalue);
848: assert(e->op == TOKsymoff); // should be SymOffExp
849:
850: #if BREAKABI
851: /*
852: * Should just pass a reference to TypeInfo_Tuple instead,
853: * but that would require existing code to be recompiled.
854: * Source compatibility can be maintained by computing _arguments[]
855: * at the start of the called function by offseting into the
856: * TypeInfo_Tuple reference.
857: */
858:
859: #else
860: // Advance to elements[] member of TypeInfo_Tuple
861: SymOffExp *se = (SymOffExp *)e;
862: se->offset += PTRSIZE + PTRSIZE;
863:
864: // Set type to TypeInfo[]*
865: se->type = Type::typeinfo->type->arrayOf()->pointerTo();
866:
867: // Indirect to get the _arguments[] value
868: e = new PtrExp(0, se);
869: e->type = se->type->next;
870: #endif
871: return e;
872: #else
873: /* Improvements:
874: * 1) create an array literal instead,
875: * as it would eliminate the extra dereference of loading the
876: * static variable.
877: */
878:
879: ArrayInitializer *ai = new ArrayInitializer(0);
880: VarDeclaration *v;
881: Type *t;
882: Expression *e;
883: OutBuffer buf;
884: Identifier *id;
885: char *name;
886:
887: // Generate identifier for _arguments[]
888: buf.writestring("_arguments_");
889: for (int i = 0; i < dim; i++)
890: { t = exps[i]->type;
891: t->toDecoBuffer(&buf);
892: }
893: buf.writeByte(0);
894: id = Lexer::idPool((char *)buf.data);
895:
896: Module *m = sc->module;
897: Dsymbol *s = m->symtab->lookup(id);
898:
899: if (s && s->parent == m)
900: { // Use existing one
901: v = s->isVarDeclaration();
902: assert(v);
903: }
904: else
905: { // Generate new one
906:
907: for (int i = 0; i < dim; i++)
908: { t = exps[i]->type;
909: e = t->getTypeInfo(sc);
910: ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
911: }
912:
913: t = Type::typeinfo->type->arrayOf();
914: ai->type = t;
915: v = new VarDeclaration(0, t, id, ai);
916: m->members->push(v);
917: m->symtabInsert(v);
918: sc = sc->push();
919: sc->linkage = LINKc;
920: sc->stc = STCstatic | STCcomdat;
921: ai->semantic(sc, t);
922: v->semantic(sc);
923: v->parent = m;
924: sc = sc->pop();
925: }
926: e = new VarExp(0, v);
927: e = e->semantic(sc);
928: return e;
929: #endif
930: }
931:
932:
933:
934: