Mercurial > projects > ddmd
view dmd/AliasDeclaration.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 5c9b78899f5d |
line wrap: on
line source
module dmd.AliasDeclaration; import dmd.LINK; import dmd.Declaration; import dmd.TypedefDeclaration; import dmd.VarDeclaration; import dmd.FuncDeclaration; import dmd.FuncAliasDeclaration; import dmd.Dsymbol; import dmd.ScopeDsymbol; import dmd.Loc; import dmd.Identifier; import dmd.Type; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.Scope; import dmd.STC; import dmd.Expression; import dmd.Global; class AliasDeclaration : Declaration { Dsymbol aliassym; Dsymbol overnext; // next in overload list int inSemantic; this(Loc loc, Identifier ident, Type type) { super(ident); //printf("AliasDeclaration(id = '%s', type = %p)\n", id.toChars(), type); //printf("type = '%s'\n", type.toChars()); this.loc = loc; this.type = type; this.aliassym = null; version (_DH) { this.htype = null; this.haliassym = null; } assert(type); } this(Loc loc, Identifier id, Dsymbol s) { super(id); //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); assert(s !is this); /// huh? this.loc = loc; this.type = null; this.aliassym = s; version (_DH) { this.htype = null; this.haliassym = null; } assert(s); } Dsymbol syntaxCopy(Dsymbol) { assert(false); } void semantic(Scope sc) { //printf("AliasDeclaration.semantic() %s\n", toChars()); if (aliassym) { if (aliassym.isTemplateInstance()) aliassym.semantic(sc); return; } this.inSemantic = 1; if (storage_class & STC.STCconst) error("cannot be const"); storage_class |= sc.stc & 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 && ((s.getType() && type.equals(s.getType())) || s.isEnumMember())) goto L2; // it's a symbolic alias ///version (DMDV2) { if (storage_class & STC.STCref) { // 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 |= STC.STCref; 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 s = getDsymbol(e); if (s) goto L2; error("cannot alias an expression %s", e.toChars()); t = e.type; } else if (t) { type = t; } if (overnext) ScopeDsymbol.multiplyDefined(Loc(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 (v && v.linkage == LINK.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); if (!fa.overloadInsert(overnext)) ScopeDsymbol.multiplyDefined(Loc(0), f, overnext); overnext = null; s = fa; s.parent = sc.parent; } } if (overnext) ScopeDsymbol.multiplyDefined(Loc(0), s, overnext); if (s == this) { assert(global.errors); s = null; } } //printf("setting aliassym %p to %p\n", this, s); aliassym = s; this.inSemantic = 0; } bool overloadInsert(Dsymbol s) { /* Don't know yet what the aliased symbol is, so assume it can * be overloaded and check later for correctness. */ //printf("AliasDeclaration.overloadInsert('%s')\n", s.toChars()); if (overnext is null) { overnext = s; return true; } else { return overnext.overloadInsert(s); } } string kind() { return "alias"; } Type getType() { return type; } Dsymbol toAlias() { //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); assert(this !is aliassym); //static int count; if (++count == 10) *(char*)0=0; if (inSemantic) { error("recursive alias declaration"); aliassym = new TypedefDeclaration(loc, ident, Type.terror, null); } Dsymbol s = aliassym ? aliassym.toAlias() : this; return s; } void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } version (_DH) { Type htype; Dsymbol haliassym; } void toDocBuffer(OutBuffer buf) { assert(false); } AliasDeclaration isAliasDeclaration() { return this; } }