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