diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-02-09 15:40:06 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-02-13 12:50:45 +0100 |
commit | a3b38b7781622babb5ca68c621367770a65012fa (patch) | |
tree | 32ba65cb98047efa6ed8f86b327903ce647c008f /gcc/d/dmd/dclass.c | |
parent | 0f3a743b688f4845e1798eed9b2e2284e891da11 (diff) | |
download | gcc-a3b38b7781622babb5ca68c621367770a65012fa.zip gcc-a3b38b7781622babb5ca68c621367770a65012fa.tar.gz gcc-a3b38b7781622babb5ca68c621367770a65012fa.tar.bz2 |
d: Merge upstream dmd 7132b3537
Splits out all semantic passes for Dsymbol, Type, and TemplateParameter
nodes into Visitors in separate files, and the copyright years of all
sources have been updated.
Reviewed-on: https://github.com/dlang/dmd/pull/12190
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 7132b3537.
* Make-lang.in (D_FRONTEND_OBJS): Add d/dsymbolsem.o, d/semantic2.o,
d/semantic3.o, and d/templateparamsem.o.
* d-compiler.cc (Compiler::genCmain): Update calls to semantic
entrypoint functions.
* d-lang.cc (d_parse_file): Likewise.
* typeinfo.cc (make_frontend_typeinfo): Likewise.
Diffstat (limited to 'gcc/d/dmd/dclass.c')
-rw-r--r-- | gcc/d/dmd/dclass.c | 917 |
1 files changed, 7 insertions, 910 deletions
diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c index 7481f91..c7dbbbe 100644 --- a/gcc/d/dmd/dclass.c +++ b/gcc/d/dmd/dclass.c @@ -1,6 +1,6 @@ /* Compiler implementation of the D programming language - * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved + * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved * written by Walter Bright * http://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. @@ -290,599 +290,6 @@ Scope *ClassDeclaration::newScope(Scope *sc) return sc2; } -/* Bugzilla 12078, 12143 and 15733: - * While resolving base classes and interfaces, a base may refer - * the member of this derived class. In that time, if all bases of - * this class can be determined, we can go forward the semantc process - * beyond the Lancestorsdone. To do the recursive semantic analysis, - * temporarily set and unset `_scope` around exp(). - */ -static Type *resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, Type *type) -{ - if (!scx) - { - scx = sc->copy(); - scx->setNoFree(); - } - cd->_scope = scx; - Type *t = type->semantic(cd->loc, sc); - cd->_scope = NULL; - return t; -} - -static void resolveBase(ClassDeclaration *cd, Scope *sc, Scope *&scx, ClassDeclaration *sym) -{ - if (!scx) - { - scx = sc->copy(); - scx->setNoFree(); - } - cd->_scope = scx; - sym->semantic(NULL); - cd->_scope = NULL; -} - -static void badObjectDotD(ClassDeclaration *cd) -{ - cd->error("missing or corrupt object.d"); - fatal(); -} - -void ClassDeclaration::semantic(Scope *sc) -{ - //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); - //printf("sc->stc = %x\n", sc->stc); - - //{ static int n; if (++n == 20) *(char*)0=0; } - - if (semanticRun >= PASSsemanticdone) - return; - unsigned errors = global.errors; - - //printf("+ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - - Scope *scx = NULL; - if (_scope) - { - sc = _scope; - scx = _scope; // save so we don't make redundant copies - _scope = NULL; - } - - if (!parent) - { - assert(sc->parent); - parent = sc->parent; - } - - if (this->errors) - type = Type::terror; - type = type->semantic(loc, sc); - - if (type->ty == Tclass && ((TypeClass *)type)->sym != this) - { - TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); - if (ti && isError(ti)) - ((TypeClass *)type)->sym = this; - } - - // Ungag errors when not speculative - Ungag ungag = ungagSpeculative(); - - if (semanticRun == PASSinit) - { - protection = sc->protection; - - storage_class |= sc->stc; - if (storage_class & STCdeprecated) - isdeprecated = true; - if (storage_class & STCauto) - error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?"); - if (storage_class & STCscope) - isscope = true; - if (storage_class & STCabstract) - isabstract = ABSyes; - - userAttribDecl = sc->userAttribDecl; - - if (sc->linkage == LINKcpp) - classKind = ClassKind::cpp; - if (sc->linkage == LINKobjc) - objc()->setObjc(this); - } - else if (symtab && !scx) - { - return; - } - semanticRun = PASSsemantic; - - if (baseok < BASEOKdone) - { - baseok = BASEOKin; - - // Expand any tuples in baseclasses[] - for (size_t i = 0; i < baseclasses->length; ) - { - BaseClass *b = (*baseclasses)[i]; - b->type = resolveBase(this, sc, scx, b->type); - - Type *tb = b->type->toBasetype(); - if (tb->ty == Ttuple) - { - TypeTuple *tup = (TypeTuple *)tb; - baseclasses->remove(i); - size_t dim = Parameter::dim(tup->arguments); - for (size_t j = 0; j < dim; j++) - { - Parameter *arg = Parameter::getNth(tup->arguments, j); - b = new BaseClass(arg->type); - baseclasses->insert(i + j, b); - } - } - else - i++; - } - - if (baseok >= BASEOKdone) - { - //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun); - if (semanticRun >= PASSsemanticdone) - return; - goto Lancestorsdone; - } - - // See if there's a base class as first in baseclasses[] - if (baseclasses->length) - { - BaseClass *b = (*baseclasses)[0]; - Type *tb = b->type->toBasetype(); - TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; - if (!tc) - { - if (b->type != Type::terror) - error("base type must be class or interface, not %s", b->type->toChars()); - baseclasses->remove(0); - goto L7; - } - - if (tc->sym->isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = true; - - tc->checkDeprecated(loc, sc); - } - } - - if (tc->sym->isInterfaceDeclaration()) - goto L7; - - for (ClassDeclaration *cdb = tc->sym; cdb; cdb = cdb->baseClass) - { - if (cdb == this) - { - error("circular inheritance"); - baseclasses->remove(0); - goto L7; - } - } - - /* Bugzilla 11034: Essentially, class inheritance hierarchy - * and instance size of each classes are orthogonal information. - * Therefore, even if tc->sym->sizeof == SIZEOKnone, - * we need to set baseClass field for class covariance check. - */ - baseClass = tc->sym; - b->sym = baseClass; - - if (tc->sym->baseok < BASEOKdone) - resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference - if (tc->sym->baseok < BASEOKdone) - { - //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); - if (tc->sym->_scope) - tc->sym->_scope->_module->addDeferredSemantic(tc->sym); - baseok = BASEOKnone; - } - L7: ; - } - - // Treat the remaining entries in baseclasses as interfaces - // Check for errors, handle forward references - for (size_t i = (baseClass ? 1 : 0); i < baseclasses->length; ) - { - BaseClass *b = (*baseclasses)[i]; - Type *tb = b->type->toBasetype(); - TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; - if (!tc || !tc->sym->isInterfaceDeclaration()) - { - if (b->type != Type::terror) - error("base type must be interface, not %s", b->type->toChars()); - baseclasses->remove(i); - continue; - } - - // Check for duplicate interfaces - for (size_t j = (baseClass ? 1 : 0); j < i; j++) - { - BaseClass *b2 = (*baseclasses)[j]; - if (b2->sym == tc->sym) - { - error("inherits from duplicate interface %s", b2->sym->toChars()); - baseclasses->remove(i); - continue; - } - } - - if (tc->sym->isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = true; - - tc->checkDeprecated(loc, sc); - } - } - - b->sym = tc->sym; - - if (tc->sym->baseok < BASEOKdone) - resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference - if (tc->sym->baseok < BASEOKdone) - { - //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars()); - if (tc->sym->_scope) - tc->sym->_scope->_module->addDeferredSemantic(tc->sym); - baseok = BASEOKnone; - } - i++; - } - if (baseok == BASEOKnone) - { - // Forward referencee of one or more bases, try again later - _scope = scx ? scx : sc->copy(); - _scope->setNoFree(); - _scope->_module->addDeferredSemantic(this); - //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars()); - return; - } - baseok = BASEOKdone; - - // If no base class, and this is not an Object, use Object as base class - if (!baseClass && ident != Id::Object && !isCPPclass()) - { - if (!object || object->errors) - badObjectDotD(this); - - Type *t = object->type; - t = t->semantic(loc, sc)->toBasetype(); - if (t->ty == Terror) - badObjectDotD(this); - assert(t->ty == Tclass); - TypeClass *tc = (TypeClass *)t; - - BaseClass *b = new BaseClass(tc); - baseclasses->shift(b); - - baseClass = tc->sym; - assert(!baseClass->isInterfaceDeclaration()); - b->sym = baseClass; - } - if (baseClass) - { - if (baseClass->storage_class & STCfinal) - error("cannot inherit from final class %s", baseClass->toChars()); - - // Inherit properties from base class - if (baseClass->isCOMclass()) - com = true; - if (baseClass->isCPPclass()) - classKind = ClassKind::cpp; - if (baseClass->isscope) - isscope = true; - enclosing = baseClass->enclosing; - storage_class |= baseClass->storage_class & STC_TYPECTOR; - } - - interfaces.length = baseclasses->length - (baseClass ? 1 : 0); - interfaces.ptr = baseclasses->tdata() + (baseClass ? 1 : 0); - - for (size_t i = 0; i < interfaces.length; i++) - { - BaseClass *b = interfaces.ptr[i]; - // If this is an interface, and it derives from a COM interface, - // then this is a COM interface too. - if (b->sym->isCOMinterface()) - com = true; - if (isCPPclass() && !b->sym->isCPPinterface()) - { - ::error(loc, "C++ class '%s' cannot implement D interface '%s'", - toPrettyChars(), b->sym->toPrettyChars()); - } - } - - interfaceSemantic(sc); - } -Lancestorsdone: - //printf("\tClassDeclaration::semantic(%s) baseok = %d\n", toChars(), baseok); - - if (!members) // if opaque declaration - { - semanticRun = PASSsemanticdone; - return; - } - if (!symtab) - { - symtab = new DsymbolTable(); - - /* Bugzilla 12152: The semantic analysis of base classes should be finished - * before the members semantic analysis of this class, in order to determine - * vtbl in this class. However if a base class refers the member of this class, - * it can be resolved as a normal forward reference. - * Call addMember() and setScope() to make this class members visible from the base classes. - */ - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->addMember(sc, this); - } - - Scope *sc2 = newScope(sc); - - /* Set scope so if there are forward references, we still might be able to - * resolve individual members like enums. - */ - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - //printf("[%d] setScope %s %s, sc2 = %p\n", i, s->kind(), s->toChars(), sc2); - s->setScope(sc2); - } - - sc2->pop(); - } - - for (size_t i = 0; i < baseclasses->length; i++) - { - BaseClass *b = (*baseclasses)[i]; - Type *tb = b->type->toBasetype(); - assert(tb->ty == Tclass); - TypeClass *tc = (TypeClass *)tb; - - if (tc->sym->semanticRun < PASSsemanticdone) - { - // Forward referencee of one or more bases, try again later - _scope = scx ? scx : sc->copy(); - _scope->setNoFree(); - if (tc->sym->_scope) - tc->sym->_scope->_module->addDeferredSemantic(tc->sym); - _scope->_module->addDeferredSemantic(this); - //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars()); - return; - } - } - - if (baseok == BASEOKdone) - { - baseok = BASEOKsemanticdone; - - // initialize vtbl - if (baseClass) - { - if (isCPPclass() && baseClass->vtbl.length == 0) - { - error("C++ base class %s needs at least one virtual function", baseClass->toChars()); - } - - // Copy vtbl[] from base class - vtbl.setDim(baseClass->vtbl.length); - memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.length); - - vthis = baseClass->vthis; - } - else - { - // No base class, so this is the root of the class hierarchy - vtbl.setDim(0); - if (vtblOffset()) - vtbl.push(this); // leave room for classinfo as first member - } - - /* If this is a nested class, add the hidden 'this' - * member which is a pointer to the enclosing scope. - */ - if (vthis) // if inheriting from nested class - { - // Use the base class's 'this' member - if (storage_class & STCstatic) - error("static class cannot inherit from nested class %s", baseClass->toChars()); - if (toParent2() != baseClass->toParent2() && - (!toParent2() || - !baseClass->toParent2()->getType() || - !baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL))) - { - if (toParent2()) - { - error("is nested within %s, but super class %s is nested within %s", - toParent2()->toChars(), - baseClass->toChars(), - baseClass->toParent2()->toChars()); - } - else - { - error("is not nested, but super class %s is nested within %s", - baseClass->toChars(), - baseClass->toParent2()->toChars()); - } - enclosing = NULL; - } - } - else - makeNested(); - } - - Scope *sc2 = newScope(sc); - - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->importAll(sc2); - } - - // Note that members.length can grow due to tuple expansion during semantic() - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->semantic(sc2); - } - - if (!determineFields()) - { - assert(type == Type::terror); - sc2->pop(); - return; - } - - /* Following special member functions creation needs semantic analysis - * completion of sub-structs in each field types. - */ - for (size_t i = 0; i < fields.length; i++) - { - VarDeclaration *v = fields[i]; - Type *tb = v->type->baseElemOf(); - if (tb->ty != Tstruct) - continue; - StructDeclaration *sd = ((TypeStruct *)tb)->sym; - if (sd->semanticRun >= PASSsemanticdone) - continue; - - sc2->pop(); - - _scope = scx ? scx : sc->copy(); - _scope->setNoFree(); - _scope->_module->addDeferredSemantic(this); - //printf("\tdeferring %s\n", toChars()); - return; - } - - /* Look for special member functions. - * They must be in this class, not in a base class. - */ - - // Can be in base class - aggNew = (NewDeclaration *)search(Loc(), Id::classNew); - aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete); - - // Look for the constructor - ctor = searchCtor(); - - if (!ctor && noDefaultCtor) - { - // A class object is always created by constructor, so this check is legitimate. - for (size_t i = 0; i < fields.length; i++) - { - VarDeclaration *v = fields[i]; - if (v->storage_class & STCnodefaultctor) - ::error(v->loc, "field %s must be initialized in constructor", v->toChars()); - } - } - - // If this class has no constructor, but base class has a default - // ctor, create a constructor: - // this() { } - if (!ctor && baseClass && baseClass->ctor) - { - FuncDeclaration *fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type, NULL, 1); - if (!fd) // try shared base ctor instead - fd = resolveFuncCall(loc, sc2, baseClass->ctor, NULL, type->sharedOf(), NULL, 1); - if (fd && !fd->errors) - { - //printf("Creating default this(){} for class %s\n", toChars()); - TypeFunction *btf = fd->type->toTypeFunction(); - TypeFunction *tf = new TypeFunction(ParameterList(), NULL, LINKd, fd->storage_class); - tf->mod = btf->mod; - tf->purity = btf->purity; - tf->isnothrow = btf->isnothrow; - tf->isnogc = btf->isnogc; - tf->trust = btf->trust; - - CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf); - ctor->fbody = new CompoundStatement(Loc(), new Statements()); - - members->push(ctor); - ctor->addMember(sc, this); - ctor->semantic(sc2); - - this->ctor = ctor; - defaultCtor = ctor; - } - else - { - error("cannot implicitly generate a default ctor when base class %s is missing a default ctor", - baseClass->toPrettyChars()); - } - } - - dtor = buildDtor(this, sc2); - - if (FuncDeclaration *f = hasIdentityOpAssign(this, sc2)) - { - if (!(f->storage_class & STCdisable)) - error(f->loc, "identity assignment operator overload is illegal"); - } - - inv = buildInv(this, sc2); - - Module::dprogress++; - semanticRun = PASSsemanticdone; - //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); - //members.print(); - - sc2->pop(); - - if (type->ty == Tclass && ((TypeClass *)type)->sym != this) - { - // https://issues.dlang.org/show_bug.cgi?id=17492 - ClassDeclaration *cd = ((TypeClass *)type)->sym; - error("already exists at %s. Perhaps in another function with the same name?", cd->loc.toChars()); - } - - if (global.errors != errors) - { - // The type is no good. - type = Type::terror; - this->errors = true; - if (deferred) - deferred->errors = true; - } - - // Verify fields of a synchronized class are not public - if (storage_class & STCsynchronized) - { - for (size_t i = 0; i < fields.length; i++) - { - VarDeclaration *vd = fields[i]; - if (!vd->isThisDeclaration() && - !vd->prot().isMoreRestrictiveThan(Prot(Prot::public_))) - { - vd->error("Field members of a synchronized class cannot be %s", - protectionToChars(vd->prot().kind)); - } - } - } - - if (deferred && !global.gag) - { - deferred->semantic2(sc); - deferred->semantic3(sc); - } - //printf("-ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); -} - /********************************************* * Determine if 'this' is a base class of cd. * This is used to detect circular inheritance only. @@ -917,7 +324,7 @@ bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) */ if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration()) { - cd->semantic(NULL); + dsymbolSemantic(cd, NULL); if (!cd->baseClass && cd->semanticRun < PASSsemanticdone) cd->error("base class is forward referenced by %s", toChars()); } @@ -951,14 +358,14 @@ Dsymbol *ClassDeclaration::search(const Loc &loc, Identifier *ident, int flags) { // must semantic on base class/interfaces ++inuse; - semantic(NULL); + dsymbolSemantic(this, NULL); --inuse; } } if (!members || !symtab) // opaque or addMember is not yet done { - error("is forward referenced when looking for '%s'", ident->toChars()); + error("is forward referenced when looking for `%s`", ident->toChars()); //*(char*)0=0; return NULL; } @@ -1277,19 +684,6 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf) return fdmatch; } -void ClassDeclaration::interfaceSemantic(Scope *) -{ - vtblInterfaces = new BaseClasses(); - vtblInterfaces->reserve(interfaces.length); - - for (size_t i = 0; i < interfaces.length; i++) - { - BaseClass *b = interfaces.ptr[i]; - vtblInterfaces->push(b); - b->copyBaseInterfaces(vtblInterfaces); - } -} - /**************************************** */ @@ -1336,7 +730,7 @@ bool ClassDeclaration::isAbstract() return 0; if (fd->_scope) - fd->semantic(NULL); + dsymbolSemantic(fd, NULL); if (fd->isAbstract()) return 1; @@ -1435,303 +829,6 @@ Scope *InterfaceDeclaration::newScope(Scope *sc) return sc2; } -void InterfaceDeclaration::semantic(Scope *sc) -{ - //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); - if (semanticRun >= PASSsemanticdone) - return; - unsigned errors = global.errors; - - //printf("+InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type); - - Scope *scx = NULL; - if (_scope) - { - sc = _scope; - scx = _scope; // save so we don't make redundant copies - _scope = NULL; - } - - if (!parent) - { - assert(sc->parent && sc->func); - parent = sc->parent; - } - assert(parent && !isAnonymous()); - - if (this->errors) - type = Type::terror; - type = type->semantic(loc, sc); - - if (type->ty == Tclass && ((TypeClass *)type)->sym != this) - { - TemplateInstance *ti = ((TypeClass *)type)->sym->isInstantiated(); - if (ti && isError(ti)) - ((TypeClass *)type)->sym = this; - } - - // Ungag errors when not speculative - Ungag ungag = ungagSpeculative(); - - if (semanticRun == PASSinit) - { - protection = sc->protection; - - storage_class |= sc->stc; - if (storage_class & STCdeprecated) - isdeprecated = true; - - userAttribDecl = sc->userAttribDecl; - } - else if (symtab) - { - if (sizeok == SIZEOKdone || !scx) - { - semanticRun = PASSsemanticdone; - return; - } - } - semanticRun = PASSsemantic; - - if (baseok < BASEOKdone) - { - baseok = BASEOKin; - - // Expand any tuples in baseclasses[] - for (size_t i = 0; i < baseclasses->length; ) - { - BaseClass *b = (*baseclasses)[i]; - b->type = resolveBase(this, sc, scx, b->type); - - Type *tb = b->type->toBasetype(); - if (tb->ty == Ttuple) - { - TypeTuple *tup = (TypeTuple *)tb; - baseclasses->remove(i); - size_t dim = Parameter::dim(tup->arguments); - for (size_t j = 0; j < dim; j++) - { - Parameter *arg = Parameter::getNth(tup->arguments, j); - b = new BaseClass(arg->type); - baseclasses->insert(i + j, b); - } - } - else - i++; - } - - if (baseok >= BASEOKdone) - { - //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun); - if (semanticRun >= PASSsemanticdone) - return; - goto Lancestorsdone; - } - - if (!baseclasses->length && sc->linkage == LINKcpp) - classKind = ClassKind::cpp; - if (sc->linkage == LINKobjc) - objc()->setObjc(this); - - // Check for errors, handle forward references - for (size_t i = 0; i < baseclasses->length; ) - { - BaseClass *b = (*baseclasses)[i]; - Type *tb = b->type->toBasetype(); - TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL; - if (!tc || !tc->sym->isInterfaceDeclaration()) - { - if (b->type != Type::terror) - error("base type must be interface, not %s", b->type->toChars()); - baseclasses->remove(i); - continue; - } - - // Check for duplicate interfaces - for (size_t j = 0; j < i; j++) - { - BaseClass *b2 = (*baseclasses)[j]; - if (b2->sym == tc->sym) - { - error("inherits from duplicate interface %s", b2->sym->toChars()); - baseclasses->remove(i); - continue; - } - } - - if (tc->sym == this || isBaseOf2(tc->sym)) - { - error("circular inheritance of interface"); - baseclasses->remove(i); - continue; - } - - if (tc->sym->isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = true; - - tc->checkDeprecated(loc, sc); - } - } - - b->sym = tc->sym; - - if (tc->sym->baseok < BASEOKdone) - resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference - if (tc->sym->baseok < BASEOKdone) - { - //printf("\ttry later, forward reference of base %s\n", tc->sym->toChars()); - if (tc->sym->_scope) - tc->sym->_scope->_module->addDeferredSemantic(tc->sym); - baseok = BASEOKnone; - } - i++; - } - if (baseok == BASEOKnone) - { - // Forward referencee of one or more bases, try again later - _scope = scx ? scx : sc->copy(); - _scope->setNoFree(); - _scope->_module->addDeferredSemantic(this); - return; - } - baseok = BASEOKdone; - - interfaces.length = baseclasses->length; - interfaces.ptr = baseclasses->tdata(); - - for (size_t i = 0; i < interfaces.length; i++) - { - BaseClass *b = interfaces.ptr[i]; - // If this is an interface, and it derives from a COM interface, - // then this is a COM interface too. - if (b->sym->isCOMinterface()) - com = true; - if (b->sym->isCPPinterface()) - classKind = ClassKind::cpp; - } - - interfaceSemantic(sc); - } -Lancestorsdone: - - if (!members) // if opaque declaration - { - semanticRun = PASSsemanticdone; - return; - } - if (!symtab) - symtab = new DsymbolTable(); - - for (size_t i = 0; i < baseclasses->length; i++) - { - BaseClass *b = (*baseclasses)[i]; - Type *tb = b->type->toBasetype(); - assert(tb->ty == Tclass); - TypeClass *tc = (TypeClass *)tb; - - if (tc->sym->semanticRun < PASSsemanticdone) - { - // Forward referencee of one or more bases, try again later - _scope = scx ? scx : sc->copy(); - _scope->setNoFree(); - if (tc->sym->_scope) - tc->sym->_scope->_module->addDeferredSemantic(tc->sym); - _scope->_module->addDeferredSemantic(this); - return; - } - } - - if (baseok == BASEOKdone) - { - baseok = BASEOKsemanticdone; - - // initialize vtbl - if (vtblOffset()) - vtbl.push(this); // leave room at vtbl[0] for classinfo - - // Cat together the vtbl[]'s from base interfaces - for (size_t i = 0; i < interfaces.length; i++) - { - BaseClass *b = interfaces.ptr[i]; - - // Skip if b has already appeared - for (size_t k = 0; k < i; k++) - { - if (b == interfaces.ptr[k]) - goto Lcontinue; - } - - // Copy vtbl[] from base class - if (b->sym->vtblOffset()) - { - size_t d = b->sym->vtbl.length; - if (d > 1) - { - vtbl.reserve(d - 1); - for (size_t j = 1; j < d; j++) - vtbl.push(b->sym->vtbl[j]); - } - } - else - { - vtbl.append(&b->sym->vtbl); - } - - Lcontinue: - ; - } - } - - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->addMember(sc, this); - } - - Scope *sc2 = newScope(sc); - - /* Set scope so if there are forward references, we still might be able to - * resolve individual members like enums. - */ - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - //printf("setScope %s %s\n", s->kind(), s->toChars()); - s->setScope(sc2); - } - - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->importAll(sc2); - } - - for (size_t i = 0; i < members->length; i++) - { - Dsymbol *s = (*members)[i]; - s->semantic(sc2); - } - - Module::dprogress++; - semanticRun = PASSsemanticdone; - //printf("-InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type); - //members->print(); - - sc2->pop(); - - if (global.errors != errors) - { - // The type is no good. - type = Type::terror; - } - - assert(type->ty != Tclass || ((TypeClass *)type)->sym == this); -} - /******************************************* * Determine if 'this' is a base class of cd. * (Actually, if it is an interface supported by cd) @@ -1901,7 +998,7 @@ bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newin //printf("newinstance = %d fd->toParent() = %s ifd->toParent() = %s\n", //newinstance, fd->toParent()->toChars(), ifd->toParent()->toChars()); if (newinstance && fd->toParent() != cd && ifd->toParent() == sym) - cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); + cd->error("interface function `%s` is not implemented", ifd->toFullSignature()); if (fd->toParent() == cd) result = true; @@ -1911,7 +1008,7 @@ bool BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newin //printf(" not found %p\n", fd); // BUG: should mark this class as abstract? if (!cd->isAbstract()) - cd->error("interface function '%s' is not implemented", ifd->toFullSignature()); + cd->error("interface function `%s` is not implemented", ifd->toFullSignature()); fd = NULL; } |