diff options
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; } |