1: 
   2: // Copyright (c) 1999-2010 by Digital Mars
   3: // All Rights Reserved
   4: // written by Walter Bright
   5: // http://www.digitalmars.com
   6: // License for redistribution is by either the Artistic License
   7: // in artistic.txt, or the GNU General Public License in gnu.txt.
   8: // See the included readme.txt for details.
   9: 
  10: #include <stdio.h>
  11: #include <stddef.h>
  12: #include <time.h>
  13: static char __file__[] = __FILE__;      /* for tassert.h                */
  14: #include        "tassert.h"
  15: 
  16: #include "mars.h"
  17: #include "module.h"
  18: #include "mtype.h"
  19: #include "declaration.h"
  20: #include "statement.h"
  21: #include "enum.h"
  22: #include "aggregate.h"
  23: #include "init.h"
  24: #include "attrib.h"
  25: #include "id.h"
  26: #include "import.h"
  27: #include "template.h"
  28: 
  29: #include "rmem.h"
  30: #include "cc.h"
  31: #include "global.h"
  32: #include "oper.h"
  33: #include "code.h"
  34: #include "type.h"
  35: #include "dt.h"
  36: #include "cgcv.h"
  37: #include "outbuf.h"
  38: #include "irstate.h"
  39: 
  40: void obj_lzext(Symbol *s1,Symbol *s2);
  41: 
  42: /* ================================================================== */
  43: 
  44: // Put out instance of ModuleInfo for this Module
  45: 
  46: void Module::genmoduleinfo()
  47: {
  48:     //printf("Module::genmoduleinfo() %s\n", toChars());
  49: 
  50:     Symbol *msym = toSymbol();
  51:     unsigned offset;
warning C4101: 'offset' : unreferenced local variable
52: #if DMDV2 53: unsigned sizeof_ModuleInfo = 16 * PTRSIZE; 54: #else 55: unsigned sizeof_ModuleInfo = 14 * PTRSIZE; 56: #endif 57: #if !MODULEINFO_IS_STRUCT 58: sizeof_ModuleInfo -= 2 * PTRSIZE; 59: #endif 60: //printf("moduleinfo size = x%x\n", sizeof_ModuleInfo); 61: 62: ////////////////////////////////////////////// 63: 64: csym->Sclass = SCglobal; 65: csym->Sfl = FLdata; 66: 67: #if 1 68: dt_t *dt = NULL; 69: ClassDeclarations aclasses; 70: 71: //printf("members->dim = %d\n", members->dim); 72: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
73: { Dsymbol *member = members->tdata()[i]; 74: 75: //printf("\tmember '%s'\n", member->toChars()); 76: member->addLocalClass(&aclasses); 77: } 78: 79: // importedModules[] 80: int aimports_dim = aimports.dim; 81: for (int i = 0; i < aimports.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
82: { Module *m = aimports.tdata()[i]; 83: if (!m->needmoduleinfo) 84: aimports_dim--; 85: } 86: 87: FuncDeclaration *sgetmembers = findGetMembers(); 88: 89: // These must match the values in druntime/src/object_.d 90: #define MIstandalone 4 91: #define MItlsctor 8 92: #define MItlsdtor 0x10 93: #define MIctor 0x20 94: #define MIdtor 0x40 95: #define MIxgetMembers 0x80 96: #define MIictor 0x100 97: #define MIunitTest 0x200 98: #define MIimportedModules 0x400 99: #define MIlocalClasses 0x800 100: #define MInew 0x80000000 // it's the "new" layout 101: 102: unsigned flags = MInew; 103: if (sctor) 104: flags |= MItlsctor; 105: if (sdtor) 106: flags |= MItlsdtor; 107: if (ssharedctor) 108: flags |= MIctor; 109: if (sshareddtor) 110: flags |= MIdtor; 111: if (sgetmembers) 112: flags |= MIxgetMembers; 113: if (sictor) 114: flags |= MIictor; 115: if (stest) 116: flags |= MIunitTest; 117: if (aimports_dim) 118: flags |= MIimportedModules; 119: if (aclasses.dim) 120: flags |= MIlocalClasses; 121: 122: if (!needmoduleinfo) 123: flags |= MIstandalone; 124: 125: dtdword(&dt, flags); // n.flags 126: dtdword(&dt, 0); // n.index 127: 128: if (flags & MItlsctor) 129: dtxoff(&dt, sctor, 0, TYnptr); 130: if (flags & MItlsdtor) 131: dtxoff(&dt, sdtor, 0, TYnptr); 132: if (flags & MIctor) 133: dtxoff(&dt, ssharedctor, 0, TYnptr); 134: if (flags & MIdtor) 135: dtxoff(&dt, sshareddtor, 0, TYnptr); 136: if (flags & MIxgetMembers) 137: dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr); 138: if (flags & MIictor) 139: dtxoff(&dt, sictor, 0, TYnptr); 140: if (flags & MIunitTest) 141: dtxoff(&dt, stest, 0, TYnptr); 142: if (flags & MIimportedModules) 143: { 144: dtsize_t(&dt, aimports_dim); 145: for (int i = 0; i < aimports.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
146: { Module *m = aimports.tdata()[i]; 147: 148: if (m->needmoduleinfo) 149: { Symbol *s = m->toSymbol(); 150: 151: /* Weak references don't pull objects in from the library, 152: * they resolve to 0 if not pulled in by something else. 153: * Don't pull in a module just because it was imported. 154: */ 155: #if !OMFOBJ // Optlink crashes with weak symbols at EIP 41AFE7, 402000 156: s->Sflags |= SFLweak; 157: #endif 158: dtxoff(&dt, s, 0, TYnptr); 159: } 160: } 161: } 162: if (flags & MIlocalClasses) 163: { 164: dtsize_t(&dt, aclasses.dim); 165: for (int i = 0; i < aclasses.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
166: { 167: ClassDeclaration *cd = aclasses.tdata()[i]; 168: dtxoff(&dt, cd->toSymbol(), 0, TYnptr); 169: } 170: } 171: 172: // Put out module name as a 0-terminated string, to save bytes 173: nameoffset = dt_size(dt); 174: const char *name = toPrettyChars(); 175: namelen = strlen(name); 176: dtnbytes(&dt, namelen + 1, name); 177: //printf("nameoffset = x%x\n", nameoffset); 178: #else 179: /* The layout is: 180: { 181: void **vptr; 182: monitor_t monitor; 183: char[] name; // class name 184: ModuleInfo importedModules[]; 185: ClassInfo localClasses[]; 186: uint flags; // initialization state 187: void *ctor; 188: void *dtor; 189: void *unitTest; 190: const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function 191: void *ictor; 192: void *sharedctor; 193: void *shareddtor; 194: uint index; 195: void*[1] reserved; 196: } 197: */ 198: dt_t *dt = NULL; 199: 200: #if !MODULEINFO_IS_STRUCT 201: if (moduleinfo) 202: dtxoff(&dt, moduleinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ModuleInfo 203: else 204: { //printf("moduleinfo is null\n"); 205: dtdword(&dt, 0); // BUG: should be an assert() 206: } 207: dtdword(&dt, 0); // monitor 208: #endif 209: 210: // name[] 211: const char *name = toPrettyChars(); 212: size_t namelen = strlen(name); 213: dtdword(&dt, namelen); 214: dtabytes(&dt, TYnptr, 0, namelen + 1, name); 215: 216: ClassDeclarations aclasses; 217: 218: //printf("members->dim = %d\n", members->dim); 219: for (int i = 0; i < members->dim; i++) 220: { Dsymbol *member = members->tdata()[i]; 221: 222: //printf("\tmember '%s'\n", member->toChars()); 223: member->addLocalClass(&aclasses); 224: } 225: 226: // importedModules[] 227: int aimports_dim = aimports.dim; 228: for (int i = 0; i < aimports.dim; i++) 229: { Module *m = aimports.tdata()[i]; 230: if (!m->needModuleInfo()) 231: aimports_dim--; 232: } 233: dtdword(&dt, aimports_dim); 234: if (aimports_dim) 235: dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr); 236: else 237: dtdword(&dt, 0); 238: 239: // localClasses[] 240: dtdword(&dt, aclasses.dim); 241: if (aclasses.dim) 242: dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr); 243: else 244: dtdword(&dt, 0); 245: 246: if (needmoduleinfo) 247: dtdword(&dt, 8); // flags 248: else 249: dtdword(&dt, 8 | MIstandalone); // flags 250: 251: if (ssharedctor) 252: dtxoff(&dt, ssharedctor, 0, TYnptr); 253: else 254: dtdword(&dt, 0); 255: 256: if (sshareddtor) 257: dtxoff(&dt, sshareddtor, 0, TYnptr); 258: else 259: dtdword(&dt, 0); 260: 261: if (stest) 262: dtxoff(&dt, stest, 0, TYnptr); 263: else 264: dtdword(&dt, 0); 265: 266: #if DMDV2 267: FuncDeclaration *sgetmembers = findGetMembers(); 268: if (sgetmembers) 269: dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr); 270: else 271: #endif 272: dtdword(&dt, 0); // xgetMembers 273: 274: if (sictor) 275: dtxoff(&dt, sictor, 0, TYnptr); 276: else 277: dtdword(&dt, 0); 278: 279: #if DMDV2 280: if (sctor) 281: dtxoff(&dt, sctor, 0, TYnptr); 282: else 283: dtdword(&dt, 0); 284: 285: if (sdtor) 286: dtxoff(&dt, sdtor, 0, TYnptr); 287: else 288: dtdword(&dt, 0); 289: 290: dtdword(&dt, 0); // index 291: 292: // void*[1] reserved; 293: dtdword(&dt, 0); 294: #endif 295: ////////////////////////////////////////////// 296: 297: for (int i = 0; i < aimports.dim; i++) 298: { Module *m = aimports.tdata()[i]; 299: 300: if (m->needModuleInfo()) 301: { Symbol *s = m->toSymbol(); 302: 303: /* Weak references don't pull objects in from the library, 304: * they resolve to 0 if not pulled in by something else. 305: * Don't pull in a module just because it was imported. 306: */ 307: #if !OMFOBJ // Optlink crashes with weak symbols at EIP 41AFE7, 402000 308: s->Sflags |= SFLweak; 309: #endif 310: dtxoff(&dt, s, 0, TYnptr); 311: } 312: } 313: 314: for (int i = 0; i < aclasses.dim; i++) 315: { 316: ClassDeclaration *cd = aclasses.data()[i]; 317: dtxoff(&dt, cd->toSymbol(), 0, TYnptr); 318: } 319: #endif 320: 321: csym->Sdt = dt; 322: #if ELFOBJ || MACHOBJ 323: // Cannot be CONST because the startup code sets flag bits in it 324: csym->Sseg = DATA; 325: #endif 326: outdata(csym); 327: 328: ////////////////////////////////////////////// 329: 330: obj_moduleinfo(msym); 331: } 332: 333: /* ================================================================== */ 334: 335: void Dsymbol::toObjFile(int multiobj) 336: { 337: //printf("Dsymbol::toObjFile('%s')\n", toChars()); 338: // ignore 339: } 340: 341: /* ================================================================== */ 342: 343: void ClassDeclaration::toObjFile(int multiobj) 344: { unsigned i; 345: unsigned offset; 346: Symbol *sinit; 347: enum_SC scclass; 348: 349: //printf("ClassDeclaration::toObjFile('%s')\n", toChars()); 350: 351: if (!members) 352: return; 353: 354: if (multiobj) 355: { obj_append(this); 356: return; 357: } 358: 359: if (global.params.symdebug) 360: toDebug(); 361: 362: assert(!scope); // semantic() should have been run to completion 363: 364: scclass = SCglobal; 365: if (inTemplateInstance()) 366: scclass = SCcomdat; 367: 368: // Put out the members 369: for (i = 0; i < members->dim; i++) 370: { 371: Dsymbol *member; 372: 373: member = members->tdata()[i]; 374: member->toObjFile(0); 375: } 376: 377: #if 0 378: // Build destructor by aggregating dtors[] 379: Symbol *sdtor; 380: switch (dtors.dim) 381: { case 0: 382: // No destructors for this class 383: sdtor = NULL; 384: break; 385: 386: case 1: 387: // One destructor, just use it directly 388: sdtor = dtors.tdata()[0]->toSymbol(); 389: break; 390: 391: default: 392: { /* Build a destructor that calls all the 393: * other destructors in dtors[]. 394: */ 395: 396: elem *edtor = NULL; 397: 398: // Declare 'this' pointer for our new destructor 399: Symbol *sthis = symbol_calloc("this"); 400: sthis->Stype = type_fake(TYnptr); 401: sthis->Stype->Tcount++; 402: sthis->Sclass = SCfastpar; 403: sthis->Spreg = AX; 404: sthis->Sfl = FLauto; 405: 406: // Call each of the destructors in dtors[] 407: // in reverse order 408: for (i = 0; i < dtors.dim; i++) 409: { DtorDeclaration *d = dtors.tdata()[i]; 410: Symbol *s = d->toSymbol(); 411: elem *e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); 412: edtor = el_combine(e, edtor); 413: } 414: 415: // Create type for the function 416: ::type *t = type_alloc(TYjfunc); 417: t->Tflags |= TFprototype | TFfixed; 418: t->Tmangle = mTYman_d; 419: t->Tnext = tsvoid; 420: tsvoid->Tcount++; 421: 422: // Create the function, sdtor, and write it out 423: localgot = NULL; 424: sdtor = toSymbolX("__dtor", SCglobal, t, "FZv"); 425: block *b = block_calloc(); 426: b->BC = BCret; 427: b->Belem = edtor; 428: sdtor->Sfunc->Fstartblock = b; 429: cstate.CSpsymtab = &sdtor->Sfunc->Flocsym; 430: symbol_add(sthis); 431: writefunc(sdtor); 432: } 433: } 434: #endif 435: 436: // Generate C symbols 437: toSymbol(); 438: toVtblSymbol(); 439: sinit = toInitializer(); 440: 441: ////////////////////////////////////////////// 442: 443: // Generate static initializer 444: sinit->Sclass = scclass; 445: sinit->Sfl = FLdata; 446: #if ELFOBJ // Burton 447: sinit->Sseg = CDATA; 448: #endif 449: #if MACHOBJ 450: sinit->Sseg = DATA; 451: #endif 452: toDt(&sinit->Sdt); 453: outdata(sinit); 454: 455: ////////////////////////////////////////////// 456: 457: // Put out the TypeInfo 458: type->getTypeInfo(NULL); 459: //type->vtinfo->toObjFile(multiobj); 460: 461: ////////////////////////////////////////////// 462: 463: // Put out the ClassInfo 464: csym->Sclass = scclass; 465: csym->Sfl = FLdata; 466: 467: /* The layout is: 468: { 469: void **vptr; 470: monitor_t monitor; 471: byte[] initializer; // static initialization data 472: char[] name; // class name 473: void *[] vtbl; 474: Interface[] interfaces; 475: ClassInfo *base; // base class 476: void *destructor; 477: void *invariant; // class invariant 478: uint flags; 479: void *deallocator; 480: OffsetTypeInfo[] offTi; 481: void *defaultConstructor; 482: const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function 483: //TypeInfo typeinfo; 484: } 485: */ 486: dt_t *dt = NULL; 487: unsigned classinfo_size = global.params.is64bit ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 488: offset = classinfo_size; 489: if (classinfo) 490: { 491: if (classinfo->structsize != classinfo_size) 492: { 493: #ifdef DEBUG 494: printf("CLASSINFO_SIZE = x%x, classinfo->structsize = x%x\n", offset, classinfo->structsize); 495: #endif 496: error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 497: fatal(); 498: } 499: } 500: 501: if (classinfo) 502: dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo 503: else 504: dtsize_t(&dt, 0); // BUG: should be an assert() 505: dtsize_t(&dt, 0); // monitor 506: 507: // initializer[] 508: assert(structsize >= 8); 509: dtsize_t(&dt, structsize); // size 510: dtxoff(&dt, sinit, 0, TYnptr); // initializer 511: 512: // name[] 513: const char *name = ident->toChars(); 514: size_t namelen = strlen(name); 515: if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) 516: { name = toPrettyChars(); 517: namelen = strlen(name); 518: } 519: dtsize_t(&dt, namelen); 520: dtabytes(&dt, TYnptr, 0, namelen + 1, name); 521: 522: // vtbl[] 523: dtsize_t(&dt, vtbl.dim); 524: dtxoff(&dt, vtblsym, 0, TYnptr); 525: 526: // interfaces[] 527: dtsize_t(&dt, vtblInterfaces->dim); 528: if (vtblInterfaces->dim) 529: dtxoff(&dt, csym, offset, TYnptr); // (*) 530: else 531: dtsize_t(&dt, 0); 532: 533: // base 534: if (baseClass) 535: dtxoff(&dt, baseClass->toSymbol(), 0, TYnptr); 536: else 537: dtsize_t(&dt, 0); 538: 539: // destructor 540: if (dtor) 541: dtxoff(&dt, dtor->toSymbol(), 0, TYnptr); 542: else 543: dtsize_t(&dt, 0); 544: 545: // invariant 546: if (inv) 547: dtxoff(&dt, inv->toSymbol(), 0, TYnptr); 548: else 549: dtsize_t(&dt, 0); 550: 551: // flags 552: int flags = 4 | isCOMclass(); 553: #if DMDV2 554: flags |= 16; 555: #endif 556: flags |= 32; 557: if (ctor) 558: flags |= 8; 559: for (ClassDeclaration *cd = this; cd; cd = cd->baseClass) 560: { 561: if (cd->members) 562: { 563: for (size_t i = 0; i < cd->members->dim; i++)
warning C6246: Local declaration of 'i' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '344' of 'c:\projects\extern\d\dmd\src\toobj.c': Lines: 344
564: { 565: Dsymbol *sm = cd->members->tdata()[i]; 566: //printf("sm = %s %s\n", sm->kind(), sm->toChars()); 567: if (sm->hasPointers()) 568: goto L2; 569: } 570: } 571: } 572: flags |= 2; // no pointers 573: L2: 574: dtsize_t(&dt, flags); 575: 576: 577: // deallocator 578: if (aggDelete) 579: dtxoff(&dt, aggDelete->toSymbol(), 0, TYnptr); 580: else 581: dtsize_t(&dt, 0); 582: 583: // offTi[] 584: dtsize_t(&dt, 0); 585: dtsize_t(&dt, 0); // null for now, fix later 586: 587: // defaultConstructor 588: if (defaultCtor) 589: dtxoff(&dt, defaultCtor->toSymbol(), 0, TYnptr); 590: else 591: dtsize_t(&dt, 0); 592: 593: #if DMDV2 594: FuncDeclaration *sgetmembers = findGetMembers(); 595: if (sgetmembers) 596: dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr); 597: else 598: dtsize_t(&dt, 0); // module getMembers() function 599: #endif 600: 601: //dtxoff(&dt, type->vtinfo->toSymbol(), 0, TYnptr); // typeinfo 602: 603: ////////////////////////////////////////////// 604: 605: // Put out vtblInterfaces->tdata()[]. Must immediately follow csym, because 606: // of the fixup (*) 607: 608: offset += vtblInterfaces->dim * (4 * PTRSIZE); 609: for (i = 0; i < vtblInterfaces->dim; i++) 610: { BaseClass *b = vtblInterfaces->tdata()[i]; 611: ClassDeclaration *id = b->base; 612: 613: /* The layout is: 614: * struct Interface 615: * { 616: * ClassInfo *interface; 617: * void *[] vtbl; 618: * ptrdiff_t offset; 619: * } 620: */ 621: 622: // Fill in vtbl[] 623: b->fillVtbl(this, &b->vtbl, 1); 624: 625: dtxoff(&dt, id->toSymbol(), 0, TYnptr); // ClassInfo 626: 627: // vtbl[] 628: dtsize_t(&dt, id->vtbl.dim); 629: dtxoff(&dt, csym, offset, TYnptr); 630: 631: dtsize_t(&dt, b->offset); // this offset 632: 633: offset += id->vtbl.dim * PTRSIZE; 634: } 635: 636: // Put out the vtblInterfaces->tdata()[].vtbl[] 637: // This must be mirrored with ClassDeclaration::baseVtblOffset() 638: //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars()); 639: for (i = 0; i < vtblInterfaces->dim; i++) 640: { BaseClass *b = vtblInterfaces->tdata()[i]; 641: ClassDeclaration *id = b->base; 642: 643: //printf(" interface[%d] is '%s'\n", i, id->toChars()); 644: int j = 0; 645: if (id->vtblOffset()) 646: { 647: // First entry is ClassInfo reference 648: //dtxoff(&dt, id->toSymbol(), 0, TYnptr); 649: 650: // First entry is struct Interface reference 651: dtxoff(&dt, csym, classinfo_size + i * (4 * PTRSIZE), TYnptr); 652: j = 1; 653: } 654: assert(id->vtbl.dim == b->vtbl.dim); 655: for (; j < id->vtbl.dim; j++)
warning C4018: '<' : signed/unsigned mismatch
656: { 657: assert(j < b->vtbl.dim);
warning C4018: '<' : signed/unsigned mismatch
658: #if 0 659: Object *o = b->vtbl.tdata()[j]; 660: if (o) 661: { 662: printf("o = %p\n", o); 663: assert(o->dyncast() == DYNCAST_DSYMBOL); 664: Dsymbol *s = (Dsymbol *)o; 665: printf("s->kind() = '%s'\n", s->kind()); 666: } 667: #endif 668: FuncDeclaration *fd = b->vtbl.tdata()[j]; 669: if (fd) 670: dtxoff(&dt, fd->toThunkSymbol(b->offset), 0, TYnptr); 671: else 672: dtsize_t(&dt, 0); 673: } 674: } 675: 676: #if 1 677: // Put out the overriding interface vtbl[]s. 678: // This must be mirrored with ClassDeclaration::baseVtblOffset() 679: //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 680: ClassDeclaration *cd; 681: FuncDeclarations bvtbl; 682: 683: for (cd = this->baseClass; cd; cd = cd->baseClass) 684: { 685: for (int k = 0; k < cd->vtblInterfaces->dim; k++)
warning C4018: '<' : signed/unsigned mismatch
686: { BaseClass *bs = cd->vtblInterfaces->tdata()[k]; 687: 688: if (bs->fillVtbl(this, &bvtbl, 0)) 689: { 690: //printf("\toverriding vtbl[] for %s\n", bs->base->toChars()); 691: ClassDeclaration *id = bs->base; 692: 693: int j = 0; 694: if (id->vtblOffset()) 695: { 696: // First entry is ClassInfo reference 697: //dtxoff(&dt, id->toSymbol(), 0, TYnptr); 698: 699: // First entry is struct Interface reference 700: dtxoff(&dt, cd->toSymbol(), classinfo_size + k * (4 * PTRSIZE), TYnptr); 701: j = 1; 702: } 703: 704: for (; j < id->vtbl.dim; j++)
warning C4018: '<' : signed/unsigned mismatch
705: { 706: FuncDeclaration *fd; 707: 708: assert(j < bvtbl.dim);
warning C4018: '<' : signed/unsigned mismatch
709: fd = bvtbl.tdata()[j]; 710: if (fd) 711: dtxoff(&dt, fd->toThunkSymbol(bs->offset), 0, TYnptr); 712: else 713: dtsize_t(&dt, 0); 714: } 715: } 716: } 717: } 718: #endif 719: #if INTERFACE_VIRTUAL 720: // Put out the overriding interface vtbl[]s. 721: // This must be mirrored with ClassDeclaration::baseVtblOffset() 722: //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 723: for (i = 0; i < vtblInterfaces->dim; i++) 724: { BaseClass *b = vtblInterfaces->tdata()[i]; 725: ClassDeclaration *cd; 726: 727: for (cd = this->baseClass; cd; cd = cd->baseClass) 728: { 729: for (int k = 0; k < cd->vtblInterfaces->dim; k++) 730: { BaseClass *bs = cd->vtblInterfaces->tdata()[k]; 731: 732: if (b->base == bs->base) 733: { 734: //printf("\toverriding vtbl[] for %s\n", b->base->toChars()); 735: ClassDeclaration *id = b->base; 736: 737: int j = 0; 738: if (id->vtblOffset()) 739: { 740: // First entry is ClassInfo reference 741: //dtxoff(&dt, id->toSymbol(), 0, TYnptr); 742: 743: // First entry is struct Interface reference 744: dtxoff(&dt, cd->toSymbol(), classinfo_size + k * (4 * PTRSIZE), TYnptr); 745: j = 1; 746: } 747: 748: for (; j < id->vtbl.dim; j++) 749: { 750: assert(j < b->vtbl.dim); 751: FuncDeclaration *fd = b->vtbl.tdata()[j]; 752: if (fd) 753: dtxoff(&dt, fd->toThunkSymbol(bs->offset), 0, TYnptr); 754: else 755: dtsize_t(&dt, 0); 756: } 757: } 758: } 759: } 760: } 761: #endif 762: 763: 764: csym->Sdt = dt; 765: #if ELFOBJ || MACHOBJ // Burton 766: // ClassInfo cannot be const data, because we use the monitor on it 767: csym->Sseg = DATA; 768: #endif 769: outdata(csym); 770: if (isExport()) 771: obj_export(csym,0); 772: 773: ////////////////////////////////////////////// 774: 775: // Put out the vtbl[] 776: //printf("putting out %s.vtbl[]\n", toChars()); 777: dt = NULL; 778: if (0) 779: i = 0; 780: else 781: { dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference 782: i = 1; 783: } 784: for (; i < vtbl.dim; i++) 785: { 786: FuncDeclaration *fd = vtbl.tdata()[i]->isFuncDeclaration(); 787: 788: //printf("\tvtbl[%d] = %p\n", i, fd); 789: if (fd && (fd->fbody || !isAbstract())) 790: { 791: // Ensure function has a return value (Bugzilla 4869) 792: if (fd->type->ty == Tfunction && !((TypeFunction *)fd->type)->next) 793: { 794: assert(fd->scope); 795: fd->semantic3(fd->scope); 796: } 797: 798: Symbol *s = fd->toSymbol(); 799: 800: #if DMDV2 801: if (isFuncHidden(fd)) 802: { /* fd is hidden from the view of this class. 803: * If fd overlaps with any function in the vtbl[], then 804: * issue 'hidden' error. 805: */ 806: for (int j = 1; j < vtbl.dim; j++)
warning C4018: '<' : signed/unsigned mismatch
807: { if (j == i) 808: continue; 809: FuncDeclaration *fd2 = vtbl.tdata()[j]->isFuncDeclaration(); 810: if (!fd2->ident->equals(fd->ident)) 811: continue; 812: if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd)) 813: { 814: if (!global.params.useDeprecated) 815: { 816: TypeFunction *tf = (TypeFunction *)fd->type; 817: if (tf->ty == Tfunction) 818: error("use of %s%s hidden by %s is deprecated\n", fd->toPrettyChars(), Parameter::argsTypesToChars(tf->parameters, tf->varargs), toChars()); 819: else 820: error("use of %s hidden by %s is deprecated\n", fd->toPrettyChars(), toChars()); 821: } 822: s = rtlsym[RTLSYM_DHIDDENFUNC]; 823: break; 824: } 825: } 826: } 827: #endif 828: dtxoff(&dt, s, 0, TYnptr); 829: } 830: else 831: dtsize_t(&dt, 0); 832: } 833: vtblsym->Sdt = dt; 834: vtblsym->Sclass = scclass; 835: vtblsym->Sfl = FLdata; 836: #if ELFOBJ 837: vtblsym->Sseg = CDATA; 838: #endif 839: #if MACHOBJ 840: vtblsym->Sseg = DATA; 841: #endif 842: outdata(vtblsym); 843: if (isExport()) 844: obj_export(vtblsym,0); 845: } 846: 847: /****************************************** 848: * Get offset of base class's vtbl[] initializer from start of csym. 849: * Returns ~0 if not this csym. 850: */ 851: 852: unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) 853: { 854: unsigned csymoffset; 855: int i; 856: 857: //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc); 858: csymoffset = global.params.is64bit ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 859: csymoffset += vtblInterfaces->dim * (4 * PTRSIZE); 860: 861: for (i = 0; i < vtblInterfaces->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
862: { 863: BaseClass *b = vtblInterfaces->tdata()[i]; 864: 865: if (b == bc) 866: return csymoffset; 867: csymoffset += b->base->vtbl.dim * PTRSIZE; 868: } 869: 870: #if 1 871: // Put out the overriding interface vtbl[]s. 872: // This must be mirrored with ClassDeclaration::baseVtblOffset() 873: //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 874: ClassDeclaration *cd; 875: FuncDeclarations bvtbl; 876: 877: for (cd = this->baseClass; cd; cd = cd->baseClass) 878: { 879: for (int k = 0; k < cd->vtblInterfaces->dim; k++)
warning C4018: '<' : signed/unsigned mismatch
880: { BaseClass *bs = cd->vtblInterfaces->tdata()[k]; 881: 882: if (bs->fillVtbl(this, NULL, 0)) 883: { 884: if (bc == bs) 885: { //printf("\tcsymoffset = x%x\n", csymoffset); 886: return csymoffset; 887: } 888: csymoffset += bs->base->vtbl.dim * PTRSIZE; 889: } 890: } 891: } 892: #endif 893: #if INTERFACE_VIRTUAL 894: for (i = 0; i < vtblInterfaces->dim; i++) 895: { BaseClass *b = vtblInterfaces->tdata()[i]; 896: ClassDeclaration *cd; 897: 898: for (cd = this->baseClass; cd; cd = cd->baseClass) 899: { 900: //printf("\tbase class %s\n", cd->toChars()); 901: for (int k = 0; k < cd->vtblInterfaces->dim; k++) 902: { BaseClass *bs = cd->vtblInterfaces->tdata()[k]; 903: 904: if (bc == bs) 905: { //printf("\tcsymoffset = x%x\n", csymoffset); 906: return csymoffset; 907: } 908: if (b->base == bs->base) 909: csymoffset += bs->base->vtbl.dim * PTRSIZE; 910: } 911: } 912: } 913: #endif 914: 915: return ~0; 916: } 917: 918: /* ================================================================== */ 919: 920: void InterfaceDeclaration::toObjFile(int multiobj) 921: { unsigned i; 922: Symbol *sinit;
warning C4101: 'sinit' : unreferenced local variable
923: enum_SC scclass; 924: 925: //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars()); 926: 927: if (!members) 928: return; 929: 930: if (global.params.symdebug) 931: toDebug(); 932: 933: scclass = SCglobal; 934: if (inTemplateInstance()) 935: scclass = SCcomdat; 936: 937: // Put out the members 938: for (i = 0; i < members->dim; i++) 939: { Dsymbol *member = members->tdata()[i]; 940: 941: member->toObjFile(0); 942: } 943: 944: // Generate C symbols 945: toSymbol(); 946: 947: ////////////////////////////////////////////// 948: 949: // Put out the TypeInfo 950: type->getTypeInfo(NULL); 951: type->vtinfo->toObjFile(multiobj); 952: 953: ////////////////////////////////////////////// 954: 955: // Put out the ClassInfo 956: csym->Sclass = scclass; 957: csym->Sfl = FLdata; 958: 959: /* The layout is: 960: { 961: void **vptr; 962: monitor_t monitor; 963: byte[] initializer; // static initialization data 964: char[] name; // class name 965: void *[] vtbl; 966: Interface[] interfaces; 967: Object *base; // base class 968: void *destructor; 969: void *invariant; // class invariant 970: uint flags; 971: void *deallocator; 972: OffsetTypeInfo[] offTi; 973: void *defaultConstructor; 974: #if DMDV2 975: const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function 976: #endif 977: //TypeInfo typeinfo; 978: } 979: */ 980: dt_t *dt = NULL; 981: 982: if (classinfo) 983: dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo 984: else 985: dtsize_t(&dt, 0); // BUG: should be an assert() 986: dtsize_t(&dt, 0); // monitor 987: 988: // initializer[] 989: dtsize_t(&dt, 0); // size 990: dtsize_t(&dt, 0); // initializer 991: 992: // name[] 993: const char *name = toPrettyChars(); 994: size_t namelen = strlen(name); 995: dtsize_t(&dt, namelen); 996: dtabytes(&dt, TYnptr, 0, namelen + 1, name); 997: 998: // vtbl[] 999: dtsize_t(&dt, 0); 1000: dtsize_t(&dt, 0); 1001: 1002: // vtblInterfaces->tdata()[] 1003: unsigned offset; 1004: dtsize_t(&dt, vtblInterfaces->dim); 1005: if (vtblInterfaces->dim) 1006: { 1007: offset = global.params.is64bit ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 1008: if (classinfo) 1009: { 1010: if (classinfo->structsize != offset) 1011: { 1012: error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 1013: fatal(); 1014: } 1015: } 1016: dtxoff(&dt, csym, offset, TYnptr); // (*) 1017: } 1018: else 1019: { offset = 0; 1020: dtsize_t(&dt, 0); 1021: } 1022: 1023: // base 1024: assert(!baseClass); 1025: dtsize_t(&dt, 0); 1026: 1027: // dtor 1028: dtsize_t(&dt, 0); 1029: 1030: // invariant 1031: dtsize_t(&dt, 0); 1032: 1033: // flags 1034: dtsize_t(&dt, 4 | isCOMinterface() | 32); 1035: 1036: // deallocator 1037: dtsize_t(&dt, 0); 1038: 1039: // offTi[] 1040: dtsize_t(&dt, 0); 1041: dtsize_t(&dt, 0); // null for now, fix later 1042: 1043: // defaultConstructor 1044: dtsize_t(&dt, 0); 1045: 1046: #if DMDV2 1047: // xgetMembers 1048: dtsize_t(&dt, 0); 1049: #endif 1050: 1051: //dtxoff(&dt, type->vtinfo->toSymbol(), 0, TYnptr); // typeinfo 1052: 1053: ////////////////////////////////////////////// 1054: 1055: // Put out vtblInterfaces->tdata()[]. Must immediately follow csym, because 1056: // of the fixup (*) 1057: 1058: offset += vtblInterfaces->dim * (4 * PTRSIZE); 1059: for (i = 0; i < vtblInterfaces->dim; i++) 1060: { BaseClass *b = vtblInterfaces->tdata()[i]; 1061: ClassDeclaration *id = b->base; 1062: 1063: // ClassInfo 1064: dtxoff(&dt, id->toSymbol(), 0, TYnptr); 1065: 1066: // vtbl[] 1067: dtsize_t(&dt, 0); 1068: dtsize_t(&dt, 0); 1069: 1070: // this offset 1071: dtsize_t(&dt, b->offset); 1072: } 1073: 1074: csym->Sdt = dt; 1075: #if ELFOBJ 1076: csym->Sseg = CDATA; 1077: #endif 1078: #if MACHOBJ 1079: csym->Sseg = DATA; 1080: #endif 1081: outdata(csym); 1082: if (isExport()) 1083: obj_export(csym,0); 1084: } 1085: 1086: /* ================================================================== */ 1087: 1088: void StructDeclaration::toObjFile(int multiobj) 1089: { 1090: //printf("StructDeclaration::toObjFile('%s')\n", toChars()); 1091: 1092: if (multiobj) 1093: { obj_append(this); 1094: return; 1095: } 1096: 1097: // Anonymous structs/unions only exist as part of others, 1098: // do not output forward referenced structs's 1099: if (!isAnonymous() && members) 1100: { 1101: if (global.params.symdebug) 1102: toDebug(); 1103: 1104: type->getTypeInfo(NULL); // generate TypeInfo 1105: 1106: if (1) 1107: { 1108: // Generate static initializer 1109: toInitializer(); 1110: #if 0 1111: sinit->Sclass = SCcomdat; 1112: #else 1113: if (inTemplateInstance()) 1114: { 1115: sinit->Sclass = SCcomdat; 1116: } 1117: else 1118: { 1119: sinit->Sclass = SCglobal; 1120: } 1121: #endif 1122: sinit->Sfl = FLdata; 1123: toDt(&sinit->Sdt); 1124: 1125: #if OMFOBJ 1126: /* For OMF, common blocks aren't pulled in from the library. 1127: */ 1128: /* ELF comdef's generate multiple 1129: * definition errors for them from the gnu linker. 1130: * Need to figure out how to generate proper comdef's for ELF. 1131: */ 1132: // See if we can convert a comdat to a comdef, 1133: // which saves on exe file space. 1134: if (0 && // causes multiple def problems with COMMON in one file and COMDAT in library 1135: sinit->Sclass == SCcomdat && 1136: sinit->Sdt && 1137: sinit->Sdt->dt == DT_azeros && 1138: sinit->Sdt->DTnext == NULL && 1139: !global.params.multiobj) 1140: { 1141: sinit->Sclass = SCglobal; 1142: sinit->Sdt->dt = DT_common; 1143: } 1144: #endif 1145: 1146: #if ELFOBJ 1147: sinit->Sseg = CDATA; 1148: #endif 1149: #if MACHOBJ 1150: sinit->Sseg = DATA; 1151: #endif 1152: outdata(sinit); 1153: } 1154: 1155: // Put out the members 1156: for (unsigned i = 0; i < members->dim; i++) 1157: { 1158: Dsymbol *member; 1159: 1160: member = members->tdata()[i]; 1161: member->toObjFile(0); 1162: } 1163: } 1164: } 1165: 1166: /* ================================================================== */ 1167: 1168: void VarDeclaration::toObjFile(int multiobj) 1169: { 1170: Symbol *s; 1171: unsigned sz; 1172: Dsymbol *parent; 1173: 1174: //printf("VarDeclaration::toObjFile(%p '%s' type=%s) protection %d\n", this, toChars(), type->toChars(), protection); 1175: //printf("\talign = %d\n", type->alignsize()); 1176: 1177: if (aliassym) 1178: { toAlias()->toObjFile(0); 1179: return; 1180: } 1181: 1182: #if DMDV2 1183: // Do not store variables we cannot take the address of 1184: if (!canTakeAddressOf()) 1185: { 1186: return; 1187: } 1188: #endif 1189: 1190: if (isDataseg() && !(storage_class & STCextern)) 1191: { 1192: s = toSymbol(); 1193: sz = type->size();
warning C4244: '=' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
1194: 1195: parent = this->toParent(); 1196: #if DMDV1 /* private statics should still get a global symbol, in case 1197: * another module inlines a function that references it. 1198: */ 1199: if (/*protection == PROTprivate ||*/ 1200: !parent || parent->ident == NULL || parent->isFuncDeclaration()) 1201: { 1202: s->Sclass = SCstatic; 1203: } 1204: else 1205: #endif 1206: { 1207: if (storage_class & STCcomdat) 1208: s->Sclass = SCcomdat; 1209: else 1210: s->Sclass = SCglobal; 1211: 1212: do 1213: { 1214: /* Global template data members need to be in comdat's 1215: * in case multiple .obj files instantiate the same 1216: * template with the same types. 1217: */ 1218: if (parent->isTemplateInstance() && !parent->isTemplateMixin()) 1219: { 1220: #if DMDV1 1221: /* These symbol constants have already been copied, 1222: * so no reason to output them. 1223: * Note that currently there is no way to take 1224: * the address of such a const. 1225: */ 1226: if (isConst() && type->toBasetype()->ty != Tsarray && 1227: init && init->isExpInitializer()) 1228: return; 1229: #endif 1230: s->Sclass = SCcomdat; 1231: break; 1232: } 1233: parent = parent->parent; 1234: } while (parent); 1235: } 1236: s->Sfl = FLdata; 1237: 1238: if (init) 1239: { s->Sdt = init->toDt(); 1240: 1241: // Look for static array that is block initialized 1242: Type *tb; 1243: ExpInitializer *ie = init->isExpInitializer(); 1244: 1245: tb = type->toBasetype(); 1246: if (tb->ty == Tsarray && ie && 1247: !tb->nextOf()->equals(ie->exp->type->toBasetype()->nextOf()) && 1248: ie->exp->implicitConvTo(tb->nextOf()) 1249: ) 1250: { 1251: size_t dim = ((TypeSArray *)tb)->dim->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'size_t', possible loss of data
1252: 1253: // Duplicate Sdt 'dim-1' times, as we already have the first one 1254: dt_t **pdt = &s->Sdt; 1255: while (--dim > 0) 1256: { 1257: pdt = ie->exp->toDt(pdt); 1258: } 1259: } 1260: } 1261: else if (storage_class & STCextern) 1262: { 1263: s->Sclass = SCextern; 1264: s->Sfl = FLextern; 1265: s->Sdt = NULL; 1266: // BUG: if isExport(), shouldn't we make it dllimport? 1267: return; 1268: } 1269: else 1270: { 1271: type->toDt(&s->Sdt); 1272: } 1273: dt_optimize(s->Sdt); 1274: 1275: // See if we can convert a comdat to a comdef, 1276: // which saves on exe file space. 1277: if (s->Sclass == SCcomdat && 1278: s->Sdt && 1279: s->Sdt->dt == DT_azeros && 1280: s->Sdt->DTnext == NULL && 1281: !isThreadlocal()) 1282: { 1283: s->Sclass = SCglobal; 1284: s->Sdt->dt = DT_common; 1285: } 1286: 1287: #if ELFOBJ || MACHOBJ // Burton 1288: if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL) 1289: s->Sseg = UDATA; 1290: else 1291: s->Sseg = DATA; 1292: #endif 1293: if (sz) 1294: { outdata(s); 1295: if (isExport()) 1296: obj_export(s,0); 1297: } 1298: } 1299: } 1300: 1301: /* ================================================================== */ 1302: 1303: void TypedefDeclaration::toObjFile(int multiobj) 1304: { 1305: //printf("TypedefDeclaration::toObjFile('%s')\n", toChars()); 1306: 1307: if (global.params.symdebug) 1308: toDebug(); 1309: 1310: type->getTypeInfo(NULL); // generate TypeInfo 1311: 1312: TypeTypedef *tc = (TypeTypedef *)type; 1313: if (type->isZeroInit() || !tc->sym->init) 1314: ; 1315: else 1316: { 1317: enum_SC scclass = SCglobal; 1318: if (inTemplateInstance()) 1319: scclass = SCcomdat; 1320: 1321: // Generate static initializer 1322: toInitializer(); 1323: sinit->Sclass = scclass; 1324: sinit->Sfl = FLdata; 1325: #if ELFOBJ // Burton 1326: sinit->Sseg = CDATA; 1327: #endif 1328: #if MACHOBJ 1329: sinit->Sseg = DATA; 1330: #endif 1331: sinit->Sdt = tc->sym->init->toDt(); 1332: outdata(sinit); 1333: } 1334: } 1335: 1336: /* ================================================================== */ 1337: 1338: void EnumDeclaration::toObjFile(int multiobj) 1339: { 1340: //printf("EnumDeclaration::toObjFile('%s')\n", toChars()); 1341: 1342: #if DMDV2 1343: if (isAnonymous()) 1344: return; 1345: #endif 1346: 1347: if (global.params.symdebug) 1348: toDebug(); 1349: 1350: type->getTypeInfo(NULL); // generate TypeInfo 1351: 1352: TypeEnum *tc = (TypeEnum *)type; 1353: if (!tc->sym->defaultval || type->isZeroInit()) 1354: ; 1355: else 1356: { 1357: enum_SC scclass = SCglobal; 1358: if (inTemplateInstance()) 1359: scclass = SCcomdat; 1360: 1361: // Generate static initializer 1362: toInitializer(); 1363: sinit->Sclass = scclass; 1364: sinit->Sfl = FLdata; 1365: #if ELFOBJ // Burton 1366: sinit->Sseg = CDATA; 1367: #endif 1368: #if MACHOBJ 1369: sinit->Sseg = DATA; 1370: #endif 1371: #if DMDV1 1372: dtnbytes(&sinit->Sdt, tc->size(0), (char *)&tc->sym->defaultval); 1373: //sinit->Sdt = tc->sym->init->toDt(); 1374: #endif 1375: #if DMDV2 1376: tc->sym->defaultval->toDt(&sinit->Sdt); 1377: #endif 1378: outdata(sinit); 1379: } 1380: } 1381: 1382: 1383: 1384: