Mercurial > projects > ddmd
view dmd/AliasDeclaration.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | af724d3510d7 |
children | cd48cb899aee |
line wrap: on
line source
module dmd.AliasDeclaration; import dmd.common; 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) { register(); 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) { register(); 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); } override Dsymbol syntaxCopy(Dsymbol s) { //printf("AliasDeclaration::syntaxCopy()\n"); assert(!s); AliasDeclaration sa; if (type) sa = new AliasDeclaration(loc, ident, type.syntaxCopy()); else sa = new AliasDeclaration(loc, ident, aliassym.syntaxCopy(null)); version (_DH) { // Syntax copy for header file if (!htype) // Don't overwrite original { if (type) // Make copy for both old and new instances { htype = type.syntaxCopy(); sa.htype = type.syntaxCopy(); } } else // Make copy of original for new instance sa.htype = htype.syntaxCopy(); if (!haliassym) { if (aliassym) { haliassym = aliassym.syntaxCopy(s); sa.haliassym = aliassym.syntaxCopy(s); } } else sa.haliassym = haliassym.syntaxCopy(s); } // version (_DH) return sa; } override void semantic(Scope sc) { //printf("AliasDeclaration.semantic() %s\n", toChars()); if (aliassym) { if (aliassym.isTemplateInstance()) aliassym.semantic(sc); return; } this.inSemantic = 1; version(DMDV1) { // don't really know why this is here 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) { type = type.addStorageClass(storage_class); if (storage_class & (STC.STCref | STCnothrow | STCpure)) { // 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); 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; } override 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) { static if (true) { if (s is this) return true; } overnext = s; return true; } else { return overnext.overloadInsert(s); } } override string kind() { return "alias"; } override Type getType() { return type; } override 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; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("alias "); /// static if (false) { // && _DH /// if (hgs.hdrgen) /// { /// if (haliassym) /// { /// haliassym.toCBuffer(buf, hgs); /// buf.writeByte(' '); /// buf.writestring(ident.toChars()); /// } /// else /// htype.toCBuffer(buf, ident, hgs); /// } /// else /// } { if (aliassym) { aliassym.toCBuffer(buf, hgs); buf.writeByte(' '); buf.writestring(ident.toChars()); } else type.toCBuffer(buf, ident, hgs); } buf.writeByte(';'); buf.writenl(); } version (_DH) { Type htype; Dsymbol haliassym; } override void toDocBuffer(OutBuffer buf) { assert(false); } override AliasDeclaration isAliasDeclaration() { return this; } }