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