1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://www.boost.org/LICENSE_1_0.txt 8 * https://github.com/D-Programming-Language/dmd/blob/master/src/class.c 9 */ 10 11 #include "root/dsystem.h" // mem{cpy|set}() 12 #include "root/root.h" 13 #include "root/rmem.h" 14 15 #include "errors.h" 16 #include "enum.h" 17 #include "init.h" 18 #include "attrib.h" 19 #include "declaration.h" 20 #include "aggregate.h" 21 #include "id.h" 22 #include "mtype.h" 23 #include "scope.h" 24 #include "module.h" 25 #include "expression.h" 26 #include "statement.h" 27 #include "template.h" 28 #include "target.h" 29 #include "objc.h" 30 31 bool symbolIsVisible(Dsymbol *origin, Dsymbol *s); 32 Objc *objc(); 33 34 35 /********************************* ClassDeclaration ****************************/ 36 37 ClassDeclaration *ClassDeclaration::object; 38 ClassDeclaration *ClassDeclaration::throwable; 39 ClassDeclaration *ClassDeclaration::exception; 40 ClassDeclaration *ClassDeclaration::errorException; 41 ClassDeclaration *ClassDeclaration::cpp_type_info_ptr; // Object.__cpp_type_info_ptr 42 43 ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject) 44 : AggregateDeclaration(loc, id ? id : Identifier::generateId("__anonclass")) 45 { 46 static const char msg[] = "only object.d can define this reserved class name"; 47 48 if (baseclasses) 49 { 50 // Actually, this is a transfer 51 this->baseclasses = baseclasses; 52 } 53 else 54 this->baseclasses = new BaseClasses(); 55 56 this->members = members; 57 58 baseClass = NULL; 59 60 interfaces.length = 0; 61 interfaces.ptr = NULL; 62 63 vtblInterfaces = NULL; 64 65 //printf("ClassDeclaration(%s), dim = %d\n", id->toChars(), this->baseclasses->dim); 66 67 // For forward references 68 type = new TypeClass(this); 69 70 staticCtor = NULL; 71 staticDtor = NULL; 72 73 vtblsym = NULL; 74 vclassinfo = NULL; 75 76 if (id) 77 { 78 // Look for special class names 79 80 if (id == Id::__sizeof || id == Id::__xalignof || id == Id::_mangleof) 81 error("illegal class name"); 82 83 // BUG: What if this is the wrong TypeInfo, i.e. it is nested? 84 if (id->toChars()[0] == 'T') 85 { 86 if (id == Id::TypeInfo) 87 { 88 if (!inObject) 89 error("%s", msg); 90 Type::dtypeinfo = this; 91 } 92 93 if (id == Id::TypeInfo_Class) 94 { 95 if (!inObject) 96 error("%s", msg); 97 Type::typeinfoclass = this; 98 } 99 100 if (id == Id::TypeInfo_Interface) 101 { 102 if (!inObject) 103 error("%s", msg); 104 Type::typeinfointerface = this; 105 } 106 107 if (id == Id::TypeInfo_Struct) 108 { 109 if (!inObject) 110 error("%s", msg); 111 Type::typeinfostruct = this; 112 } 113 114 if (id == Id::TypeInfo_Pointer) 115 { 116 if (!inObject) 117 error("%s", msg); 118 Type::typeinfopointer = this; 119 } 120 121 if (id == Id::TypeInfo_Array) 122 { 123 if (!inObject) 124 error("%s", msg); 125 Type::typeinfoarray = this; 126 } 127 128 if (id == Id::TypeInfo_StaticArray) 129 { 130 //if (!inObject) 131 // Type::typeinfostaticarray->error("%s", msg); 132 Type::typeinfostaticarray = this; 133 } 134 135 if (id == Id::TypeInfo_AssociativeArray) 136 { 137 if (!inObject) 138 error("%s", msg); 139 Type::typeinfoassociativearray = this; 140 } 141 142 if (id == Id::TypeInfo_Enum) 143 { 144 if (!inObject) 145 error("%s", msg); 146 Type::typeinfoenum = this; 147 } 148 149 if (id == Id::TypeInfo_Function) 150 { 151 if (!inObject) 152 error("%s", msg); 153 Type::typeinfofunction = this; 154 } 155 156 if (id == Id::TypeInfo_Delegate) 157 { 158 if (!inObject) 159 error("%s", msg); 160 Type::typeinfodelegate = this; 161 } 162 163 if (id == Id::TypeInfo_Tuple) 164 { 165 if (!inObject) 166 error("%s", msg); 167 Type::typeinfotypelist = this; 168 } 169 170 if (id == Id::TypeInfo_Const) 171 { 172 if (!inObject) 173 error("%s", msg); 174 Type::typeinfoconst = this; 175 } 176 177 if (id == Id::TypeInfo_Invariant) 178 { 179 if (!inObject) 180 error("%s", msg); 181 Type::typeinfoinvariant = this; 182 } 183 184 if (id == Id::TypeInfo_Shared) 185 { 186 if (!inObject) 187 error("%s", msg); 188 Type::typeinfoshared = this; 189 } 190 191 if (id == Id::TypeInfo_Wild) 192 { 193 if (!inObject) 194 error("%s", msg); 195 Type::typeinfowild = this; 196 } 197 198 if (id == Id::TypeInfo_Vector) 199 { 200 if (!inObject) 201 error("%s", msg); 202 Type::typeinfovector = this; 203 } 204 } 205 206 if (id == Id::Object) 207 { 208 if (!inObject) 209 error("%s", msg); 210 object = this; 211 } 212 213 if (id == Id::Throwable) 214 { 215 if (!inObject) 216 error("%s", msg); 217 throwable = this; 218 } 219 220 if (id == Id::Exception) 221 { 222 if (!inObject) 223 error("%s", msg); 224 exception = this; 225 } 226 227 if (id == Id::Error) 228 { 229 if (!inObject) 230 error("%s", msg); 231 errorException = this; 232 } 233 234 if (id == Id::cpp_type_info_ptr) 235 { 236 if (!inObject) 237 error("%s", msg); 238 cpp_type_info_ptr = this; 239 } 240 } 241 242 com = false; 243 isscope = false; 244 isabstract = ABSfwdref; 245 inuse = 0; 246 baseok = BASEOKnone; 247 cpp_type_info_ptr_sym = NULL; 248 } 249 250 ClassDeclaration *ClassDeclaration::create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject) 251 { 252 return new ClassDeclaration(loc, id, baseclasses, members, inObject); 253 } 254 255 Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) 256 { 257 //printf("ClassDeclaration::syntaxCopy('%s')\n", toChars()); 258 ClassDeclaration *cd = 259 s ? (ClassDeclaration *)s 260 : new ClassDeclaration(loc, ident, NULL, NULL, false); 261 262 cd->storage_class |= storage_class; 263 264 cd->baseclasses->setDim(this->baseclasses->dim); 265 for (size_t i = 0; i < cd->baseclasses->dim; i++) 266 { 267 BaseClass *b = (*this->baseclasses)[i]; 268 BaseClass *b2 = new BaseClass(b->type->syntaxCopy()); 269 (*cd->baseclasses)[i] = b2; 270 } 271 272 return ScopeDsymbol::syntaxCopy(cd); 273 } 274 275 Scope *ClassDeclaration::newScope(Scope *sc) 276 { 277 Scope *sc2 = AggregateDeclaration::newScope(sc); 278 if (isCOMclass()) 279 { 280 if (global.params.isWindows) 281 sc2->linkage = LINKwindows; 282 else 283 { 284 /* This enables us to use COM objects under Linux and 285 * work with things like XPCOM 286 */ 287 sc2->linkage = LINKc; 288 } 289 } 290 return sc2; 291 } 292 293 /* Bugzilla 12078, 12143 and 15733: 294 * While resolving base classes and interfaces, a base may refer 295 * the member of this derived class. In that time, if all bases of 296 * this class can be determined, we can go forward the semantc process 297 * beyond the Lancestorsdone. To do the recursive semantic analysis, 298 * temporarily set and unset `_scope` around exp(). 299 */ 300 static Type *resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, Type *type) 301 { 302 if (!scx) 303 { 304 scx = sc->copy(); 305 scx->setNoFree(); 306 } 307 cd->_scope = scx; 308 Type *t = type->semantic(cd->loc, sc); 309 cd->_scope = NULL; 310 return t; 311 } 312 313 static void resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, ClassDeclaration *sym) 314 { 315 if (!scx) 316 { 317 scx = sc->copy(); 318 scx->setNoFree(); 319 } 320 cd->_scope = scx; 321 sym->semantic(NULL); 322 cd->_scope = NULL; 323 } 324 325 static void badObjectDotD(ClassDeclaration *cd) 326 { 327 cd->error("missing or corrupt object.d"); 328 fatal(); 329 } 330 331 void ClassDeclaration::semantic(Scope *sc) 332 { 333 //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 334 //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); 335 //printf("sc->stc = %x\n", sc->stc); 336 337 //{ static int n; if (++n == 20) *(char*)0=0; } 338 339 if (semanticRun >= PASSsemanticdone) 340 return; 341 unsigned errors = global.errors; 342 343 //printf("+ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 344 345 Scope *scx = NULL; 346 if (_scope) 347 { 348 sc = _scope; 349 scx = _scope; // save so we don't make redundant copies 350 _scope = NULL; 351 } 352 353 if (!parent) 354 { 355 assert(sc->parent); 356 parent = sc->parent; 357 } 358 359 if (this->errors) 360 type = Type::terror; 361 type = type->semantic(loc, sc); 362 363 if (type->ty == Tclass && ((TypeClass *)type)->sym != this) 364 { 365 TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); 366 if (ti && isError(ti)) 367 ((TypeClass *)type)->sym = this; 368 } 369 370 // Ungag errors when not speculative 371 Ungag ungag = ungagSpeculative(); 372 373 if (semanticRun == PASSinit) 374 { 375 protection = sc->protection; 376 377 storage_class |= sc->stc; 378 if (storage_class & STCdeprecated) 379 isdeprecated = true; 380 if (storage_class & STCauto) 381 error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); 382 if (storage_class & STCscope) 383 isscope = true; 384 if (storage_class & STCabstract) 385 isabstract = ABSyes; 386 387 userAttribDecl = sc->userAttribDecl; 388 389 if (sc->linkage == LINKcpp) 390 classKind = ClassKind::cpp; 391 if (sc->linkage == LINKobjc) 392 objc()->setObjc(this); 393 } 394 else if (symtab && !scx) 395 { 396 return; 397 } 398 semanticRun = PASSsemantic; 399 400 if (baseok < BASEOKdone) 401 { 402 baseok = BASEOKin; 403 404 // Expand any tuples in baseclasses[] 405 for (size_t i = 0; i < baseclasses->dim; ) 406 { 407 BaseClass *b = (*baseclasses)[i]; 408 b->type = resolveBase(this, sc, scx, b->type); 409 410 Type *tb = b->type->toBasetype(); 411 if (tb->ty == Ttuple) 412 { 413 TypeTuple *tup = (TypeTuple *)tb; 414 baseclasses->remove(i); 415 size_t dim = Parameter::dim(tup->arguments); 416 for (size_t j = 0; j < dim; j++) 417 { 418 Parameter *arg = Parameter::getNth(tup->arguments, j); 419 b = new BaseClass(arg->type); 420 baseclasses->insert(i + j, b); 421 } 422 } 423 else 424 i++; 425 } 426 427 if (baseok >= BASEOKdone) 428 { 429 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun); 430 if (semanticRun >= PASSsemanticdone) 431 return; 432 goto Lancestorsdone; 433 } 434 435 // See if there's a base class as first in baseclasses[] 436 if (baseclasses->dim) 437 { 438 BaseClass *b = (*baseclasses)[0]; 439 Type *tb = b->type->toBasetype(); 440 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; 441 if (!tc) 442 { 443 if (b->type != Type::terror) 444 error("base type must be class or interface, not %s", b->type->toChars()); 445 baseclasses->remove(0); 446 goto L7; 447 } 448 449 if (tc->sym->isDeprecated()) 450 { 451 if (!isDeprecated()) 452 { 453 // Deriving from deprecated class makes this one deprecated too 454 isdeprecated = true; 455 456 tc->checkDeprecated(loc, sc); 457 } 458 } 459 460 if (tc->sym->isInterfaceDeclaration()) 461 goto L7; 462 463 for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) 464 { 465 if (cdb == this) 466 { 467 error("circular inheritance"); 468 baseclasses->remove(0); 469 goto L7; 470 } 471 } 472 473 /* Bugzilla 11034: Essentially, class inheritance hierarchy 474 * and instance size of each classes are orthogonal information. 475 * Therefore, even if tc->sym->sizeof == SIZEOKnone, 476 * we need to set baseClass field for class covariance check. 477 */ 478 baseClass = tc->sym; 479 b->sym = baseClass; 480 481 if (tc->sym->baseok < BASEOKdone) 482 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference 483 if (tc->sym->baseok < BASEOKdone) 484 { 485 //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); 486 if (tc->sym->_scope) 487 tc->sym->_scope->_module->addDeferredSemantic(tc->sym); 488 baseok = BASEOKnone; 489 } 490 L7: ; 491 } 492 493 // Treat the remaining entries in baseclasses as interfaces 494 // Check for errors, handle forward references 495 for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; ) 496 { 497 BaseClass *b = (*baseclasses)[i]; 498 Type *tb = b->type->toBasetype(); 499 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; 500 if (!tc || !tc->sym->isInterfaceDeclaration()) 501 { 502 if (b->type != Type::terror) 503 error("base type must be interface, not %s", b->type->toChars()); 504 baseclasses->remove(i); 505 continue; 506 } 507 508 // Check for duplicate interfaces 509 for (size_t j = (baseClass ? 1 : 0); j < i; j++) 510 { 511 BaseClass *b2 = (*baseclasses)[j]; 512 if (b2->sym == tc->sym) 513 { 514 error("inherits from duplicate interface %s", b2->sym->toChars()); 515 baseclasses->remove(i); 516 continue; 517 } 518 } 519 520 if (tc->sym->isDeprecated()) 521 { 522 if (!isDeprecated()) 523 { 524 // Deriving from deprecated class makes this one deprecated too 525 isdeprecated = true; 526 527 tc->checkDeprecated(loc, sc); 528 } 529 } 530 531 b->sym = tc->sym; 532 533 if (tc->sym->baseok < BASEOKdone) 534 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference 535 if (tc->sym->baseok < BASEOKdone) 536 { 537 //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars()); 538 if (tc->sym->_scope) 539 tc->sym->_scope->_module->addDeferredSemantic(tc->sym); 540 baseok = BASEOKnone; 541 } 542 i++; 543 } 544 if (baseok == BASEOKnone) 545 { 546 // Forward referencee of one or more bases, try again later 547 _scope = scx ? scx : sc->copy(); 548 _scope->setNoFree(); 549 _scope->_module->addDeferredSemantic(this); 550 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars()); 551 return; 552 } 553 baseok = BASEOKdone; 554 555 // If no base class, and this is not an Object, use Object as base class 556 if (!baseClass && ident != Id::Object && !isCPPclass()) 557 { 558 if (!object || object->errors) 559 badObjectDotD(this); 560 561 Type *t = object->type; 562 t = t->semantic(loc, sc)->toBasetype(); 563 if (t->ty == Terror) 564 badObjectDotD(this); 565 assert(t->ty == Tclass); 566 TypeClass *tc = (TypeClass *)t; 567 568 BaseClass *b = new BaseClass(tc); 569 baseclasses->shift(b); 570 571 baseClass = tc->sym; 572 assert(!baseClass->isInterfaceDeclaration()); 573 b->sym = baseClass; 574 } 575 if (baseClass) 576 { 577 if (baseClass->storage_class & STCfinal) 578 error("cannot inherit from final class %s", baseClass->toChars()); 579 580 // Inherit properties from base class 581 if (baseClass->isCOMclass()) 582 com = true; 583 if (baseClass->isCPPclass()) 584 classKind = ClassKind::cpp; 585 if (baseClass->isscope) 586 isscope = true; 587 enclosing = baseClass->enclosing; 588 storage_class |= baseClass->storage_class & STC_TYPECTOR; 589 } 590 591 interfaces.length = baseclasses->dim - (baseClass ? 1 : 0); 592 interfaces.ptr = baseclasses->tdata() + (baseClass ? 1 : 0); 593 594 for (size_t i = 0; i < interfaces.length; i++) 595 { 596 BaseClass *b = interfaces.ptr[i]; 597 // If this is an interface, and it derives from a COM interface, 598 // then this is a COM interface too. 599 if (b->sym->isCOMinterface()) 600 com = true; 601 if (isCPPclass() && !b->sym->isCPPinterface()) 602 { 603 ::error(loc, "C++ class '%s' cannot implement D interface '%s'", 604 toPrettyChars(), b->sym->toPrettyChars()); 605 } 606 } 607 608 interfaceSemantic(sc); 609 } 610 Lancestorsdone: 611 //printf("\tClassDeclaration::semantic(%s) baseok = %d\n", toChars(), baseok); 612 613 if (!members) // if opaque declaration 614 { 615 semanticRun = PASSsemanticdone; 616 return; 617 } 618 if (!symtab) 619 { 620 symtab = new DsymbolTable(); 621 622 /* Bugzilla 12152: The semantic analysis of base classes should be finished 623 * before the members semantic analysis of this class, in order to determine 624 * vtbl in this class. However if a base class refers the member of this class, 625 * it can be resolved as a normal forward reference. 626 * Call addMember() and setScope() to make this class members visible from the base classes. 627 */ 628 for (size_t i = 0; i < members->dim; i++) 629 { 630 Dsymbol *s = (*members)[i]; 631 s->addMember(sc, this); 632 } 633 634 Scope *sc2 = newScope(sc); 635 636 /* Set scope so if there are forward references, we still might be able to 637 * resolve individual members like enums. 638 */ 639 for (size_t i = 0; i < members->dim; i++) 640 { 641 Dsymbol *s = (*members)[i]; 642 //printf("[%d] setScope %s %s, sc2 = %p\n", i, s->kind(), s->toChars(), sc2); 643 s->setScope(sc2); 644 } 645 646 sc2->pop(); 647 } 648 649 for (size_t i = 0; i < baseclasses->dim; i++) 650 { 651 BaseClass *b = (*baseclasses)[i]; 652 Type *tb = b->type->toBasetype(); 653 assert(tb->ty == Tclass); 654 TypeClass *tc = (TypeClass *)tb; 655 656 if (tc->sym->semanticRun < PASSsemanticdone) 657 { 658 // Forward referencee of one or more bases, try again later 659 _scope = scx ? scx : sc->copy(); 660 _scope->setNoFree(); 661 if (tc->sym->_scope) 662 tc->sym->_scope->_module->addDeferredSemantic(tc->sym); 663 _scope->_module->addDeferredSemantic(this); 664 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars()); 665 return; 666 } 667 } 668 669 if (baseok == BASEOKdone) 670 { 671 baseok = BASEOKsemanticdone; 672 673 // initialize vtbl 674 if (baseClass) 675 { 676 if (isCPPclass() && baseClass->vtbl.dim == 0) 677 { 678 error("C++ base class %s needs at least one virtual function", baseClass->toChars()); 679 } 680 681 // Copy vtbl[] from base class 682 vtbl.setDim(baseClass->vtbl.dim); 683 memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim); 684 685 vthis = baseClass->vthis; 686 } 687 else 688 { 689 // No base class, so this is the root of the class hierarchy 690 vtbl.setDim(0); 691 if (vtblOffset()) 692 vtbl.push(this); // leave room for classinfo as first member 693 } 694 695 /* If this is a nested class, add the hidden 'this' 696 * member which is a pointer to the enclosing scope. 697 */ 698 if (vthis) // if inheriting from nested class 699 { 700 // Use the base class's 'this' member 701 if (storage_class & STCstatic) 702 error("static class cannot inherit from nested class %s", baseClass->toChars()); 703 if (toParent2() != baseClass->toParent2() && 704 (!toParent2() || 705 !baseClass->toParent2()->getType() || 706 !baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL))) 707 { 708 if (toParent2()) 709 { 710 error("is nested within %s, but super class %s is nested within %s", 711 toParent2()->toChars(), 712 baseClass->toChars(), 713 baseClass->toParent2()->toChars()); 714 } 715 else 716 { 717 error("is not nested, but super class %s is nested within %s", 718 baseClass->toChars(), 719 baseClass->toParent2()->toChars()); 720 } 721 enclosing = NULL; 722 } 723 } 724 else 725 makeNested(); 726 } 727 728 Scope *sc2 = newScope(sc); 729 730 for (size_t i = 0; i < members->dim; i++) 731 { 732 Dsymbol *s = (*members)[i]; 733 s->importAll(sc2); 734 } 735 736 // Note that members.dim can grow due to tuple expansion during semantic() 737 for (size_t i = 0; i < members->dim; i++) 738 { 739 Dsymbol *s = (*members)[i]; 740 s->semantic(sc2); 741 } 742 743 if (!determineFields()) 744 { 745 assert(type == Type::terror); 746 sc2->pop(); 747 return; 748 } 749 750 /* Following special member functions creation needs semantic analysis 751 * completion of sub-structs in each field types. 752 */ 753 for (size_t i = 0; i < fields.dim; i++) 754 { 755 VarDeclaration *v = fields[i]; 756 Type *tb = v->type->baseElemOf(); 757 if (tb->ty != Tstruct) 758 continue; 759 StructDeclaration *sd = ((TypeStruct *)tb)->sym; 760 if (sd->semanticRun >= PASSsemanticdone) 761 continue; 762 763 sc2->pop(); 764 765 _scope = scx ? scx : sc->copy(); 766 _scope->setNoFree(); 767 _scope->_module->addDeferredSemantic(this); 768 //printf("\tdeferring %s\n", toChars()); 769 return; 770 } 771 772 /* Look for special member functions. 773 * They must be in this class, not in a base class. 774 */ 775 776 // Can be in base class 777 aggNew = (NewDeclaration *)search(Loc(), Id::classNew); 778 aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete); 779 780 // Look for the constructor 781 ctor = searchCtor(); 782 783 if (!ctor && noDefaultCtor) 784 { 785 // A class object is always created by constructor, so this check is legitimate. 786 for (size_t i = 0; i < fields.dim; i++) 787 { 788 VarDeclaration *v = fields[i]; 789 if (v->storage_class & STCnodefaultctor) 790 ::error(v->loc, "field %s must be initialized in constructor", v->toChars()); 791 } 792 } 793 794 // If this class has no constructor, but base class has a default 795 // ctor, create a constructor: 796 // this() { } 797 if (!ctor && baseClass && baseClass->ctor) 798 { 799 FuncDeclaration *fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type, NULL, 1); 800 if (!fd) // try shared base ctor instead 801 fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type->sharedOf(), NULL, 1); 802 if (fd && !fd->errors) 803 { 804 //printf("Creating default this(){} for class %s\n", toChars()); 805 TypeFunction *btf = fd->type->toTypeFunction(); 806 TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class); 807 tf->mod = btf->mod; 808 tf->purity = btf->purity; 809 tf->isnothrow = btf->isnothrow; 810 tf->isnogc = btf->isnogc; 811 tf->trust = btf->trust; 812 813 CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf); 814 ctor->fbody = new CompoundStatement(Loc(), new Statements()); 815 816 members->push(ctor); 817 ctor->addMember(sc, this); 818 ctor->semantic(sc2); 819 820 this->ctor = ctor; 821 defaultCtor = ctor; 822 } 823 else 824 { 825 error("cannot implicitly generate a default ctor when base class %s is missing a default ctor", 826 baseClass->toPrettyChars()); 827 } 828 } 829 830 dtor = buildDtor(this, sc2); 831 832 if (FuncDeclaration *f = hasIdentityOpAssign(this, sc2)) 833 { 834 if (!(f->storage_class & STCdisable)) 835 error(f->loc, "identity assignment operator overload is illegal"); 836 } 837 838 inv = buildInv(this, sc2); 839 840 Module::dprogress++; 841 semanticRun = PASSsemanticdone; 842 //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); 843 //members.print(); 844 845 sc2->pop(); 846 847 if (type->ty == Tclass && ((TypeClass *)type)->sym != this) 848 { 849 // https://issues.dlang.org/show_bug.cgi?id=17492 850 ClassDeclaration *cd = ((TypeClass *)type)->sym; 851 error("already exists at %s. Perhaps in another function with the same name?", cd->loc.toChars()); 852 } 853 854 if (global.errors != errors) 855 { 856 // The type is no good. 857 type = Type::terror; 858 this->errors = true; 859 if (deferred) 860 deferred->errors = true; 861 } 862 863 // Verify fields of a synchronized class are not public 864 if (storage_class & STCsynchronized) 865 { 866 for (size_t i = 0; i < fields.dim; i++) 867 { 868 VarDeclaration *vd = fields[i]; 869 if (!vd->isThisDeclaration() && 870 !vd->prot().isMoreRestrictiveThan(Prot(PROTpublic))) 871 { 872 vd->error("Field members of a synchronized class cannot be %s", 873 protectionToChars(vd->prot().kind)); 874 } 875 } 876 } 877 878 if (deferred && !global.gag) 879 { 880 deferred->semantic2(sc); 881 deferred->semantic3(sc); 882 } 883 //printf("-ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); 884 } 885 886 /********************************************* 887 * Determine if 'this' is a base class of cd. 888 * This is used to detect circular inheritance only. 889 */ 890 891 bool ClassDeclaration::isBaseOf2(ClassDeclaration *cd) 892 { 893 if (!cd) 894 return false; 895 //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 896 for (size_t i = 0; i < cd->baseclasses->dim; i++) 897 { 898 BaseClass *b = (*cd->baseclasses)[i]; 899 if (b->sym == this || isBaseOf2(b->sym)) 900 return true; 901 } 902 return false; 903 } 904 905 /******************************************* 906 * Determine if 'this' is a base class of cd. 907 */ 908 909 bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) 910 { 911 //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 912 if (poffset) 913 *poffset = 0; 914 while (cd) 915 { 916 /* cd->baseClass might not be set if cd is forward referenced. 917 */ 918 if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration()) 919 { 920 cd->semantic(NULL); 921 if (!cd->baseClass && cd->semanticRun < PASSsemanticdone) 922 cd->error("base class is forward referenced by %s", toChars()); 923 } 924 925 if (this == cd->baseClass) 926 return true; 927 928 cd = cd->baseClass; 929 } 930 return false; 931 } 932 933 /********************************************* 934 * Determine if 'this' has complete base class information. 935 * This is used to detect forward references in covariant overloads. 936 */ 937 938 bool ClassDeclaration::isBaseInfoComplete() 939 { 940 return baseok >= BASEOKdone; 941 } 942 943 Dsymbol *ClassDeclaration::search(const Loc &loc, Identifier *ident, int flags) 944 { 945 //printf("%s.ClassDeclaration::search('%s', flags=x%x)\n", toChars(), ident->toChars(), flags); 946 947 //if (_scope) printf("%s baseok = %d\n", toChars(), baseok); 948 if (_scope && baseok < BASEOKdone) 949 { 950 if (!inuse) 951 { 952 // must semantic on base class/interfaces 953 ++inuse; 954 semantic(NULL); 955 --inuse; 956 } 957 } 958 959 if (!members || !symtab) // opaque or addMember is not yet done 960 { 961 error("is forward referenced when looking for '%s'", ident->toChars()); 962 //*(char*)0=0; 963 return NULL; 964 } 965 966 Dsymbol *s = ScopeDsymbol::search(loc, ident, flags); 967 968 // don't search imports of base classes 969 if (flags & SearchImportsOnly) 970 return s; 971 972 if (!s) 973 { 974 // Search bases classes in depth-first, left to right order 975 976 for (size_t i = 0; i < baseclasses->dim; i++) 977 { 978 BaseClass *b = (*baseclasses)[i]; 979 980 if (b->sym) 981 { 982 if (!b->sym->symtab) 983 error("base %s is forward referenced", b->sym->ident->toChars()); 984 else 985 { 986 s = b->sym->search(loc, ident, flags); 987 if (!s) 988 continue; 989 else if (s == this) // happens if s is nested in this and derives from this 990 s = NULL; 991 else if (!(flags & IgnoreSymbolVisibility) && !(s->prot().kind == PROTprotected) && !symbolIsVisible(this, s)) 992 s = NULL; 993 else 994 break; 995 } 996 } 997 } 998 } 999 return s; 1000 } 1001 1002 /************************************ 1003 * Search base classes in depth-first, left-to-right order for 1004 * a class or interface named 'ident'. 1005 * Stops at first found. Does not look for additional matches. 1006 * Params: 1007 * ident = identifier to search for 1008 * Returns: 1009 * ClassDeclaration if found, null if not 1010 */ 1011 ClassDeclaration *ClassDeclaration::searchBase(Identifier *ident) 1012 { 1013 for (size_t i = 0; i < baseclasses->dim; i++) 1014 { 1015 BaseClass *b = (*baseclasses)[i]; 1016 ClassDeclaration *cdb = b->type->isClassHandle(); 1017 if (!cdb) // Bugzilla 10616 1018 return NULL; 1019 if (cdb->ident->equals(ident)) 1020 return cdb; 1021 cdb = cdb->searchBase(ident); 1022 if (cdb) 1023 return cdb; 1024 } 1025 return NULL; 1026 } 1027 1028 /**** 1029 * Runs through the inheritance graph to set the BaseClass.offset fields. 1030 * Recursive in order to account for the size of the interface classes, if they are 1031 * more than just interfaces. 1032 * Params: 1033 * cd = interface to look at 1034 * baseOffset = offset of where cd will be placed 1035 * Returns: 1036 * subset of instantiated size used by cd for interfaces 1037 */ 1038 static unsigned membersPlace(BaseClasses *vtblInterfaces, size_t &bi, ClassDeclaration *cd, unsigned baseOffset) 1039 { 1040 //printf(" membersPlace(%s, %d)\n", cd->toChars(), baseOffset); 1041 unsigned offset = baseOffset; 1042 1043 for (size_t i = 0; i < cd->interfaces.length; i++) 1044 { 1045 BaseClass *b = cd->interfaces.ptr[i]; 1046 if (b->sym->sizeok != SIZEOKdone) 1047 b->sym->finalizeSize(); 1048 assert(b->sym->sizeok == SIZEOKdone); 1049 1050 if (!b->sym->alignsize) 1051 b->sym->alignsize = Target::ptrsize; 1052 cd->alignmember(b->sym->alignsize, b->sym->alignsize, &offset); 1053 assert(bi < vtblInterfaces->dim); 1054 BaseClass *bv = (*vtblInterfaces)[bi]; 1055 if (b->sym->interfaces.length == 0) 1056 { 1057 //printf("\tvtblInterfaces[%d] b=%p b->sym = %s, offset = %d\n", bi, bv, bv->sym->toChars(), offset); 1058 bv->offset = offset; 1059 ++bi; 1060 // All the base interfaces down the left side share the same offset 1061 for (BaseClass *b2 = bv; b2->baseInterfaces.length; ) 1062 { 1063 b2 = &b2->baseInterfaces.ptr[0]; 1064 b2->offset = offset; 1065 //printf("\tvtblInterfaces[%d] b=%p sym = %s, offset = %d\n", bi, b2, b2->sym->toChars(), b2->offset); 1066 } 1067 } 1068 membersPlace(vtblInterfaces, bi, b->sym, offset); 1069 //printf(" %s size = %d\n", b->sym->toChars(), b->sym->structsize); 1070 offset += b->sym->structsize; 1071 if (cd->alignsize < b->sym->alignsize) 1072 cd->alignsize = b->sym->alignsize; 1073 } 1074 return offset - baseOffset; 1075 } 1076 1077 void ClassDeclaration::finalizeSize() 1078 { 1079 assert(sizeok != SIZEOKdone); 1080 1081 // Set the offsets of the fields and determine the size of the class 1082 if (baseClass) 1083 { 1084 assert(baseClass->sizeok == SIZEOKdone); 1085 1086 alignsize = baseClass->alignsize; 1087 structsize = baseClass->structsize; 1088 if (isCPPclass() && global.params.isWindows) 1089 structsize = (structsize + alignsize - 1) & ~(alignsize - 1); 1090 } 1091 else if (isInterfaceDeclaration()) 1092 { 1093 if (interfaces.length == 0) 1094 { 1095 alignsize = Target::ptrsize; 1096 structsize = Target::ptrsize; // allow room for __vptr 1097 } 1098 } 1099 else 1100 { 1101 alignsize = Target::ptrsize; 1102 structsize = Target::ptrsize; // allow room for __vptr 1103 if (!isCPPclass()) 1104 structsize += Target::ptrsize; // allow room for __monitor 1105 } 1106 1107 //printf("finalizeSize() %s, sizeok = %d\n", toChars(), sizeok); 1108 size_t bi = 0; // index into vtblInterfaces[] 1109 1110 // Add vptr's for any interfaces implemented by this class 1111 structsize += membersPlace(vtblInterfaces, bi, this, structsize); 1112 1113 if (isInterfaceDeclaration()) 1114 { 1115 sizeok = SIZEOKdone; 1116 return; 1117 } 1118 1119 // FIXME: Currently setFieldOffset functions need to increase fields 1120 // to calculate each variable offsets. It can be improved later. 1121 fields.setDim(0); 1122 1123 unsigned offset = structsize; 1124 for (size_t i = 0; i < members->dim; i++) 1125 { 1126 Dsymbol *s = (*members)[i]; 1127 s->setFieldOffset(this, &offset, false); 1128 } 1129 1130 sizeok = SIZEOKdone; 1131 1132 // Calculate fields[i]->overlapped 1133 checkOverlappedFields(); 1134 } 1135 1136 /********************************************************** 1137 * fd is in the vtbl[] for this class. 1138 * Return 1 if function is hidden (not findable through search). 1139 */ 1140 1141 int isf(void *param, Dsymbol *s) 1142 { 1143 FuncDeclaration *fd = s->isFuncDeclaration(); 1144 if (!fd) 1145 return 0; 1146 //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars()); 1147 return (RootObject *)param == fd; 1148 } 1149 1150 bool ClassDeclaration::isFuncHidden(FuncDeclaration *fd) 1151 { 1152 //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toPrettyChars()); 1153 Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors); 1154 if (!s) 1155 { 1156 //printf("not found\n"); 1157 /* Because, due to a hack, if there are multiple definitions 1158 * of fd->ident, NULL is returned. 1159 */ 1160 return false; 1161 } 1162 s = s->toAlias(); 1163 OverloadSet *os = s->isOverloadSet(); 1164 if (os) 1165 { 1166 for (size_t i = 0; i < os->a.dim; i++) 1167 { 1168 Dsymbol *s2 = os->a[i]; 1169 FuncDeclaration *f2 = s2->isFuncDeclaration(); 1170 if (f2 && overloadApply(f2, (void *)fd, &isf)) 1171 return false; 1172 } 1173 return true; 1174 } 1175 else 1176 { 1177 FuncDeclaration *fdstart = s->isFuncDeclaration(); 1178 //printf("%s fdstart = %p\n", s->kind(), fdstart); 1179 if (overloadApply(fdstart, (void *)fd, &isf)) 1180 return false; 1181 1182 return !fd->parent->isTemplateMixin(); 1183 } 1184 } 1185 1186 /**************** 1187 * Find virtual function matching identifier and type. 1188 * Used to build virtual function tables for interface implementations. 1189 */ 1190 1191 FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) 1192 { 1193 //printf("ClassDeclaration::findFunc(%s, %s) %s\n", ident->toChars(), tf->toChars(), toChars()); 1194 FuncDeclaration *fdmatch = NULL; 1195 FuncDeclaration *fdambig = NULL; 1196 1197 ClassDeclaration *cd = this; 1198 Dsymbols *vtbl = &cd->vtbl; 1199 while (1) 1200 { 1201 for (size_t i = 0; i < vtbl->dim; i++) 1202 { 1203 FuncDeclaration *fd = (*vtbl)[i]->isFuncDeclaration(); 1204 if (!fd) 1205 continue; // the first entry might be a ClassInfo 1206 1207 //printf("\t[%d] = %s\n", i, fd->toChars()); 1208 if (ident == fd->ident && 1209 fd->type->covariant(tf) == 1) 1210 { 1211 //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration()); 1212 if (!fdmatch) 1213 goto Lfd; 1214 if (fd == fdmatch) 1215 goto Lfdmatch; 1216 1217 { 1218 // Function type matcing: exact > covariant 1219 MATCH m1 = tf->equals(fd ->type) ? MATCHexact : MATCHnomatch; 1220 MATCH m2 = tf->equals(fdmatch->type) ? MATCHexact : MATCHnomatch; 1221 if (m1 > m2) 1222 goto Lfd; 1223 else if (m1 < m2) 1224 goto Lfdmatch; 1225 } 1226 1227 { 1228 MATCH m1 = (tf->mod == fd ->type->mod) ? MATCHexact : MATCHnomatch; 1229 MATCH m2 = (tf->mod == fdmatch->type->mod) ? MATCHexact : MATCHnomatch; 1230 if (m1 > m2) 1231 goto Lfd; 1232 else if (m1 < m2) 1233 goto Lfdmatch; 1234 } 1235 1236 { 1237 // The way of definition: non-mixin > mixin 1238 MATCH m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch; 1239 MATCH m2 = fdmatch->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch; 1240 if (m1 > m2) 1241 goto Lfd; 1242 else if (m1 < m2) 1243 goto Lfdmatch; 1244 } 1245 1246 fdambig = fd; 1247 //printf("Lambig fdambig = %s %s [%s]\n", fdambig->toChars(), fdambig->type->toChars(), fdambig->loc.toChars()); 1248 continue; 1249 1250 Lfd: 1251 fdmatch = fd; 1252 fdambig = NULL; 1253 //printf("Lfd fdmatch = %s %s [%s]\n", fdmatch->toChars(), fdmatch->type->toChars(), fdmatch->loc.toChars()); 1254 continue; 1255 1256 Lfdmatch: 1257 continue; 1258 } 1259 //else printf("\t\t%d\n", fd->type->covariant(tf)); 1260 } 1261 if (!cd) 1262 break; 1263 vtbl = &cd->vtblFinal; 1264 cd = cd->baseClass; 1265 } 1266 1267 if (fdambig) 1268 error("ambiguous virtual function %s", fdambig->toChars()); 1269 return fdmatch; 1270 } 1271 1272 void ClassDeclaration::interfaceSemantic(Scope *) 1273 { 1274 vtblInterfaces = new BaseClasses(); 1275 vtblInterfaces->reserve(interfaces.length); 1276 1277 for (size_t i = 0; i < interfaces.length; i++) 1278 { 1279 BaseClass *b = interfaces.ptr[i]; 1280 vtblInterfaces->push(b); 1281 b->copyBaseInterfaces(vtblInterfaces); 1282 } 1283 } 1284 1285 /**************************************** 1286 */ 1287 1288 bool ClassDeclaration::isCOMclass() const 1289 { 1290 return com; 1291 } 1292 1293 bool ClassDeclaration::isCOMinterface() const 1294 { 1295 return false; 1296 } 1297 1298 bool ClassDeclaration::isCPPclass() const 1299 { 1300 return classKind == ClassKind::cpp; 1301 } 1302 1303 bool ClassDeclaration::isCPPinterface() const 1304 { 1305 return false; 1306 } 1307 1308 1309 /**************************************** 1310 */ 1311 1312 bool ClassDeclaration::isAbstract() 1313 { 1314 if (isabstract != ABSfwdref) 1315 return isabstract == ABSyes; 1316 1317 /* Bugzilla 11169: Resolve forward references to all class member functions, 1318 * and determine whether this class is abstract. 1319 */ 1320 struct SearchAbstract 1321 { 1322 static int fp(Dsymbol *s, void *) 1323 { 1324 FuncDeclaration *fd = s->isFuncDeclaration(); 1325 if (!fd) 1326 return 0; 1327 if (fd->storage_class & STCstatic) 1328 return 0; 1329 1330 if (fd->_scope) 1331 fd->semantic(NULL); 1332 1333 if (fd->isAbstract()) 1334 return 1; 1335 return 0; 1336 } 1337 }; 1338 1339 for (size_t i = 0; i < members->dim; i++) 1340 { 1341 Dsymbol *s = (*members)[i]; 1342 if (s->apply(&SearchAbstract::fp, this)) 1343 { 1344 isabstract = ABSyes; 1345 return true; 1346 } 1347 } 1348 1349 /* Iterate inherited member functions and check their abstract attribute. 1350 */ 1351 for (size_t i = 1; i < vtbl.dim; i++) 1352 { 1353 FuncDeclaration *fd = vtbl[i]->isFuncDeclaration(); 1354 //if (fd) printf("\tvtbl[%d] = [%s] %s\n", i, fd->loc.toChars(), fd->toChars()); 1355 if (!fd || fd->isAbstract()) 1356 { 1357 isabstract = ABSyes; 1358 return true; 1359 } 1360 } 1361 1362 isabstract = ABSno; 1363 return false; 1364 } 1365 1366 1367 /**************************************** 1368 * Determine if slot 0 of the vtbl[] is reserved for something else. 1369 * For class objects, yes, this is where the classinfo ptr goes. 1370 * For COM interfaces, no. 1371 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1372 * Returns: 1373 * 0 vtbl[0] is first virtual function pointer 1374 * 1 vtbl[0] is classinfo/interfaceinfo pointer 1375 */ 1376 1377 int ClassDeclaration::vtblOffset() const 1378 { 1379 return classKind == ClassKind::cpp ? 0 : 1; 1380 } 1381 1382 /**************************************** 1383 */ 1384 1385 const char *ClassDeclaration::kind() const 1386 { 1387 return "class"; 1388 } 1389 1390 /**************************************** 1391 */ 1392 1393 void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses) 1394 { 1395 aclasses->push(this); 1396 } 1397 1398 /********************************* InterfaceDeclaration ****************************/ 1399 1400 InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses) 1401 : ClassDeclaration(loc, id, baseclasses, NULL, false) 1402 { 1403 if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces 1404 { 1405 com = true; 1406 classKind = ClassKind::cpp; // IUnknown is also a C++ interface 1407 } 1408 } 1409 1410 Dsymbol *InterfaceDeclaration::syntaxCopy(Dsymbol *s) 1411 { 1412 InterfaceDeclaration *id = 1413 s ? (InterfaceDeclaration *)s 1414 : new InterfaceDeclaration(loc, ident, NULL); 1415 return ClassDeclaration::syntaxCopy(id); 1416 } 1417 1418 Scope *InterfaceDeclaration::newScope(Scope *sc) 1419 { 1420 Scope *sc2 = ClassDeclaration::newScope(sc); 1421 if (com) 1422 sc2->linkage = LINKwindows; 1423 else if (classKind == ClassKind::cpp) 1424 sc2->linkage = LINKcpp; 1425 else if (classKind == ClassKind::objc) 1426 sc2->linkage = LINKobjc; 1427 return sc2; 1428 } 1429 1430 void InterfaceDeclaration::semantic(Scope *sc) 1431 { 1432 //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1433 if (semanticRun >= PASSsemanticdone) 1434 return; 1435 unsigned errors = global.errors; 1436 1437 //printf("+InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type); 1438 1439 Scope *scx = NULL; 1440 if (_scope) 1441 { 1442 sc = _scope; 1443 scx = _scope; // save so we don't make redundant copies 1444 _scope = NULL; 1445 } 1446 1447 if (!parent) 1448 { 1449 assert(sc->parent && sc->func); 1450 parent = sc->parent; 1451 } 1452 assert(parent && !isAnonymous()); 1453 1454 if (this->errors) 1455 type = Type::terror; 1456 type = type->semantic(loc, sc); 1457 1458 if (type->ty == Tclass && ((TypeClass *)type)->sym != this) 1459 { 1460 TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); 1461 if (ti && isError(ti)) 1462 ((TypeClass *)type)->sym = this; 1463 } 1464 1465 // Ungag errors when not speculative 1466 Ungag ungag = ungagSpeculative(); 1467 1468 if (semanticRun == PASSinit) 1469 { 1470 protection = sc->protection; 1471 1472 storage_class |= sc->stc; 1473 if (storage_class & STCdeprecated) 1474 isdeprecated = true; 1475 1476 userAttribDecl = sc->userAttribDecl; 1477 } 1478 else if (symtab) 1479 { 1480 if (sizeok == SIZEOKdone || !scx) 1481 { 1482 semanticRun = PASSsemanticdone; 1483 return; 1484 } 1485 } 1486 semanticRun = PASSsemantic; 1487 1488 if (baseok < BASEOKdone) 1489 { 1490 baseok = BASEOKin; 1491 1492 // Expand any tuples in baseclasses[] 1493 for (size_t i = 0; i < baseclasses->dim; ) 1494 { 1495 BaseClass *b = (*baseclasses)[i]; 1496 b->type = resolveBase(this, sc, scx, b->type); 1497 1498 Type *tb = b->type->toBasetype(); 1499 if (tb->ty == Ttuple) 1500 { 1501 TypeTuple *tup = (TypeTuple *)tb; 1502 baseclasses->remove(i); 1503 size_t dim = Parameter::dim(tup->arguments); 1504 for (size_t j = 0; j < dim; j++) 1505 { 1506 Parameter *arg = Parameter::getNth(tup->arguments, j); 1507 b = new BaseClass(arg->type); 1508 baseclasses->insert(i + j, b); 1509 } 1510 } 1511 else 1512 i++; 1513 } 1514 1515 if (baseok >= BASEOKdone) 1516 { 1517 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun); 1518 if (semanticRun >= PASSsemanticdone) 1519 return; 1520 goto Lancestorsdone; 1521 } 1522 1523 if (!baseclasses->dim && sc->linkage == LINKcpp) 1524 classKind = ClassKind::cpp; 1525 if (sc->linkage == LINKobjc) 1526 objc()->setObjc(this); 1527 1528 // Check for errors, handle forward references 1529 for (size_t i = 0; i < baseclasses->dim; ) 1530 { 1531 BaseClass *b = (*baseclasses)[i]; 1532 Type *tb = b->type->toBasetype(); 1533 TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; 1534 if (!tc || !tc->sym->isInterfaceDeclaration()) 1535 { 1536 if (b->type != Type::terror) 1537 error("base type must be interface, not %s", b->type->toChars()); 1538 baseclasses->remove(i); 1539 continue; 1540 } 1541 1542 // Check for duplicate interfaces 1543 for (size_t j = 0; j < i; j++) 1544 { 1545 BaseClass *b2 = (*baseclasses)[j]; 1546 if (b2->sym == tc->sym) 1547 { 1548 error("inherits from duplicate interface %s", b2->sym->toChars()); 1549 baseclasses->remove(i); 1550 continue; 1551 } 1552 } 1553 1554 if (tc->sym == this || isBaseOf2(tc->sym)) 1555 { 1556 error("circular inheritance of interface"); 1557 baseclasses->remove(i); 1558 continue; 1559 } 1560 1561 if (tc->sym->isDeprecated()) 1562 { 1563 if (!isDeprecated()) 1564 { 1565 // Deriving from deprecated class makes this one deprecated too 1566 isdeprecated = true; 1567 1568 tc->checkDeprecated(loc, sc); 1569 } 1570 } 1571 1572 b->sym = tc->sym; 1573 1574 if (tc->sym->baseok < BASEOKdone) 1575 resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference 1576 if (tc->sym->baseok < BASEOKdone) 1577 { 1578 //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars()); 1579 if (tc->sym->_scope) 1580 tc->sym->_scope->_module->addDeferredSemantic(tc->sym); 1581 baseok = BASEOKnone; 1582 } 1583 i++; 1584 } 1585 if (baseok == BASEOKnone) 1586 { 1587 // Forward referencee of one or more bases, try again later 1588 _scope = scx ? scx : sc->copy(); 1589 _scope->setNoFree(); 1590 _scope->_module->addDeferredSemantic(this); 1591 return; 1592 } 1593 baseok = BASEOKdone; 1594 1595 interfaces.length = baseclasses->dim; 1596 interfaces.ptr = baseclasses->tdata(); 1597 1598 for (size_t i = 0; i < interfaces.length; i++) 1599 { 1600 BaseClass *b = interfaces.ptr[i]; 1601 // If this is an interface, and it derives from a COM interface, 1602 // then this is a COM interface too. 1603 if (b->sym->isCOMinterface()) 1604 com = true; 1605 if (b->sym->isCPPinterface()) 1606 classKind = ClassKind::cpp; 1607 } 1608 1609 interfaceSemantic(sc); 1610 } 1611 Lancestorsdone: 1612 1613 if (!members) // if opaque declaration 1614 { 1615 semanticRun = PASSsemanticdone; 1616 return; 1617 } 1618 if (!symtab) 1619 symtab = new DsymbolTable(); 1620 1621 for (size_t i = 0; i < baseclasses->dim; i++) 1622 { 1623 BaseClass *b = (*baseclasses)[i]; 1624 Type *tb = b->type->toBasetype(); 1625 assert(tb->ty == Tclass); 1626 TypeClass *tc = (TypeClass *)tb; 1627 1628 if (tc->sym->semanticRun < PASSsemanticdone) 1629 { 1630 // Forward referencee of one or more bases, try again later 1631 _scope = scx ? scx : sc->copy(); 1632 _scope->setNoFree(); 1633 if (tc->sym->_scope) 1634 tc->sym->_scope->_module->addDeferredSemantic(tc->sym); 1635 _scope->_module->addDeferredSemantic(this); 1636 return; 1637 } 1638 } 1639 1640 if (baseok == BASEOKdone) 1641 { 1642 baseok = BASEOKsemanticdone; 1643 1644 // initialize vtbl 1645 if (vtblOffset()) 1646 vtbl.push(this); // leave room at vtbl[0] for classinfo 1647 1648 // Cat together the vtbl[]'s from base interfaces 1649 for (size_t i = 0; i < interfaces.length; i++) 1650 { 1651 BaseClass *b = interfaces.ptr[i]; 1652 1653 // Skip if b has already appeared 1654 for (size_t k = 0; k < i; k++) 1655 { 1656 if (b == interfaces.ptr[k]) 1657 goto Lcontinue; 1658 } 1659 1660 // Copy vtbl[] from base class 1661 if (b->sym->vtblOffset()) 1662 { 1663 size_t d = b->sym->vtbl.dim; 1664 if (d > 1) 1665 { 1666 vtbl.reserve(d - 1); 1667 for (size_t j = 1; j < d; j++) 1668 vtbl.push(b->sym->vtbl[j]); 1669 } 1670 } 1671 else 1672 { 1673 vtbl.append(&b->sym->vtbl); 1674 } 1675 1676 Lcontinue: 1677 ; 1678 } 1679 } 1680 1681 for (size_t i = 0; i < members->dim; i++) 1682 { 1683 Dsymbol *s = (*members)[i]; 1684 s->addMember(sc, this); 1685 } 1686 1687 Scope *sc2 = newScope(sc); 1688 1689 /* Set scope so if there are forward references, we still might be able to 1690 * resolve individual members like enums. 1691 */ 1692 for (size_t i = 0; i < members->dim; i++) 1693 { 1694 Dsymbol *s = (*members)[i]; 1695 //printf("setScope %s %s\n", s->kind(), s->toChars()); 1696 s->setScope(sc2); 1697 } 1698 1699 for (size_t i = 0; i < members->dim; i++) 1700 { 1701 Dsymbol *s = (*members)[i]; 1702 s->importAll(sc2); 1703 } 1704 1705 for (size_t i = 0; i < members->dim; i++) 1706 { 1707 Dsymbol *s = (*members)[i]; 1708 s->semantic(sc2); 1709 } 1710 1711 Module::dprogress++; 1712 semanticRun = PASSsemanticdone; 1713 //printf("-InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type); 1714 //members->print(); 1715 1716 sc2->pop(); 1717 1718 if (global.errors != errors) 1719 { 1720 // The type is no good. 1721 type = Type::terror; 1722 } 1723 1724 assert(type->ty != Tclass || ((TypeClass *)type)->sym == this); 1725 } 1726 1727 /******************************************* 1728 * Determine if 'this' is a base class of cd. 1729 * (Actually, if it is an interface supported by cd) 1730 * Output: 1731 * *poffset offset to start of class 1732 * OFFSET_RUNTIME must determine offset at runtime 1733 * Returns: 1734 * false not a base 1735 * true is a base 1736 */ 1737 1738 bool InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) 1739 { 1740 //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars()); 1741 assert(!baseClass); 1742 for (size_t j = 0; j < cd->interfaces.length; j++) 1743 { 1744 BaseClass *b = cd->interfaces.ptr[j]; 1745 1746 //printf("\tX base %s\n", b->sym->toChars()); 1747 if (this == b->sym) 1748 { 1749 //printf("\tfound at offset %d\n", b->offset); 1750 if (poffset) 1751 { 1752 // don't return incorrect offsets https://issues.dlang.org/show_bug.cgi?id=16980 1753 *poffset = cd->sizeok == SIZEOKdone ? b->offset : OFFSET_FWDREF; 1754 } 1755 //printf("\tfound at offset %d\n", b->offset); 1756 return true; 1757 } 1758 if (isBaseOf(b, poffset)) 1759 return true; 1760 } 1761 1762 if (cd->baseClass && isBaseOf(cd->baseClass, poffset)) 1763 return true; 1764 1765 if (poffset) 1766 *poffset = 0; 1767 return false; 1768 } 1769 1770 bool InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset) 1771 { 1772 //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->sym->toChars()); 1773 for (size_t j = 0; j < bc->baseInterfaces.length; j++) 1774 { 1775 BaseClass *b = &bc->baseInterfaces.ptr[j]; 1776 1777 //printf("\tY base %s\n", b->sym->toChars()); 1778 if (this == b->sym) 1779 { 1780 //printf("\tfound at offset %d\n", b->offset); 1781 if (poffset) 1782 { 1783 *poffset = b->offset; 1784 } 1785 return true; 1786 } 1787 if (isBaseOf(b, poffset)) 1788 { 1789 return true; 1790 } 1791 } 1792 if (poffset) 1793 *poffset = 0; 1794 return false; 1795 } 1796 1797 /**************************************** 1798 * Determine if slot 0 of the vtbl[] is reserved for something else. 1799 * For class objects, yes, this is where the ClassInfo ptr goes. 1800 * For COM interfaces, no. 1801 * For non-COM interfaces, yes, this is where the Interface ptr goes. 1802 */ 1803 1804 int InterfaceDeclaration::vtblOffset() const 1805 { 1806 if (isCOMinterface() || isCPPinterface()) 1807 return 0; 1808 return 1; 1809 } 1810 1811 bool InterfaceDeclaration::isCOMinterface() const 1812 { 1813 return com; 1814 } 1815 1816 bool InterfaceDeclaration::isCPPinterface() const 1817 { 1818 return classKind == ClassKind::cpp; 1819 } 1820 1821 /******************************************* 1822 */ 1823 1824 const char *InterfaceDeclaration::kind() const 1825 { 1826 return "interface"; 1827 } 1828 1829 1830 /******************************** BaseClass *****************************/ 1831 1832 BaseClass::BaseClass() 1833 { 1834 this->type = NULL; 1835 this->sym = NULL; 1836 this->offset = 0; 1837 1838 this->baseInterfaces.length = 0; 1839 this->baseInterfaces.ptr = NULL; 1840 } 1841 1842 BaseClass::BaseClass(Type *type) 1843 { 1844 //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); 1845 this->type = type; 1846 this->sym = NULL; 1847 this->offset = 0; 1848 1849 this->baseInterfaces.length = 0; 1850 this->baseInterfaces.ptr = NULL; 1851 } 1852 1853 /**************************************** 1854 * Fill in vtbl[] for base class based on member functions of class cd. 1855 * Input: 1856 * vtbl if !=NULL, fill it in 1857 * newinstance !=0 means all entries must be filled in by members 1858 * of cd, not members of any base classes of cd. 1859 * Returns: 1860 * true if any entries were filled in by members of cd (not exclusively 1861 * by base classes) 1862 */ 1863 1864 bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance) 1865 { 1866 bool result = false; 1867 1868 //printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", sym->toChars(), cd->toChars()); 1869 if (vtbl) 1870 vtbl->setDim(sym->vtbl.dim); 1871 1872 // first entry is ClassInfo reference 1873 for (size_t j = sym->vtblOffset(); j < sym->vtbl.dim; j++) 1874 { 1875 FuncDeclaration *ifd = sym->vtbl[j]->isFuncDeclaration(); 1876 FuncDeclaration *fd; 1877 TypeFunction *tf; 1878 1879 //printf(" vtbl[%d] is '%s'\n", j, ifd ? ifd->toChars() : "null"); 1880 1881 assert(ifd); 1882 // Find corresponding function in this class 1883 tf = ifd->type->toTypeFunction(); 1884 fd = cd->findFunc(ifd->ident, tf); 1885 if (fd && !fd->isAbstract()) 1886 { 1887 //printf(" found\n"); 1888 // Check that calling conventions match 1889 if (fd->linkage != ifd->linkage) 1890 fd->error("linkage doesn't match interface function"); 1891 1892 // Check that it is current 1893 //printf("newinstance = %d fd->toParent() = %s ifd->toParent() = %s\n", 1894 //newinstance, fd->toParent()->toChars(), ifd->toParent()->toChars()); 1895 if (newinstance && fd->toParent() != cd && ifd->toParent() == sym) 1896 cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); 1897 1898 if (fd->toParent() == cd) 1899 result = true; 1900 } 1901 else 1902 { 1903 //printf(" not found %p\n", fd); 1904 // BUG: should mark this class as abstract? 1905 if (!cd->isAbstract()) 1906 cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); 1907 1908 fd = NULL; 1909 } 1910 if (vtbl) 1911 (*vtbl)[j] = fd; 1912 } 1913 1914 return result; 1915 } 1916 1917 void BaseClass::copyBaseInterfaces(BaseClasses *vtblInterfaces) 1918 { 1919 //printf("+copyBaseInterfaces(), %s\n", sym->toChars()); 1920 // if (baseInterfaces.length) 1921 // return; 1922 1923 baseInterfaces.length = sym->interfaces.length; 1924 baseInterfaces.ptr = (BaseClass *)mem.xcalloc(baseInterfaces.length, sizeof(BaseClass)); 1925 1926 //printf("%s.copyBaseInterfaces()\n", sym->toChars()); 1927 for (size_t i = 0; i < baseInterfaces.length; i++) 1928 { 1929 void *pb = &baseInterfaces.ptr[i]; 1930 BaseClass *b2 = sym->interfaces.ptr[i]; 1931 1932 assert(b2->vtbl.dim == 0); // should not be filled yet 1933 BaseClass *b = (BaseClass *)memcpy(pb, b2, sizeof(BaseClass)); 1934 1935 if (i) // single inheritance is i==0 1936 vtblInterfaces->push(b); // only need for M.I. 1937 b->copyBaseInterfaces(vtblInterfaces); 1938 } 1939 //printf("-copyBaseInterfaces\n"); 1940 } 1941