1: 
   2: // Compiler implementation of the D programming language
   3: // Copyright (c) 1999-2011 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: #include <stdlib.h>
  13: static char __file__[] = __FILE__;      /* for tassert.h                */
  14: #include        "tassert.h"
  15: 
  16: #include "root.h"
  17: #include "rmem.h"
  18: 
  19: #include "enum.h"
  20: #include "init.h"
  21: #include "attrib.h"
  22: #include "declaration.h"
  23: #include "aggregate.h"
  24: #include "id.h"
  25: #include "mtype.h"
  26: #include "scope.h"
  27: #include "module.h"
  28: #include "expression.h"
  29: #include "statement.h"
  30: 
  31: /********************************* ClassDeclaration ****************************/
  32: 
  33: ClassDeclaration *ClassDeclaration::classinfo;
  34: ClassDeclaration *ClassDeclaration::object;
  35: ClassDeclaration *ClassDeclaration::throwable;
  36: ClassDeclaration *ClassDeclaration::exception;
  37: 
  38: ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
  39:     : AggregateDeclaration(loc, id)
  40: {
  41:     static char msg[] = "only object.d can define this reserved class name";
  42: 
  43:     if (baseclasses)
  44:         // Actually, this is a transfer
  45:         this->baseclasses = baseclasses;
  46:     else
  47:         this->baseclasses = new BaseClasses();
  48:     baseClass = NULL;
  49: 
  50:     interfaces_dim = 0;
  51:     interfaces = NULL;
  52: 
  53:     vtblInterfaces = NULL;
  54: 
  55:     //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses->dim);
  56: 
  57:     // For forward references
  58:     type = new TypeClass(this);
  59:     handle = type;
  60: 
  61:     staticCtor = NULL;
  62:     staticDtor = NULL;
  63: 
  64:     vtblsym = NULL;
  65:     vclassinfo = NULL;
  66: 
  67:     if (id)
  68:     {   // Look for special class names
  69: 
  70:         if (id == Id::__sizeof || id == Id::__xalignof || id == Id::mangleof)
  71:             error("illegal class name");
  72: 
  73:         // BUG: What if this is the wrong TypeInfo, i.e. it is nested?
  74:         if (id->toChars()[0] == 'T')
  75:         {
  76:             if (id == Id::TypeInfo)
  77:             {   if (Type::typeinfo)
  78:                     Type::typeinfo->error("%s", msg);
  79:                 Type::typeinfo = this;
  80:             }
  81: 
  82:             if (id == Id::TypeInfo_Class)
  83:             {   if (Type::typeinfoclass)
  84:                     Type::typeinfoclass->error("%s", msg);
  85:                 Type::typeinfoclass = this;
  86:             }
  87: 
  88:             if (id == Id::TypeInfo_Interface)
  89:             {   if (Type::typeinfointerface)
  90:                     Type::typeinfointerface->error("%s", msg);
  91:                 Type::typeinfointerface = this;
  92:             }
  93: 
  94:             if (id == Id::TypeInfo_Struct)
  95:             {   if (Type::typeinfostruct)
  96:                     Type::typeinfostruct->error("%s", msg);
  97:                 Type::typeinfostruct = this;
  98:             }
  99: 
 100:             if (id == Id::TypeInfo_Typedef)
 101:             {   if (Type::typeinfotypedef)
 102:                     Type::typeinfotypedef->error("%s", msg);
 103:                 Type::typeinfotypedef = this;
 104:             }
 105: 
 106:             if (id == Id::TypeInfo_Pointer)
 107:             {   if (Type::typeinfopointer)
 108:                     Type::typeinfopointer->error("%s", msg);
 109:                 Type::typeinfopointer = this;
 110:             }
 111: 
 112:             if (id == Id::TypeInfo_Array)
 113:             {   if (Type::typeinfoarray)
 114:                     Type::typeinfoarray->error("%s", msg);
 115:                 Type::typeinfoarray = this;
 116:             }
 117: 
 118:             if (id == Id::TypeInfo_StaticArray)
 119:             {   //if (Type::typeinfostaticarray)
 120:                     //Type::typeinfostaticarray->error("%s", msg);
 121:                 Type::typeinfostaticarray = this;
 122:             }
 123: 
 124:             if (id == Id::TypeInfo_AssociativeArray)
 125:             {   if (Type::typeinfoassociativearray)
 126:                     Type::typeinfoassociativearray->error("%s", msg);
 127:                 Type::typeinfoassociativearray = this;
 128:             }
 129: 
 130:             if (id == Id::TypeInfo_Enum)
 131:             {   if (Type::typeinfoenum)
 132:                     Type::typeinfoenum->error("%s", msg);
 133:                 Type::typeinfoenum = this;
 134:             }
 135: 
 136:             if (id == Id::TypeInfo_Function)
 137:             {   if (Type::typeinfofunction)
 138:                     Type::typeinfofunction->error("%s", msg);
 139:                 Type::typeinfofunction = this;
 140:             }
 141: 
 142:             if (id == Id::TypeInfo_Delegate)
 143:             {   if (Type::typeinfodelegate)
 144:                     Type::typeinfodelegate->error("%s", msg);
 145:                 Type::typeinfodelegate = this;
 146:             }
 147: 
 148:             if (id == Id::TypeInfo_Tuple)
 149:             {   if (Type::typeinfotypelist)
 150:                     Type::typeinfotypelist->error("%s", msg);
 151:                 Type::typeinfotypelist = this;
 152:             }
 153: 
 154: #if DMDV2
 155:             if (id == Id::TypeInfo_Const)
 156:             {   if (Type::typeinfoconst)
 157:                     Type::typeinfoconst->error("%s", msg);
 158:                 Type::typeinfoconst = this;
 159:             }
 160: 
 161:             if (id == Id::TypeInfo_Invariant)
 162:             {   if (Type::typeinfoinvariant)
 163:                     Type::typeinfoinvariant->error("%s", msg);
 164:                 Type::typeinfoinvariant = this;
 165:             }
 166: 
 167:             if (id == Id::TypeInfo_Shared)
 168:             {   if (Type::typeinfoshared)
 169:                     Type::typeinfoshared->error("%s", msg);
 170:                 Type::typeinfoshared = this;
 171:             }
 172: 
 173:             if (id == Id::TypeInfo_Wild)
 174:             {   if (Type::typeinfowild)
 175:                     Type::typeinfowild->error("%s", msg);
 176:                 Type::typeinfowild = this;
 177:             }
 178: #endif
 179:         }
 180: 
 181:         if (id == Id::Object)
 182:         {   if (object)
 183:                 object->error("%s", msg);
 184:             object = this;
 185:         }
 186: 
 187:         if (id == Id::Throwable)
 188:         {   if (throwable)
 189:                 throwable->error("%s", msg);
 190:             throwable = this;
 191:         }
 192: 
 193:         if (id == Id::Exception)
 194:         {   if (exception)
 195:                 exception->error("%s", msg);
 196:             exception = this;
 197:         }
 198: 
 199:         //if (id == Id::ClassInfo)
 200:         if (id == Id::TypeInfo_Class)
 201:         {   if (classinfo)
 202:                 classinfo->error("%s", msg);
 203:             classinfo = this;
 204:         }
 205: 
 206:         if (id == Id::ModuleInfo)
 207:         {   if (Module::moduleinfo)
 208:                 Module::moduleinfo->error("%s", msg);
 209:             Module::moduleinfo = this;
 210:         }
 211:     }
 212: 
 213:     com = 0;
 214:     isscope = 0;
 215:     isabstract = 0;
 216:     inuse = 0;
 217: }
 218: 
 219: Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
 220: {
 221:     ClassDeclaration *cd;
 222: 
 223:     //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars());
 224:     if (s)
 225:         cd = (ClassDeclaration *)s;
 226:     else
 227:         cd = new ClassDeclaration(loc, ident, NULL);
warning C6211: Leaking memory 'return value' due to an exception. Consider using a local catch block to clean up memory: Lines: 221, 224, 227, 229, 231, 232, 234, 235
228: 229: cd->storage_class |= storage_class; 230: 231: cd->baseclasses->setDim(this->baseclasses->dim); 232: for (int i = 0; i < cd->baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
233: { 234: BaseClass *b = this->baseclasses->tdata()[i]; 235: BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection); 236: cd->baseclasses->tdata()[i] = b2; 237: } 238: 239: ScopeDsymbol::syntaxCopy(cd); 240: return cd; 241: } 242: 243: void ClassDeclaration::semantic(Scope *sc) 244: { int i; 245: unsigned offset;
warning C4101: 'offset' : unreferenced local variable
246: 247: //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 248: //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 249: //printf("sc->stc = %x\n", sc->stc); 250: 251: //{ static int n; if (++n == 20) *(char*)0=0; } 252: 253: if (!ident) // if anonymous class 254: { const char *id = "__anonclass"; 255: 256: ident = Identifier::generateId(id); 257: } 258: 259: if (!sc) 260: sc = scope; 261: if (!parent && sc->parent && !sc->parent->isModule()) 262: parent = sc->parent; 263: 264: type = type->semantic(loc, sc); 265: handle = type; 266: 267: if (!members) // if forward reference 268: { //printf("\tclass '%s' is forward referenced\n", toChars()); 269: return; 270: } 271: if (symtab) 272: { if (sizeok == 1 || !scope) 273: { //printf("\tsemantic for '%s' is already completed\n", toChars()); 274: return; // semantic() already completed 275: } 276: } 277: else 278: symtab = new DsymbolTable(); 279: 280: Scope *scx = NULL; 281: if (scope) 282: { sc = scope; 283: scx = scope; // save so we don't make redundant copies 284: scope = NULL; 285: } 286: unsigned dprogress_save = Module::dprogress; 287: #ifdef IN_GCC 288: methods.setDim(0); 289: #endif 290: 291: if (sc->stc & STCdeprecated) 292: { 293: isdeprecated = 1; 294: } 295: 296: if (sc->linkage == LINKcpp) 297: error("cannot create C++ classes"); 298: 299: // Expand any tuples in baseclasses[] 300: for (i = 0; i < baseclasses->dim; )
warning C4018: '<' : signed/unsigned mismatch
301: { BaseClass *b = baseclasses->tdata()[i]; 302: //printf("test1 %s %s\n", toChars(), b->type->toChars()); 303: b->type = b->type->semantic(loc, sc); 304: //printf("test2\n"); 305: Type *tb = b->type->toBasetype(); 306: 307: if (tb->ty == Ttuple) 308: { TypeTuple *tup = (TypeTuple *)tb; 309: enum PROT protection = b->protection; 310: baseclasses->remove(i); 311: size_t dim = Parameter::dim(tup->arguments); 312: for (size_t j = 0; j < dim; j++) 313: { Parameter *arg = Parameter::getNth(tup->arguments, j); 314: b = new BaseClass(arg->type, protection); 315: baseclasses->insert(i + j, b); 316: } 317: } 318: else 319: i++; 320: } 321: 322: // See if there's a base class as first in baseclasses[] 323: if (baseclasses->dim) 324: { TypeClass *tc; 325: BaseClass *b; 326: Type *tb; 327: 328: b = baseclasses->tdata()[0]; 329: //b->type = b->type->semantic(loc, sc); 330: tb = b->type->toBasetype(); 331: if (tb->ty != Tclass) 332: { error("base type must be class or interface, not %s", b->type->toChars()); 333: baseclasses->remove(0); 334: } 335: else 336: { 337: tc = (TypeClass *)(tb); 338: 339: if (tc->sym->isDeprecated()) 340: { 341: if (!isDeprecated()) 342: { 343: // Deriving from deprecated class makes this one deprecated too 344: isdeprecated = 1; 345: 346: tc->checkDeprecated(loc, sc); 347: } 348: } 349: 350: if (tc->sym->isInterfaceDeclaration()) 351: ; 352: else 353: { 354: for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 355: { 356: if (cdb == this) 357: { 358: error("circular inheritance"); 359: baseclasses->remove(0); 360: goto L7; 361: } 362: } 363: if (!tc->sym->symtab || tc->sym->sizeok == 0) 364: { // Try to resolve forward reference 365: if (/*sc->mustsemantic &&*/ tc->sym->scope) 366: tc->sym->semantic(NULL); 367: } 368: if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0) 369: { 370: //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars()); 371: //error("forward reference of base class %s", baseClass->toChars()); 372: // Forward reference of base class, try again later 373: //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 374: scope = scx ? scx : new Scope(*sc); 375: scope->setNoFree(); 376: if (tc->sym->scope) 377: tc->sym->scope->module->addDeferredSemantic(tc->sym); 378: scope->module->addDeferredSemantic(this); 379: return; 380: } 381: else 382: { baseClass = tc->sym; 383: b->base = baseClass; 384: } 385: L7: ; 386: } 387: } 388: } 389: 390: // Treat the remaining entries in baseclasses as interfaces 391: // Check for errors, handle forward references 392: for (i = (baseClass ? 1 : 0); i < baseclasses->dim; )
warning C4018: '<' : signed/unsigned mismatch
393: { TypeClass *tc; 394: BaseClass *b; 395: Type *tb; 396: 397: b = baseclasses->tdata()[i]; 398: b->type = b->type->semantic(loc, sc); 399: tb = b->type->toBasetype(); 400: if (tb->ty == Tclass) 401: tc = (TypeClass *)tb; 402: else 403: tc = NULL; 404: if (!tc || !tc->sym->isInterfaceDeclaration()) 405: { 406: error("base type must be interface, not %s", b->type->toChars()); 407: baseclasses->remove(i); 408: continue; 409: } 410: else 411: { 412: if (tc->sym->isDeprecated()) 413: { 414: if (!isDeprecated()) 415: { 416: // Deriving from deprecated class makes this one deprecated too 417: isdeprecated = 1; 418: 419: tc->checkDeprecated(loc, sc); 420: } 421: } 422: 423: // Check for duplicate interfaces 424: for (size_t j = (baseClass ? 1 : 0); j < i; j++)
warning C4018: '<' : signed/unsigned mismatch
425: { 426: BaseClass *b2 = baseclasses->tdata()[j]; 427: if (b2->base == tc->sym) 428: error("inherits from duplicate interface %s", b2->base->toChars()); 429: } 430: 431: if (!tc->sym->symtab) 432: { // Try to resolve forward reference 433: if (/*sc->mustsemantic &&*/ tc->sym->scope) 434: tc->sym->semantic(NULL); 435: } 436: 437: b->base = tc->sym; 438: if (!b->base->symtab || b->base->scope) 439: { 440: //error("forward reference of base class %s", baseClass->toChars()); 441: // Forward reference of base, try again later 442: //printf("\ttry later, forward reference of base %s\n", baseClass->toChars()); 443: scope = scx ? scx : new Scope(*sc); 444: scope->setNoFree(); 445: if (tc->sym->scope) 446: tc->sym->scope->module->addDeferredSemantic(tc->sym); 447: scope->module->addDeferredSemantic(this); 448: return; 449: } 450: } 451: i++; 452: } 453: 454: 455: // If no base class, and this is not an Object, use Object as base class 456: if (!baseClass && ident != Id::Object) 457: { 458: // BUG: what if Object is redefined in an inner scope? 459: Type *tbase = new TypeIdentifier(0, Id::Object); 460: BaseClass *b; 461: TypeClass *tc; 462: Type *bt; 463: 464: if (!object) 465: { 466: error("missing or corrupt object.d"); 467: fatal(); 468: } 469: bt = tbase->semantic(loc, sc)->toBasetype(); 470: b = new BaseClass(bt, PROTpublic); 471: baseclasses->shift(b); 472: assert(b->type->ty == Tclass); 473: tc = (TypeClass *)(b->type); 474: baseClass = tc->sym; 475: assert(!baseClass->isInterfaceDeclaration()); 476: b->base = baseClass; 477: } 478: 479: interfaces_dim = baseclasses->dim; 480: interfaces = baseclasses->tdata(); 481: 482: 483: if (baseClass) 484: { 485: if (baseClass->storage_class & STCfinal) 486: error("cannot inherit from final class %s", baseClass->toChars()); 487: 488: interfaces_dim--; 489: interfaces++; 490: 491: // Copy vtbl[] from base class 492: vtbl.setDim(baseClass->vtbl.dim); 493: memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim); 494: 495: // Inherit properties from base class 496: com = baseClass->isCOMclass(); 497: isscope = baseClass->isscope; 498: vthis = baseClass->vthis; 499: storage_class |= baseClass->storage_class & STC_TYPECTOR; 500: } 501: else 502: { 503: // No base class, so this is the root of the class hierarchy 504: vtbl.setDim(0); 505: vtbl.push(this); // leave room for classinfo as first member 506: } 507: 508: protection = sc->protection; 509: storage_class |= sc->stc; 510: 511: if (sizeok == 0) 512: { 513: interfaceSemantic(sc); 514: 515: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
516: { 517: Dsymbol *s = members->tdata()[i]; 518: s->addMember(sc, this, 1); 519: } 520: 521: /* If this is a nested class, add the hidden 'this' 522: * member which is a pointer to the enclosing scope. 523: */ 524: if (vthis) // if inheriting from nested class 525: { // Use the base class's 'this' member 526: isnested = 1; 527: if (storage_class & STCstatic) 528: error("static class cannot inherit from nested class %s", baseClass->toChars()); 529: if (toParent2() != baseClass->toParent2()) 530: { 531: if (toParent2()) 532: { 533: error("is nested within %s, but super class %s is nested within %s", 534: toParent2()->toChars(), 535: baseClass->toChars(), 536: baseClass->toParent2()->toChars()); 537: } 538: else 539: { 540: error("is not nested, but super class %s is nested within %s", 541: baseClass->toChars(), 542: baseClass->toParent2()->toChars()); 543: } 544: isnested = 0; 545: } 546: } 547: else if (!(storage_class & STCstatic)) 548: { Dsymbol *s = toParent2(); 549: if (s) 550: { 551: AggregateDeclaration *ad = s->isClassDeclaration(); 552: FuncDeclaration *fd = s->isFuncDeclaration(); 553: 554: 555: if (ad || fd) 556: { isnested = 1; 557: Type *t; 558: if (ad) 559: t = ad->handle; 560: else if (fd) 561: { AggregateDeclaration *ad = fd->isMember2();
warning C6246: Local declaration of 'ad' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '551' of 'c:\projects\extern\d\dmd\src\class.c': Lines: 551
562: if (ad) 563: t = ad->handle; 564: else 565: { 566: t = Type::tvoidptr; 567: } 568: } 569: else 570: assert(0); 571: if (t->ty == Tstruct) // ref to struct 572: t = Type::tvoidptr; 573: assert(!vthis); 574: vthis = new ThisDeclaration(loc, t); 575: members->push(vthis); 576: } 577: } 578: } 579: } 580: 581: if (storage_class & STCauto) 582: error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 583: if (storage_class & STCscope) 584: isscope = 1; 585: if (storage_class & STCabstract) 586: isabstract = 1; 587: 588: if (storage_class & STCimmutable) 589: type = type->addMod(MODimmutable); 590: if (storage_class & STCconst) 591: type = type->addMod(MODconst); 592: if (storage_class & STCshared) 593: type = type->addMod(MODshared); 594: 595: sc = sc->push(this); 596: //sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared); 597: //sc->stc |= storage_class & STC_TYPECTOR; 598: sc->stc &= STCsafe | STCtrusted | STCsystem; 599: sc->parent = this; 600: sc->inunion = 0; 601: 602: if (isCOMclass()) 603: { 604: #if _WIN32 605: sc->linkage = LINKwindows; 606: #else 607: /* This enables us to use COM objects under Linux and 608: * work with things like XPCOM 609: */ 610: sc->linkage = LINKc; 611: #endif 612: } 613: sc->protection = PROTpublic; 614: sc->explicitProtection = 0; 615: sc->structalign = 8; 616: structalign = sc->structalign; 617: if (baseClass) 618: { sc->offset = baseClass->structsize; 619: alignsize = baseClass->alignsize; 620: // if (isnested) 621: // sc->offset += PTRSIZE; // room for uplevel context pointer 622: } 623: else 624: { sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor 625: alignsize = PTRSIZE; 626: } 627: structsize = sc->offset; 628: Scope scsave = *sc; 629: int members_dim = members->dim; 630: sizeok = 0; 631: 632: /* Set scope so if there are forward references, we still might be able to 633: * resolve individual members like enums. 634: */ 635: for (i = 0; i < members_dim; i++) 636: { Dsymbol *s = members->tdata()[i]; 637: /* There are problems doing this in the general case because 638: * Scope keeps track of things like 'offset' 639: */ 640: if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident)) 641: { 642: //printf("setScope %s %s\n", s->kind(), s->toChars()); 643: s->setScope(sc); 644: } 645: } 646: 647: for (i = 0; i < members_dim; i++) 648: { Dsymbol *s = members->tdata()[i]; 649: s->semantic(sc); 650: } 651: 652: if (sizeok == 2) 653: { // semantic() failed because of forward references. 654: // Unwind what we did, and defer it for later 655: fields.setDim(0); 656: structsize = 0; 657: alignsize = 0; 658: structalign = 0; 659: 660: sc = sc->pop(); 661: 662: scope = scx ? scx : new Scope(*sc); 663: scope->setNoFree(); 664: scope->module->addDeferredSemantic(this); 665: 666: Module::dprogress = dprogress_save; 667: 668: //printf("\tsemantic('%s') failed due to forward references\n", toChars()); 669: return; 670: } 671: 672: //printf("\tsemantic('%s') successful\n", toChars()); 673: 674: structsize = sc->offset; 675: //members->print(); 676: 677: /* Look for special member functions. 678: * They must be in this class, not in a base class. 679: */ 680: ctor = (CtorDeclaration *)search(0, Id::ctor, 0); 681: if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration())) 682: ctor = NULL; 683: 684: // dtor = (DtorDeclaration *)search(Id::dtor, 0); 685: // if (dtor && dtor->toParent() != this) 686: // dtor = NULL; 687: 688: // inv = (InvariantDeclaration *)search(Id::classInvariant, 0); 689: // if (inv && inv->toParent() != this) 690: // inv = NULL; 691: 692: // Can be in base class 693: aggNew = (NewDeclaration *)search(0, Id::classNew, 0); 694: aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); 695: 696: // If this class has no constructor, but base class does, create 697: // a constructor: 698: // this() { } 699: if (!ctor && baseClass && baseClass->ctor) 700: { 701: //printf("Creating default this(){} for class %s\n", toChars()); 702: Type *tf = new TypeFunction(NULL, NULL, 0, LINKd, 0); 703: CtorDeclaration *ctor = new CtorDeclaration(loc, 0, 0, tf); 704: ctor->fbody = new CompoundStatement(0, new Statements()); 705: members->push(ctor); 706: ctor->addMember(sc, this, 1); 707: *sc = scsave; // why? What about sc->nofree? 708: sc->offset = structsize; 709: ctor->semantic(sc); 710: this->ctor = ctor; 711: defaultCtor = ctor; 712: } 713: 714: #if 0 715: if (baseClass) 716: { if (!aggDelete) 717: aggDelete = baseClass->aggDelete; 718: if (!aggNew) 719: aggNew = baseClass->aggNew; 720: } 721: #endif 722: 723: // Allocate instance of each new interface 724: for (i = 0; i < vtblInterfaces->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
725: { 726: BaseClass *b = vtblInterfaces->tdata()[i]; 727: unsigned thissize = PTRSIZE; 728: 729: alignmember(structalign, thissize, &sc->offset); 730: assert(b->offset == 0); 731: b->offset = sc->offset; 732: 733: // Take care of single inheritance offsets 734: while (b->baseInterfaces_dim) 735: { 736: b = &b->baseInterfaces[0]; 737: b->offset = sc->offset; 738: } 739: 740: sc->offset += thissize; 741: if (alignsize < thissize) 742: alignsize = thissize; 743: } 744: structsize = sc->offset; 745: sizeok = 1; 746: Module::dprogress++; 747: 748: dtor = buildDtor(sc); 749: 750: sc->pop(); 751: 752: #if 0 // Do not call until toObjfile() because of forward references 753: // Fill in base class vtbl[]s 754: for (i = 0; i < vtblInterfaces->dim; i++) 755: { 756: BaseClass *b = vtblInterfaces->tdata()[i]; 757: 758: //b->fillVtbl(this, &b->vtbl, 1); 759: } 760: #endif 761: //printf("-ClassDeclaration::semantic(%s), type = %p\n", toChars(), type); 762: 763: if (deferred) 764: { 765: deferred->semantic2(sc); 766: deferred->semantic3(sc); 767: } 768: } 769: 770: void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 771: { 772: if (!isAnonymous()) 773: { 774: buf->printf("%s ", kind()); 775: buf->writestring(toChars()); 776: if (baseclasses->dim) 777: buf->writestring(" : "); 778: } 779: for (int i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
780: { 781: BaseClass *b = baseclasses->tdata()[i]; 782: 783: if (i) 784: buf->writeByte(','); 785: //buf->writestring(b->base->ident->toChars()); 786: b->type->toCBuffer(buf, NULL, hgs); 787: } 788: if (members) 789: { 790: buf->writenl(); 791: buf->writeByte('{'); 792: buf->writenl(); 793: for (int i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
794: { 795: Dsymbol *s = members->tdata()[i]; 796: 797: buf->writestring(" "); 798: s->toCBuffer(buf, hgs); 799: } 800: buf->writestring("}"); 801: } 802: else 803: buf->writeByte(';'); 804: buf->writenl(); 805: } 806: 807: #if 0 808: void ClassDeclaration::defineRef(Dsymbol *s) 809: { 810: ClassDeclaration *cd; 811: 812: AggregateDeclaration::defineRef(s); 813: cd = s->isClassDeclaration(); 814: baseType = cd->baseType; 815: cd->baseType = NULL; 816: } 817: #endif 818: 819: /********************************************* 820: * Determine if 'this' is a base class of cd. 821: * This is used to detect circular inheritance only. 822: */ 823: 824: int ClassDeclaration::isBaseOf2(ClassDeclaration *cd) 825: { 826: if (!cd) 827: return 0; 828: //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 829: for (int i = 0; i < cd->baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
830: { BaseClass *b = cd->baseclasses->tdata()[i]; 831: 832: if (b->base == this || isBaseOf2(b->base)) 833: return 1; 834: } 835: return 0; 836: } 837: 838: /******************************************* 839: * Determine if 'this' is a base class of cd. 840: */ 841: 842: int ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) 843: { 844: //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 845: if (poffset) 846: *poffset = 0; 847: while (cd) 848: { 849: /* cd->baseClass might not be set if cd is forward referenced. 850: */ 851: if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration()) 852: { 853: cd->semantic(NULL); 854: if (!cd->baseClass) 855: cd->error("base class is forward referenced by %s", toChars()); 856: } 857: 858: if (this == cd->baseClass) 859: return 1; 860: 861: cd = cd->baseClass; 862: } 863: return 0; 864: } 865: 866: /********************************************* 867: * Determine if 'this' has complete base class information. 868: * This is used to detect forward references in covariant overloads. 869: */ 870: 871: int ClassDeclaration::isBaseInfoComplete() 872: { 873: if (!baseClass) 874: return ident == Id::Object; 875: for (int i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
876: { BaseClass *b = baseclasses->tdata()[i]; 877: if (!b->base || !b->base->isBaseInfoComplete()) 878: return 0; 879: } 880: return 1; 881: } 882: 883: Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) 884: { 885: Dsymbol *s; 886: //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars()); 887: 888: if (scope && !symtab) 889: { Scope *sc = scope; 890: sc->mustsemantic++; 891: semantic(sc); 892: sc->mustsemantic--; 893: } 894: 895: if (!members || !symtab) 896: { 897: error("is forward referenced when looking for '%s'", ident->toChars()); 898: //*(char*)0=0; 899: return NULL; 900: } 901: 902: s = ScopeDsymbol::search(loc, ident, flags); 903: if (!s) 904: { 905: // Search bases classes in depth-first, left to right order 906: 907: int i; 908: 909: for (i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
910: { 911: BaseClass *b = baseclasses->tdata()[i]; 912: 913: if (b->base) 914: { 915: if (!b->base->symtab) 916: error("base %s is forward referenced", b->base->ident->toChars()); 917: else 918: { 919: s = b->base->search(loc, ident, flags); 920: if (s == this) // happens if s is nested in this and derives from this 921: s = NULL; 922: else if (s) 923: break; 924: } 925: } 926: } 927: } 928: return s; 929: } 930: 931: /********************************************************** 932: * fd is in the vtbl[] for this class. 933: * Return 1 if function is hidden (not findable through search). 934: */ 935: 936: #if DMDV2 937: int isf(void *param, FuncDeclaration *fd) 938: { 939: //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 940: return param == fd; 941: } 942: 943: int ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 944: { 945: //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars()); 946: Dsymbol *s = search(0, fd->ident, 4|2); 947: if (!s) 948: { //printf("not found\n"); 949: /* Because, due to a hack, if there are multiple definitions 950: * of fd->ident, NULL is returned. 951: */ 952: return 0; 953: } 954: s = s->toAlias(); 955: OverloadSet *os = s->isOverloadSet(); 956: if (os) 957: { 958: for (int i = 0; i < os->a.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
959: { Dsymbol *s = os->a.tdata()[i];
warning C6246: Local declaration of 's' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '946' of 'c:\projects\extern\d\dmd\src\class.c': Lines: 946
960: FuncDeclaration *f2 = s->isFuncDeclaration(); 961: if (f2 && overloadApply(f2, &isf, fd)) 962: return 0; 963: } 964: return 1; 965: } 966: else 967: { 968: FuncDeclaration *fdstart = s->isFuncDeclaration(); 969: //printf("%s fdstart = %p\n", s->kind(), fdstart); 970: return !overloadApply(fdstart, &isf, fd); 971: } 972: } 973: #endif 974: 975: /**************** 976: * Find virtual function matching identifier and type. 977: * Used to build virtual function tables for interface implementations. 978: */ 979: 980: FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 981: { 982: //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars()); 983: 984: ClassDeclaration *cd = this; 985: Dsymbols *vtbl = &cd->vtbl; 986: while (1) 987: { 988: for (size_t i = 0; i < vtbl->dim; i++) 989: { 990: FuncDeclaration *fd = vtbl->tdata()[i]->isFuncDeclaration(); 991: if (!fd) 992: continue; // the first entry might be a ClassInfo 993: 994: //printf("\t[%d] = %s\n", i, fd->toChars()); 995: if (ident == fd->ident && 996: //tf->equals(fd->type) 997: fd->type->covariant(tf) == 1 998: ) 999: { //printf("\t\tfound\n"); 1000: return fd; 1001: } 1002: //else printf("\t\t%d\n", fd->type->covariant(tf)); 1003: } 1004: if (!cd) 1005: break; 1006: vtbl = &cd->vtblFinal; 1007: cd = cd->baseClass; 1008: } 1009: 1010: return NULL; 1011: } 1012: 1013: void ClassDeclaration::interfaceSemantic(Scope *sc) 1014: { 1015: InterfaceDeclaration *id = isInterfaceDeclaration(); 1016: 1017: vtblInterfaces = new BaseClasses(); 1018: vtblInterfaces->reserve(interfaces_dim); 1019: 1020: for (size_t i = 0; i < interfaces_dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1021: { 1022: BaseClass *b = interfaces[i]; 1023: 1024: // If this is an interface, and it derives from a COM interface, 1025: // then this is a COM interface too. 1026: if (b->base->isCOMinterface()) 1027: com = 1; 1028: 1029: if (b->base->isCPPinterface() && id) 1030: id->cpp = 1; 1031: 1032: vtblInterfaces->push(b); 1033: b->copyBaseInterfaces(vtblInterfaces); 1034: } 1035: } 1036: 1037: /**************************************** 1038: */ 1039: 1040: int ClassDeclaration::isCOMclass() 1041: { 1042: return com; 1043: } 1044: 1045: int ClassDeclaration::isCOMinterface() 1046: { 1047: return 0; 1048: } 1049: 1050: #if DMDV2 1051: int ClassDeclaration::isCPPinterface() 1052: { 1053: return 0; 1054: } 1055: #endif 1056: 1057: 1058: /**************************************** 1059: */ 1060: 1061: int ClassDeclaration::isAbstract() 1062: { 1063: if (isabstract) 1064: return TRUE; 1065: for (int i = 1; i < vtbl.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1066: { 1067: FuncDeclaration *fd = vtbl.tdata()[i]->isFuncDeclaration(); 1068: 1069: //printf("\tvtbl[%d] = %p\n", i, fd); 1070: if (!fd || fd->isAbstract()) 1071: { 1072: isabstract |= 1; 1073: return TRUE; 1074: } 1075: } 1076: return FALSE; 1077: } 1078: 1079: 1080: /**************************************** 1081: * Determine if slot 0 of the vtbl[] is reserved for something else. 1082: * For class objects, yes, this is where the classinfo ptr goes. 1083: * For COM interfaces, no. 1084: * For non-COM interfaces, yes, this is where the Interface ptr goes. 1085: */ 1086: 1087: int ClassDeclaration::vtblOffset() 1088: { 1089: return 1; 1090: } 1091: 1092: /**************************************** 1093: */ 1094: 1095: const char *ClassDeclaration::kind() 1096: { 1097: return "class"; 1098: } 1099: 1100: /**************************************** 1101: */ 1102: 1103: void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses) 1104: { 1105: aclasses->push(this); 1106: } 1107: 1108: /********************************* InterfaceDeclaration ****************************/ 1109: 1110: InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses) 1111: : ClassDeclaration(loc, id, baseclasses) 1112: { 1113: com = 0; 1114: cpp = 0; 1115: if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces 1116: { com = 1; 1117: cpp = 1; // IUnknown is also a C++ interface 1118: } 1119: } 1120: 1121: Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 1122: { 1123: InterfaceDeclaration *id; 1124: 1125: if (s) 1126: id = (InterfaceDeclaration *)s; 1127: else 1128: id = new InterfaceDeclaration(loc, ident, NULL); 1129: 1130: ClassDeclaration::syntaxCopy(id); 1131: return id; 1132: } 1133: 1134: void InterfaceDeclaration::semantic(Scope *sc) 1135: { int i; 1136: 1137: //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1138: if (inuse) 1139: return; 1140: 1141: if (!sc) 1142: sc = scope; 1143: if (!parent && sc->parent && !sc->parent->isModule()) 1144: parent = sc->parent; 1145: 1146: type = type->semantic(loc, sc); 1147: handle = type; 1148: 1149: if (!members) // if forward reference 1150: { //printf("\tinterface '%s' is forward referenced\n", toChars()); 1151: return; 1152: } 1153: if (symtab) // if already done 1154: { if (!scope) 1155: return; 1156: } 1157: else 1158: symtab = new DsymbolTable(); 1159: 1160: Scope *scx = NULL; 1161: if (scope) 1162: { sc = scope; 1163: scx = scope; // save so we don't make redundant copies 1164: scope = NULL; 1165: } 1166: 1167: if (sc->stc & STCdeprecated) 1168: { 1169: isdeprecated = 1; 1170: } 1171: 1172: // Expand any tuples in baseclasses[] 1173: for (i = 0; i < baseclasses->dim; )
warning C4018: '<' : signed/unsigned mismatch
1174: { BaseClass *b = baseclasses->tdata()[0]; 1175: b->type = b->type->semantic(loc, sc); 1176: Type *tb = b->type->toBasetype(); 1177: 1178: if (tb->ty == Ttuple) 1179: { TypeTuple *tup = (TypeTuple *)tb; 1180: enum PROT protection = b->protection; 1181: baseclasses->remove(i); 1182: size_t dim = Parameter::dim(tup->arguments); 1183: for (size_t j = 0; j < dim; j++) 1184: { Parameter *arg = Parameter::getNth(tup->arguments, j); 1185: b = new BaseClass(arg->type, protection); 1186: baseclasses->insert(i + j, b); 1187: } 1188: } 1189: else 1190: i++; 1191: } 1192: 1193: if (!baseclasses->dim && sc->linkage == LINKcpp) 1194: cpp = 1; 1195: 1196: // Check for errors, handle forward references 1197: for (i = 0; i < baseclasses->dim; )
warning C4018: '<' : signed/unsigned mismatch
1198: { TypeClass *tc; 1199: BaseClass *b; 1200: Type *tb; 1201: 1202: b = baseclasses->tdata()[i]; 1203: b->type = b->type->semantic(loc, sc); 1204: tb = b->type->toBasetype(); 1205: if (tb->ty == Tclass) 1206: tc = (TypeClass *)tb; 1207: else 1208: tc = NULL; 1209: if (!tc || !tc->sym->isInterfaceDeclaration()) 1210: { 1211: error("base type must be interface, not %s", b->type->toChars()); 1212: baseclasses->remove(i); 1213: continue; 1214: } 1215: else 1216: { 1217: // Check for duplicate interfaces 1218: for (size_t j = 0; j < i; j++)
warning C4018: '<' : signed/unsigned mismatch
1219: { 1220: BaseClass *b2 = baseclasses->tdata()[j]; 1221: if (b2->base == tc->sym) 1222: error("inherits from duplicate interface %s", b2->base->toChars()); 1223: } 1224: 1225: b->base = tc->sym; 1226: if (b->base == this || isBaseOf2(b->base)) 1227: { 1228: error("circular inheritance of interface"); 1229: baseclasses->remove(i); 1230: continue; 1231: } 1232: if (!b->base->symtab) 1233: { // Try to resolve forward reference 1234: if (sc->mustsemantic && b->base->scope) 1235: b->base->semantic(NULL); 1236: } 1237: if (!b->base->symtab || b->base->scope || b->base->inuse) 1238: { 1239: //error("forward reference of base class %s", baseClass->toChars()); 1240: // Forward reference of base, try again later 1241: //printf("\ttry later, forward reference of base %s\n", b->base->toChars()); 1242: scope = scx ? scx : new Scope(*sc); 1243: scope->setNoFree(); 1244: scope->module->addDeferredSemantic(this); 1245: return; 1246: } 1247: } 1248: #if 0 1249: // Inherit const/invariant from base class 1250: storage_class |= b->base->storage_class & STC_TYPECTOR; 1251: #endif 1252: i++; 1253: } 1254: 1255: interfaces_dim = baseclasses->dim; 1256: interfaces = baseclasses->tdata(); 1257: 1258: interfaceSemantic(sc); 1259: 1260: if (vtblOffset()) 1261: vtbl.push(this); // leave room at vtbl[0] for classinfo 1262: 1263: // Cat together the vtbl[]'s from base interfaces 1264: for (i = 0; i < interfaces_dim; i++) 1265: { BaseClass *b = interfaces[i]; 1266: 1267: // Skip if b has already appeared 1268: for (int k = 0; k < i; k++) 1269: { 1270: if (b == interfaces[k]) 1271: goto Lcontinue; 1272: } 1273: 1274: // Copy vtbl[] from base class 1275: if (b->base->vtblOffset()) 1276: { int d = b->base->vtbl.dim; 1277: if (d > 1) 1278: { 1279: vtbl.reserve(d - 1); 1280: for (int j = 1; j < d; j++) 1281: vtbl.push(b->base->vtbl.tdata()[j]); 1282: } 1283: } 1284: else 1285: { 1286: vtbl.append(&b->base->vtbl); 1287: } 1288: 1289: Lcontinue: 1290: ; 1291: } 1292: 1293: protection = sc->protection; 1294: storage_class |= sc->stc & STC_TYPECTOR; 1295: 1296: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1297: { 1298: Dsymbol *s = members->tdata()[i]; 1299: s->addMember(sc, this, 1); 1300: } 1301: 1302: sc = sc->push(this); 1303: sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 1304: STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared); 1305: sc->stc |= storage_class & STC_TYPECTOR; 1306: sc->parent = this; 1307: if (isCOMinterface()) 1308: sc->linkage = LINKwindows; 1309: else if (isCPPinterface()) 1310: sc->linkage = LINKcpp; 1311: sc->structalign = 8; 1312: structalign = sc->structalign; 1313: sc->offset = PTRSIZE * 2; 1314: inuse++; 1315: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1316: { 1317: Dsymbol *s = members->tdata()[i]; 1318: s->semantic(sc); 1319: } 1320: inuse--; 1321: //members->print(); 1322: sc->pop(); 1323: //printf("-InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1324: } 1325: 1326: 1327: /******************************************* 1328: * Determine if 'this' is a base class of cd. 1329: * (Actually, if it is an interface supported by cd) 1330: * Output: 1331: * *poffset offset to start of class 1332: * OFFSET_RUNTIME must determine offset at runtime 1333: * Returns: 1334: * 0 not a base 1335: * 1 is a base 1336: */ 1337: 1338: int InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) 1339: { 1340: unsigned j; 1341: 1342: //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars()); 1343: assert(!baseClass); 1344: for (j = 0; j < cd->interfaces_dim; j++)
warning C4018: '<' : signed/unsigned mismatch
1345: { 1346: BaseClass *b = cd->interfaces[j]; 1347: 1348: //printf("\tbase %s\n", b->base->toChars()); 1349: if (this == b->base) 1350: { 1351: //printf("\tfound at offset %d\n", b->offset); 1352: if (poffset) 1353: { *poffset = b->offset; 1354: if (j && cd->isInterfaceDeclaration()) 1355: *poffset = OFFSET_RUNTIME; 1356: } 1357: return 1; 1358: } 1359: if (isBaseOf(b, poffset)) 1360: { if (j && poffset && cd->isInterfaceDeclaration()) 1361: *poffset = OFFSET_RUNTIME; 1362: return 1; 1363: } 1364: } 1365: 1366: if (cd->baseClass && isBaseOf(cd->baseClass, poffset)) 1367: return 1; 1368: 1369: if (poffset) 1370: *poffset = 0; 1371: return 0; 1372: } 1373: 1374: 1375: int InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset) 1376: { 1377: //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->base->toChars()); 1378: for (unsigned j = 0; j < bc->baseInterfaces_dim; j++)
warning C4018: '<' : signed/unsigned mismatch
1379: { 1380: BaseClass *b = &bc->baseInterfaces[j]; 1381: 1382: if (this == b->base) 1383: { 1384: if (poffset) 1385: { *poffset = b->offset; 1386: if (j && bc->base->isInterfaceDeclaration()) 1387: *poffset = OFFSET_RUNTIME; 1388: } 1389: return 1; 1390: } 1391: if (isBaseOf(b, poffset)) 1392: { if (j && poffset && bc->base->isInterfaceDeclaration()) 1393: *poffset = OFFSET_RUNTIME; 1394: return 1; 1395: } 1396: } 1397: if (poffset) 1398: *poffset = 0; 1399: return 0; 1400: } 1401: 1402: /********************************************* 1403: * Determine if 'this' has clomplete base class information. 1404: * This is used to detect forward references in covariant overloads. 1405: */ 1406: 1407: int InterfaceDeclaration::isBaseInfoComplete() 1408: { 1409: assert(!baseClass); 1410: for (int i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1411: { BaseClass *b = baseclasses->tdata()[i]; 1412: if (!b->base || !b->base->isBaseInfoComplete ()) 1413: return 0; 1414: } 1415: return 1; 1416: } 1417: 1418: /**************************************** 1419: * Determine if slot 0 of the vtbl[] is reserved for something else. 1420: * For class objects, yes, this is where the ClassInfo ptr goes. 1421: * For COM interfaces, no. 1422: * For non-COM interfaces, yes, this is where the Interface ptr goes. 1423: */ 1424: 1425: int InterfaceDeclaration::vtblOffset() 1426: { 1427: if (isCOMinterface() || isCPPinterface()) 1428: return 0; 1429: return 1; 1430: } 1431: 1432: int InterfaceDeclaration::isCOMinterface() 1433: { 1434: return com; 1435: } 1436: 1437: #if DMDV2 1438: int InterfaceDeclaration::isCPPinterface() 1439: { 1440: return cpp; 1441: } 1442: #endif 1443: 1444: /******************************************* 1445: */ 1446: 1447: const char *InterfaceDeclaration::kind() 1448: { 1449: return "interface"; 1450: } 1451: 1452: 1453: /******************************** BaseClass *****************************/ 1454: 1455: BaseClass::BaseClass() 1456: { 1457: memset(this, 0, sizeof(BaseClass)); 1458: } 1459: 1460: BaseClass::BaseClass(Type *type, enum PROT protection) 1461: { 1462: //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 1463: this->type = type; 1464: this->protection = protection; 1465: base = NULL; 1466: offset = 0; 1467: 1468: baseInterfaces_dim = 0; 1469: baseInterfaces = NULL; 1470: } 1471: 1472: /**************************************** 1473: * Fill in vtbl[] for base class based on member functions of class cd. 1474: * Input: 1475: * vtbl if !=NULL, fill it in 1476: * newinstance !=0 means all entries must be filled in by members 1477: * of cd, not members of any base classes of cd. 1478: * Returns: 1479: * !=0 if any entries were filled in by members of cd (not exclusively 1480: * by base classes) 1481: */ 1482: 1483: int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance) 1484: { 1485: ClassDeclaration *id = base; 1486: int j; 1487: int result = 0; 1488: 1489: //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", base->toChars(), cd->toChars()); 1490: if (vtbl) 1491: vtbl->setDim(base->vtbl.dim); 1492: 1493: // first entry is ClassInfo reference 1494: for (j = base->vtblOffset(); j < base->vtbl.dim; j++)
warning C4018: '<' : signed/unsigned mismatch
1495: { 1496: FuncDeclaration *ifd = base->vtbl.tdata()[j]->isFuncDeclaration(); 1497: FuncDeclaration *fd; 1498: TypeFunction *tf; 1499: 1500: //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd->toChars() : "null"); 1501: 1502: assert(ifd); 1503: // Find corresponding function in this class 1504: tf = (ifd->type->ty == Tfunction) ? (TypeFunction *)(ifd->type) : NULL; 1505: fd = cd->findFunc(ifd->ident, tf); 1506: if (fd && !fd->isAbstract()) 1507: { 1508: //printf(" found\n"); 1509: // Check that calling conventions match 1510: if (fd->linkage != ifd->linkage) 1511: fd->error("linkage doesn't match interface function"); 1512: 1513: // Check that it is current 1514: if (newinstance && 1515: fd->toParent() != cd && 1516: ifd->toParent() == base) 1517: cd->error("interface function %s.%s is not implemented", 1518: id->toChars(), ifd->ident->toChars()); 1519: 1520: if (fd->toParent() == cd) 1521: result = 1; 1522: } 1523: else 1524: { 1525: //printf(" not found\n"); 1526: // BUG: should mark this class as abstract? 1527: if (!cd->isAbstract()) 1528: cd->error("interface function %s.%s isn't implemented", 1529: id->toChars(), ifd->ident->toChars()); 1530: fd = NULL; 1531: } 1532: if (vtbl) 1533: vtbl->tdata()[j] = fd; 1534: } 1535: 1536: return result; 1537: } 1538: 1539: void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces) 1540: { 1541: //printf("+copyBaseInterfaces(), %s\n", base->toChars()); 1542: // if (baseInterfaces_dim) 1543: // return; 1544: 1545: baseInterfaces_dim = base->interfaces_dim; 1546: baseInterfaces = (BaseClass *)mem.calloc(baseInterfaces_dim, sizeof(BaseClass)); 1547: 1548: //printf("%s.copyBaseInterfaces()\n", base->toChars()); 1549: for (int i = 0; i < baseInterfaces_dim; i++) 1550: { 1551: BaseClass *b = &baseInterfaces[i]; 1552: BaseClass *b2 = base->interfaces[i]; 1553: 1554: assert(b2->vtbl.dim == 0); // should not be filled yet 1555: memcpy(b, b2, sizeof(BaseClass)); 1556: 1557: if (i) // single inheritance is i==0 1558: vtblInterfaces->push(b); // only need for M.I. 1559: b->copyBaseInterfaces(vtblInterfaces); 1560: } 1561: //printf("-copyBaseInterfaces\n"); 1562: } 1563: