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