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