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: