PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/dmd2/class.c

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