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