void AliasDeclaration::semantic(Scope *sc) { //printf("AliasDeclaration::semantic() %s\n", toChars()); if (aliassym) { if (aliassym->isTemplateInstance()) aliassym->semantic(sc); return; } this->inSemantic = 1; #if DMDV1 // don't really know why this is here if (storage_class & STCconst) error("cannot be const"); #endif storage_class |= sc->stc & STCdeprecated; // Given: // alias foo.bar.abc def; // it is not knowable from the syntax whether this is an alias // for a type or an alias for a symbol. It is up to the semantic() // pass to distinguish. // If it is a type, then type is set and getType() will return that // type. If it is a symbol, then aliassym is set and type is NULL - // toAlias() will return aliasssym. Dsymbol *s; Type *t; Expression *e; /* This section is needed because resolve() will: * const x = 3; * alias x y; * try to alias y to 3. */ s = type->toDsymbol(sc); if (s #if DMDV2 ` && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) #endif ) goto L2; // it's a symbolic alias #if DMDV2 type = type->addStorageClass(storage_class); if (storage_class & (STCref | STCnothrow | STCpure | STCdisable)) { // For 'ref' to be attached to function types, and picked // up by Type::resolve(), it has to go into sc. sc = sc->push(); sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable); type->resolve(loc, sc, &e, &t, &s); sc = sc->pop(); } else #endif type->resolve(loc, sc, &e, &t, &s); if (s) { goto L2; } else if (e) { // Try to convert Expression to Dsymbol if (e->op == TOKvar) { s = ((VarExp *)e)->var; goto L2; } else if (e->op == TOKfunction) { s = ((FuncExp *)e)->fd; goto L2; } else { error("cannot alias an expression %s", e->toChars()); t = e->type; } } else if (t) { type = t; } if (overnext) ScopeDsymbol::multiplyDefined(0, this, overnext); this->inSemantic = 0; return; L2: //printf("alias is a symbol %s %s\n", s->kind(), s->toChars()); type = NULL; VarDeclaration *v = s->isVarDeclaration(); if (0 && v && v->linkage == LINKdefault) { error("forward reference of %s", v->toChars()); s = NULL; } else { FuncDeclaration *f = s->toAlias()->isFuncDeclaration(); if (f) { if (overnext) { FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); fa->importprot = importprot; if (!fa->overloadInsert(overnext)) ScopeDsymbol::multiplyDefined(0, f, overnext); overnext = NULL; s = fa; s->parent = sc->parent; } } if (overnext) ScopeDsymbol::multiplyDefined(0, s, overnext); if (s == this) { assert(global.errors); s = NULL; } } //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars()); aliassym = s; this->inSemantic = 0; }