diff dmd/Dsymbol.d @ 187:b0d41ff5e0df

Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author Abscissa
date Tue, 07 Jun 2011 23:37:34 -0400
parents cd48cb899aee
children
line wrap: on
line diff
--- a/dmd/Dsymbol.d	Tue Jun 07 21:01:03 2011 -0400
+++ b/dmd/Dsymbol.d	Tue Jun 07 23:37:34 2011 -0400
@@ -1,940 +1,944 @@
-module dmd.Dsymbol;
-
-import dmd.common;
-import dmd.Loc;
-import dmd.STC;
-import dmd.Scope;
-import dmd.Lexer;
-import dmd.Module;
-import dmd.Array;
-import dmd.ScopeDsymbol;
-import dmd.OutBuffer;
-import dmd.Id;
-import dmd.Identifier;
-import dmd.TemplateInstance;
-import dmd.SharedStaticCtorDeclaration;
-import dmd.SharedStaticDtorDeclaration;
-import dmd.HdrGenState;
-import dmd.AggregateDeclaration;
-import dmd.ClassDeclaration;
-import dmd.LabelDsymbol;
-import dmd.Type;
-import dmd.PROT;
-import dmd.ArrayTypes;
-import dmd.Package;
-import dmd.EnumMember;
-import dmd.TemplateDeclaration;
-import dmd.TemplateMixin;
-import dmd.Declaration;
-import dmd.ThisDeclaration;
-import dmd.TupleDeclaration;
-import dmd.TypedefDeclaration;
-import dmd.AliasDeclaration;
-import dmd.FuncDeclaration;
-import dmd.FuncAliasDeclaration;
-import dmd.FuncLiteralDeclaration;
-import dmd.CtorDeclaration;
-import dmd.PostBlitDeclaration;
-import dmd.DtorDeclaration;
-import dmd.StaticCtorDeclaration;
-import dmd.StaticDtorDeclaration;
-import dmd.InvariantDeclaration;
-import dmd.UnitTestDeclaration;
-import dmd.NewDeclaration;
-import dmd.VarDeclaration;
-import dmd.StructDeclaration;
-import dmd.UnionDeclaration;
-import dmd.InterfaceDeclaration;
-import dmd.WithScopeSymbol;
-import dmd.ArrayScopeSymbol;
-import dmd.Import;
-import dmd.EnumDeclaration;
-import dmd.DeleteDeclaration;
-import dmd.SymbolDeclaration;
-import dmd.AttribDeclaration;
-import dmd.OverloadSet;
-import dmd.DYNCAST;
-import dmd.Global;
-import dmd.Expression;
-import dmd.TOK;
-import dmd.VarExp;
-import dmd.FuncExp;
-
-import dmd.backend.Symbol;
-import dmd.backend.TYPE;
-import dmd.backend.Util;
-import dmd.backend.mTYman;
-import dmd.backend.TYFL;
-import dmd.backend.TYM;
-import dmd.backend.mTY;
-import dmd.backend.SC;
-import dmd.backend.FL;
-import dmd.backend.LIST;
-public import dmd.PASS;
-
-import core.stdc.string : strcmp, memcpy, strlen;
-version (Bug4054) import core.memory;
-else import core.stdc.stdlib : alloca;
-
-import std.stdio;
-
-// TODO: remove dependencies on these
-Expression isExpression(Object o)
-{
-    return cast(Expression)o;
-}
-
-Dsymbol isDsymbol(Object o)
-{
-    return cast(Dsymbol)o;
-}
-
-Type isType(Object o)
-{
-    return cast(Type)o;
-}
-
-/***********************
- * Try to get arg as a type.
- */
-
-Type getType(Object o)
-{
-    Type t = isType(o);
-    if (!t)
-    {   Expression e = isExpression(o);
-	if (e)
-	    t = e.type;
-    }
-    return t;
-}
-
-
-Dsymbol getDsymbol(Object oarg)
-{
-	Dsymbol sa;
-    Expression ea = isExpression(oarg);
-    if (ea)
-    {   // Try to convert Expression to symbol
-		if (ea.op == TOK.TOKvar)
-			sa = (cast(VarExp)ea).var;
-		else if (ea.op == TOK.TOKfunction)
-			sa = (cast(FuncExp)ea).fd;
-		else
-			sa = null;
-    }
-    else
-    {   // Try to convert Type to symbol
-		Type ta = isType(oarg);
-		if (ta)
-			sa = ta.toDsymbol(null);
-		else
-			sa = isDsymbol(oarg);	// if already a symbol
-    }
-    return sa;
-}
-
-alias Vector!Dsymbol Dsymbols;
-
-import dmd.TObject;
-
-class Dsymbol : TObject
-{
-    Identifier ident;
-    Identifier c_ident;
-    Dsymbol parent;
-    Symbol* csym;		// symbol for code generator
-    Symbol* isym;		// import version of csym
-    string comment;	// documentation comment for this Dsymbol
-    Loc loc;			// where defined
-    Scope scope_;		// !=null means context to use for semantic()
-
-    this()
-	{
-		register();
-		// do nothing
-	}
-	
-    this(Identifier ident)
-	{
-		register();
-		this.ident = ident;
-	}
-
-    string toChars()
-	{
-		return ident ? ident.toChars() : "__anonymous";
-	}
-
-    string locToChars()
-	{
-		scope OutBuffer buf = new OutBuffer();
-		Module m = getModule();
-
-		if (m && m.srcfile)
-			loc.filename = m.srcfile.toChars();
-
-		return loc.toChars();
-	}
-
-    bool equals(Object o)
-	{
-		Dsymbol s;
-
-		if (this is o)
-			return true;
-			
-		s = cast(Dsymbol)(o);
-		if (s && ident.equals(s.ident))
-			return true;
-
-		return false;
-	}
-
-    bool isAnonymous()
-	{
-		return ident ? 0 : 1;
-	}
-
-    void error(T...)(Loc loc, string format, T t)
-	{
-		if (!global.gag)
-		{
-			string p = loc.toChars();
-			if (p.length == 0)
-				p = locToChars();
-
-			if (p.length != 0) {
-				writef("%s: ", p);
-			}
-
-			write("Error: ");
-			writef("%s %s ", kind(), toPrettyChars());
-
-			writefln(format, t);
-		}
-
-		global.errors++;
-		
-		//fatal();
-	}
-
-    void error(T...)(string format, T t)
-	{
-		//printf("Dsymbol.error()\n");
-		if (!global.gag)
-		{
-			string p = loc.toChars();
-
-			if (p.length != 0) {
-				writef("%s: ", p);
-			}
-
-			write("Error: ");
-			if (isAnonymous()) {
-				writef("%s ", kind());
-			} else {
-				writef("%s %s ", kind(), toPrettyChars());
-			}
-
-			writefln(format, t);
-		}
-		global.errors++;
-
-		//fatal();
-	}
-
-    void checkDeprecated(Loc loc, Scope sc)
-	{
-		if (!global.params.useDeprecated && isDeprecated())
-		{
-			// Don't complain if we're inside a deprecated symbol's scope
-			for (Dsymbol sp = sc.parent; sp; sp = sp.parent)
-			{   
-				if (sp.isDeprecated())
-					goto L1;
-			}
-
-			for (; sc; sc = sc.enclosing)
-			{
-				if (sc.scopesym && sc.scopesym.isDeprecated())
-					goto L1;
-
-				// If inside a StorageClassDeclaration that is deprecated
-				if (sc.stc & STC.STCdeprecated)
-					goto L1;
-			}
-
-			error(loc, "is deprecated");
-		}
-		
-	L1:
-		Declaration d = isDeclaration();
-		if (d && d.storage_class & STCdisable)
-		{
-			if (!(sc.func && sc.func.storage_class & STCdisable))
-			{
-				if (d.ident == Id.cpctor && d.toParent())
-					d.toParent().error(loc, "is not copyable");
-				else
-					error(loc, "is not callable");
-			}
-		}
-	}
-	
-    Module getModule()
-	{
-		//printf("Dsymbol.getModule()\n");
-		Dsymbol s = this;
-		while (s)
-		{
-			//printf("\ts = '%s'\n", s.toChars());
-			Module m = s.isModule();
-			if (m)
-				return m;
-			s = s.parent;
-		}
-
-		return null;
-	}
-	
-    Dsymbol pastMixin()
-	{
-		 Dsymbol s = this;
-		//printf("Dsymbol::pastMixin() %s\n", toChars());
-		while (s && s.isTemplateMixin())
-			s = s.parent;
-		return s;
-	}
-	
-    Dsymbol toParent()
-	{
-		return parent ? parent.pastMixin() : null;
-	}
-
-	/**********************************
-	 * Use this instead of toParent() when looking for the
-	 * 'this' pointer of the enclosing function/class.
-	 */
-    Dsymbol toParent2()
-	{
-		Dsymbol s = parent;
-		while (s && s.isTemplateInstance())
-			s = s.parent;
-		return s;
-	}
-	
-    TemplateInstance inTemplateInstance()
-	{
-		for (Dsymbol parent = this.parent; parent; parent = parent.parent)
-		{
-			TemplateInstance ti = parent.isTemplateInstance();
-			if (ti)
-				return ti;
-		}
-
-		return null;
-	}
-
-    DYNCAST dyncast() { return DYNCAST.DYNCAST_DSYMBOL; }	// kludge for template.isSymbol()
-
-	/*************************************
-	 * Do syntax copy of an array of Dsymbol's.
-	 */
-    static Vector!Dsymbol arraySyntaxCopy(Vector!Dsymbol a)
-	{
-		Vector!Dsymbol b = null;
-		if (a)
-		{
-			b = a.copy();
-			for (int i = 0; i < b.dim; i++)
-			{
-				auto s = b[i];
-
-				s = s.syntaxCopy(null);
-				b[i] = s;
-			}
-		}
-		return b;
-	}
-
-    string toPrettyChars()
-	{
-		//printf("Dsymbol.toPrettyChars() '%s'\n", toChars());
-		if (!parent) {
-			return toChars();
-		}
-
-		size_t len = 0;
-		for (Dsymbol p = this; p; p = p.parent) {
-			len += p.toChars().length + 1;
-		}
-		--len;
-
-version (Bug4054)
-		char* s = cast(char*)GC.malloc(len);
-else
-		char* s = cast(char*)alloca(len);
-		char* q = s + len;
-
-		for (Dsymbol p = this; p; p = p.parent)
-		{
-			string t = p.toChars();
-			size_t length = t.length;
-			q -= length;
-
-			memcpy(q, t.ptr, length);
-			if (q is s)
-				break;
-			
-			q--;
-	version (TARGET_NET) {
-			if (AggregateDeclaration ad = p.isAggregateDeclaration())
-			{
-				if (ad.isNested() && p.parent && p.parent.isAggregateDeclaration())
-				{
-					*q = '/';
-					continue;
-				}
-			}
-	}
-			*q = '.';
-		}
-
-		return s[0..len].idup;
-	}
-	
-    string kind()
-	{
-		assert(false);
-	}
-	
-	/*********************************
-	 * If this symbol is really an alias for another,
-	 * return that other.
-	 */
-    Dsymbol toAlias()			// resolve real symbol
-	{
-		return this;
-	}
-	
-    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
-	{
-		//printf("Dsymbol.addMember('%s')\n", toChars());
-		//printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars());
-		assert(sd !is null);
-		parent = sd;
-		if (!isAnonymous())		// no name, so can't add it to symbol table
-		{
-			if (!sd.symtabInsert(this))	// if name is already defined
-			{
-				Dsymbol s2 = sd.symtab.lookup(ident);
-				if (!s2.overloadInsert(this))
-				{
-					sd.multiplyDefined(Loc(0), this, s2);
-				}
-			}
-			if (sd.isAggregateDeclaration() || sd.isEnumDeclaration())
-			{
-				if (ident is Id.__sizeof || ident is Id.alignof_ || ident is Id.mangleof_)
-					error(".%s property cannot be redefined", ident.toChars());
-			}
-			return true;
-		}
-
-		return false;
-	}
-	
-    void setScope(Scope sc)
-	{
-		//printf("Dsymbol.setScope() %p %s\n", this, toChars());
-		if (!sc.nofree)
-			sc.setNoFree();		// may need it even after semantic() finishes
-		scope_ = sc;
-	}
-    
-    void importAll(Scope sc)
-    {
-    }
-	
-    void semantic(Scope sc)
-	{
-    	error("%p has no semantic routine", this);
-	}
-	
-	/*************************************
-	 * Does semantic analysis on initializers and members of aggregates.
-	 */
-    void semantic2(Scope sc)
-	{
-		// Most Dsymbols have no further semantic analysis needed
-	}
-
-	/*************************************
-	 * Does semantic analysis on function bodies.
-	 */	
-    void semantic3(Scope sc)
-	{
-		// Most Dsymbols have no further semantic analysis needed
-	}
-	
-	/*************************************
-	 * Look for function inlining possibilities.
-	 */
-    void inlineScan()
-	{
-		// Most Dsymbols aren't functions
-	}
-	
-	/*********************************************
-	 * Search for ident as member of s.
-	 * Input:
-	 *	flags:	1	don't find private members
-	 *		2	don't give error messages
-	 *		4	return null if ambiguous
-	 * Returns:
-	 *	null if not found
-	 */
-    Dsymbol search(Loc loc, Identifier ident, int flags)
-	{
-		//printf("Dsymbol.search(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
-		return null;
-	}
-	
-	/***************************************
-	 * Search for identifier id as a member of 'this'.
-	 * id may be a template instance.
-	 * Returns:
-	 *	symbol found, null if not
-	 */
-    Dsymbol searchX(Loc loc, Scope sc, Object o)
-	{
-		//printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
-		Dsymbol s = toAlias();
-		Dsymbol sm;
-
-		if (auto ident = cast(Identifier)o)
-		{
-			sm = s.search(loc, ident, 0);
-		}
-		else if (auto st = cast(Dsymbol)o)
-		{
-			// It's a template instance
-			//printf("\ttemplate instance id\n");
-			TemplateInstance ti = st.isTemplateInstance();
-			Identifier id = ti.name;
-			sm = s.search(loc, cast(Identifier)id, 0);
-			if (!sm)
-			{   
-				error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.toChars());
-				return null;
-			}
-			sm = sm.toAlias();
-			TemplateDeclaration td = sm.isTemplateDeclaration();
-			if (!td)
-			{
-				error("%s is not a template, it is a %s", id.toChars(), sm.kind());
-				return null;
-			}
-
-			ti.tempdecl = td;
-			if (!ti.semanticRun)
-				ti.semantic(sc);
-
-			sm = ti.toAlias();
-		}
-		else
-		{
-			assert(0);
-		}
-		return sm;
-	}
-	
-    bool overloadInsert(Dsymbol s)
-	{
-		assert(false);
-	}
-	
-version (_DH)
-{
-    char* toHChars()
-	{
-		assert(false);
-	}
-	
-    void toHBuffer(OutBuffer buf, HdrGenState* hgs)
-	{
-		assert(false);
-	}
-}
-    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
-	{
-		assert(false);
-	}
-	
-    void toDocBuffer(OutBuffer buf)
-	{
-		assert(false);
-	}
-    
-    void toJsonBuffer(OutBuffer buf)
-    {
-    }
-	
-    uint size(Loc loc)
-	{
-		assert(false);
-	}
-
-    int isforwardRef()
-	{
-		assert(false);
-	}
-	
-    void defineRef(Dsymbol s)
-	{
-		assert(false);
-	}
-	
-    AggregateDeclaration isThis()	// is a 'this' required to access the member
-	{
-		return null;
-	}
-	
-    ClassDeclaration isClassMember()	// are we a member of a class?
-	{
-		Dsymbol parent = toParent();
-		if (parent && parent.isClassDeclaration())
-			return cast(ClassDeclaration)parent;
-		return null;
-	}
-	
-    bool isExport()			// is Dsymbol exported?
-	{
-		return false;
-	}
-	
-    bool isImportedSymbol()		// is Dsymbol imported?
-	{
-		return false;
-	}
-	
-    bool isDeprecated()			// is Dsymbol deprecated?
-	{
-		return false;
-	}
-
-version (DMDV2) {
-    bool isOverloadable()
-	{
-		return false;
-	}
-}
-
-    LabelDsymbol isLabel()		// is this a LabelDsymbol?
-	{
-		return null;
-	}
-	
-    AggregateDeclaration isMember()	// is this symbol a member of an AggregateDeclaration?
-	{
-		//printf("Dsymbol::isMember() %s\n", toChars());
-		Dsymbol parent = toParent();
-		//printf("parent is %s %s\n", parent.kind(), parent.toChars());
-		return parent ? parent.isAggregateDeclaration() : null;
-	}
-
-    Type getType()			// is this a type?
-	{
-		return null;
-	}
-	
-    string mangle()
-	{
-		OutBuffer buf = new OutBuffer();
-		string id;
-
-static if (false) {
-		printf("Dsymbol::mangle() '%s'", toChars());
-		if (parent)
-			printf("  parent = %s %s", parent.kind(), parent.toChars());
-		printf("\n");
-}
-		id = ident ? ident.toChars() : toChars();
-		if (parent)
-		{
-			string p = parent.mangle();
-			if (p[0] == '_' && p[1] == 'D')
-				p =  p[2..$];
-			buf.writestring(p);
-		}
-		///buf.printf("%zu%s", id.length, id);
-		buf.printf("%d%s", id.length, id);
-		id = buf.toChars();
-		buf.data = null;
-		//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
-		return id;
-	}
-
-    bool needThis()			// need a 'this' pointer?
-	{
-		return false;
-	}
-
-    PROT prot()
-	{
-		assert(false);
-	}
-
-    Dsymbol syntaxCopy(Dsymbol s)	// copy only syntax trees
-	{
-		assert(false);
-	}
-
-	/**************************************
-	 * Determine if this symbol is only one.
-	 * Returns:
-	 *	false, *ps = null: There are 2 or more symbols
-	 *	true,  *ps = null: There are zero symbols
-	 *	true,  *ps = symbol: The one and only one symbol
-	 */
-    bool oneMember(Dsymbol* ps)
-	{
-		//printf("Dsymbol::oneMember()\n");
-		*ps = this;
-		return true;
-	}
-
-	/*****************************************
-	 * Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
-	 */
-    static bool oneMembers(Dsymbols members, Dsymbol* ps)
-	{
-		//printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0);
-		Dsymbol s = null;
-
-		if (members)
-		{
-			foreach(sx; members)
-			{   
-				bool x = sx.oneMember(ps);
-				//printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps);
-				if (!x)
-				{
-					//printf("\tfalse 1\n");
-					assert(*ps is null);
-					return false;
-				}
-				if (*ps)
-				{
-					if (s)			// more than one symbol
-					{   
-						*ps = null;
-						//printf("\tfalse 2\n");
-						return false;
-					}
-					s = *ps;
-				}
-			}
-		}
-
-		*ps = s;		// s is the one symbol, null if none
-		//printf("\ttrue\n");
-		return true;
-	}
-	
-	/*****************************************
-	 * Is Dsymbol a variable that contains pointers?
-	 */
-    bool hasPointers()
-	{
-		//printf("Dsymbol::hasPointers() %s\n", toChars());
-		return 0;
-	}
-
-    void addLocalClass(ClassDeclarations) { }
-    void checkCtorConstInit() { }
-
-    // since comment is stored immutable string is correct here
-    void addComment(string comment)
-	{
-		//if (comment)
-			//writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
-
-		if (this.comment is null)
-		{
-			this.comment = comment;
-		}
-		else
-		{
-static if (true)
-{
-			if (comment !is null && comment != this.comment)
-			{	// Concatenate the two
-				this.comment = Lexer.combineComments(this.comment, comment);
-			}
-}
-		}
-	}
-	
-    void emitComment(Scope sc)
-	{
-		assert(false);
-	}
-	
-    void emitDitto(Scope sc)
-	{
-		assert(false);
-	}
-
-    // Backend
-
-    Symbol* toSymbol()			// to backend symbol
-	{
-		assert(false);
-	}
-	
-    void toObjFile(int multiobj)			// compile to .obj file
-	{
-		//printf("Dsymbol::toObjFile('%s')\n", toChars());
-		// ignore
-	}
-	
-    int cvMember(ubyte* p)	// emit cv debug info for member
-	{
-		assert(false);
-	}
-
-	/*********************************
-	 * Generate import symbol from symbol.
-	 */
-    Symbol* toImport()				// to backend import symbol
-	{
-		if (!isym)
-		{
-			if (!csym)
-				csym = toSymbol();
-			isym = toImport(csym);
-		}
-
-		return isym;
-	}
-	
-    static Symbol* toImport(Symbol* sym)		// to backend import symbol
-	{
-		char* id;
-		char* n;
-		Symbol* s;
-		type* t;
-
-		//printf("Dsymbol::toImport('%s')\n", sym->Sident);
-		n = sym.Sident.ptr;
-version (Bug4054)
-		id = cast(char*) GC.malloc(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1);
-else
-		id = cast(char*) alloca(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1);
-		if (sym.Stype.Tmangle == mTYman_std && tyfunc(sym.Stype.Tty))
-		{
-			sprintf(id, "_imp__%s@%lu", n, type_paramsize_i(sym.Stype));
-		}
-		else if (sym.Stype.Tmangle == mTYman_d)
-			sprintf(id,"_imp_%s",n);
-		else
-			sprintf(id,"_imp__%s",n);
-		t = type_alloc(TYnptr | mTYconst);
-		t.Tnext = sym.Stype;
-		t.Tnext.Tcount++;
-		t.Tmangle = mTYman_c;
-		t.Tcount++;
-		s = symbol_calloc(id);
-		s.Stype = t;
-		s.Sclass = SCextern;
-		s.Sfl = FLextern;
-		slist_add(s);
-
-		return s;
-	}
-
-    Symbol* toSymbolX(string prefix, int sclass, TYPE* t, string suffix)	// helper
-	{
-		Symbol* s;
-		char* id;
-		string n;
-		size_t nlen;
-
-		//writef("Dsymbol::toSymbolX('%s', '%s')\n", prefix, this.classinfo.name);
-		n = mangle();
-		assert(n.length != 0);
-
-		nlen = n.length;
-static if (false) {
-		if (nlen > 2 && n[0] == '_' && n[1] == 'D')
-		{
-			nlen -= 2;
-			n += 2;
-		}
-}
-		version (Bug4054)
-		id = cast(char*) GC.malloc(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1);
-		else
-		id = cast(char*) alloca(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1);
-	    sprintf(id, "_D%.*s%zu%.*s%.*s", n, prefix.length, prefix, suffix);
-		
-	static if (false) {
-		if (global.params.isWindows && (type_mangle(t) == mTYman.mTYman_c || type_mangle(t) == mTYman.mTYman_std))
-			id++;			// Windows C mangling will put the '_' back in
-	}
-		s = symbol_name(id, sclass, t);
-		
-		//printf("-Dsymbol::toSymbolX() %s\n", id);
-		return s;
-	}
-
-    // Eliminate need for dynamic_cast
-    Package isPackage() { return null; }
-    Module isModule() { return null; }
-    EnumMember isEnumMember() { return null; }
-    TemplateDeclaration isTemplateDeclaration() { return null; }
-    TemplateInstance isTemplateInstance() { return null; }
-    TemplateMixin isTemplateMixin() { return null; }
-    Declaration isDeclaration() { return null; }
-    ThisDeclaration isThisDeclaration() { return null; }
-    TupleDeclaration isTupleDeclaration() { return null; }
-    TypedefDeclaration isTypedefDeclaration() { return null; }
-    AliasDeclaration isAliasDeclaration() { return null; }
-    AggregateDeclaration isAggregateDeclaration() { return null; }
-    FuncDeclaration isFuncDeclaration() { return null; }
-    FuncAliasDeclaration isFuncAliasDeclaration() { return null; }
-    FuncLiteralDeclaration isFuncLiteralDeclaration() { return null; }
-    CtorDeclaration isCtorDeclaration() { return null; }
-    PostBlitDeclaration isPostBlitDeclaration() { return null; }
-    DtorDeclaration isDtorDeclaration() { return null; }
-    StaticCtorDeclaration isStaticCtorDeclaration() { return null; }
-    StaticDtorDeclaration isStaticDtorDeclaration() { return null; }
-    SharedStaticCtorDeclaration isSharedStaticCtorDeclaration() { return null; }
-    SharedStaticDtorDeclaration isSharedStaticDtorDeclaration() { return null; }
-    InvariantDeclaration isInvariantDeclaration() { return null; }
-    UnitTestDeclaration isUnitTestDeclaration() { return null; }
-    NewDeclaration isNewDeclaration() { return null; }
-    VarDeclaration isVarDeclaration() { return null; }
-    ClassDeclaration isClassDeclaration() { return null; }
-    StructDeclaration isStructDeclaration() { return null; }
-    UnionDeclaration isUnionDeclaration() { return null; }
-    InterfaceDeclaration isInterfaceDeclaration() { return null; }
-    ScopeDsymbol isScopeDsymbol() { return null; }
-    WithScopeSymbol isWithScopeSymbol() { return null; }
-    ArrayScopeSymbol isArrayScopeSymbol() { return null; }
-    Import isImport() { return null; }
-    EnumDeclaration isEnumDeclaration() { return null; }
-version (_DH)
-{
-    DeleteDeclaration isDeleteDeclaration() { return null; }
-}
-    SymbolDeclaration isSymbolDeclaration() { return null; }
-    AttribDeclaration isAttribDeclaration() { return null; }
-    OverloadSet isOverloadSet() { return null; }
-version (TARGET_NET)
-{
-    PragmaScope isPragmaScope() { return null; }
-}
+module dmd.Dsymbol;
+
+import dmd.common;
+import dmd.Loc;
+import dmd.STC;
+import dmd.Scope;
+import dmd.Lexer;
+import dmd.Module;
+import dmd.Array;
+import dmd.ScopeDsymbol;
+import dmd.OutBuffer;
+import dmd.Id;
+import dmd.Identifier;
+import dmd.TemplateInstance;
+import dmd.SharedStaticCtorDeclaration;
+import dmd.SharedStaticDtorDeclaration;
+import dmd.HdrGenState;
+import dmd.AggregateDeclaration;
+import dmd.ClassDeclaration;
+import dmd.LabelDsymbol;
+import dmd.Type;
+import dmd.PROT;
+import dmd.ArrayTypes;
+import dmd.Package;
+import dmd.EnumMember;
+import dmd.TemplateDeclaration;
+import dmd.TemplateMixin;
+import dmd.Declaration;
+import dmd.ThisDeclaration;
+import dmd.TupleDeclaration;
+import dmd.TypedefDeclaration;
+import dmd.AliasDeclaration;
+import dmd.FuncDeclaration;
+import dmd.FuncAliasDeclaration;
+import dmd.FuncLiteralDeclaration;
+import dmd.CtorDeclaration;
+import dmd.PostBlitDeclaration;
+import dmd.DtorDeclaration;
+import dmd.StaticCtorDeclaration;
+import dmd.StaticDtorDeclaration;
+import dmd.InvariantDeclaration;
+import dmd.UnitTestDeclaration;
+import dmd.NewDeclaration;
+import dmd.VarDeclaration;
+import dmd.StructDeclaration;
+import dmd.UnionDeclaration;
+import dmd.InterfaceDeclaration;
+import dmd.WithScopeSymbol;
+import dmd.ArrayScopeSymbol;
+import dmd.Import;
+import dmd.EnumDeclaration;
+import dmd.DeleteDeclaration;
+import dmd.SymbolDeclaration;
+import dmd.AttribDeclaration;
+import dmd.OverloadSet;
+import dmd.DYNCAST;
+import dmd.Global;
+import dmd.Expression;
+import dmd.TOK;
+import dmd.VarExp;
+import dmd.FuncExp;
+
+import dmd.backend.Symbol;
+import dmd.backend.TYPE;
+import dmd.backend.Util;
+import dmd.backend.mTYman;
+import dmd.backend.TYFL;
+import dmd.backend.TYM;
+import dmd.backend.mTY;
+import dmd.backend.SC;
+import dmd.backend.FL;
+import dmd.backend.LIST;
+public import dmd.PASS;
+
+import dmd.DDMDExtensions;
+
+import core.stdc.string : strcmp, memcpy, strlen;
+version (Bug4054) import core.memory;
+else import core.stdc.stdlib : alloca;
+
+import std.stdio;
+
+// TODO: remove dependencies on these
+Expression isExpression(Object o)
+{
+    return cast(Expression)o;
+}
+
+Dsymbol isDsymbol(Object o)
+{
+    return cast(Dsymbol)o;
+}
+
+Type isType(Object o)
+{
+    return cast(Type)o;
+}
+
+/***********************
+ * Try to get arg as a type.
+ */
+
+Type getType(Object o)
+{
+    Type t = isType(o);
+    if (!t)
+    {   Expression e = isExpression(o);
+	if (e)
+	    t = e.type;
+    }
+    return t;
+}
+
+
+Dsymbol getDsymbol(Object oarg)
+{
+	Dsymbol sa;
+    Expression ea = isExpression(oarg);
+    if (ea)
+    {   // Try to convert Expression to symbol
+		if (ea.op == TOK.TOKvar)
+			sa = (cast(VarExp)ea).var;
+		else if (ea.op == TOK.TOKfunction)
+			sa = (cast(FuncExp)ea).fd;
+		else
+			sa = null;
+    }
+    else
+    {   // Try to convert Type to symbol
+		Type ta = isType(oarg);
+		if (ta)
+			sa = ta.toDsymbol(null);
+		else
+			sa = isDsymbol(oarg);	// if already a symbol
+    }
+    return sa;
+}
+
+alias Vector!Dsymbol Dsymbols;
+
+import dmd.TObject;
+
+class Dsymbol : TObject
+{
+	mixin insertMemberExtension!(typeof(this));
+	
+    Identifier ident;
+    Identifier c_ident;
+    Dsymbol parent;
+    Symbol* csym;		// symbol for code generator
+    Symbol* isym;		// import version of csym
+    string comment;	// documentation comment for this Dsymbol
+    Loc loc;			// where defined
+    Scope scope_;		// !=null means context to use for semantic()
+
+    this()
+	{
+		register();
+		// do nothing
+	}
+	
+    this(Identifier ident)
+	{
+		register();
+		this.ident = ident;
+	}
+
+    string toChars()
+	{
+		return ident ? ident.toChars() : "__anonymous";
+	}
+
+    string locToChars()
+	{
+		scope OutBuffer buf = new OutBuffer();
+		Module m = getModule();
+
+		if (m && m.srcfile)
+			loc.filename = m.srcfile.toChars();
+
+		return loc.toChars();
+	}
+
+    bool equals(Object o)
+	{
+		Dsymbol s;
+
+		if (this is o)
+			return true;
+			
+		s = cast(Dsymbol)(o);
+		if (s && ident.equals(s.ident))
+			return true;
+
+		return false;
+	}
+
+    bool isAnonymous()
+	{
+		return ident ? 0 : 1;
+	}
+
+    void error(T...)(Loc loc, string format, T t)
+	{
+		if (!global.gag)
+		{
+			string p = loc.toChars();
+			if (p.length == 0)
+				p = locToChars();
+
+			if (p.length != 0) {
+				writef("%s: ", p);
+			}
+
+			write("Error: ");
+			writef("%s %s ", kind(), toPrettyChars());
+
+			writefln(format, t);
+		}
+
+		global.errors++;
+		
+		//fatal();
+	}
+
+    void error(T...)(string format, T t)
+	{
+		//printf("Dsymbol.error()\n");
+		if (!global.gag)
+		{
+			string p = loc.toChars();
+
+			if (p.length != 0) {
+				writef("%s: ", p);
+			}
+
+			write("Error: ");
+			if (isAnonymous()) {
+				writef("%s ", kind());
+			} else {
+				writef("%s %s ", kind(), toPrettyChars());
+			}
+
+			writefln(format, t);
+		}
+		global.errors++;
+
+		//fatal();
+	}
+
+    void checkDeprecated(Loc loc, Scope sc)
+	{
+		if (!global.params.useDeprecated && isDeprecated())
+		{
+			// Don't complain if we're inside a deprecated symbol's scope
+			for (Dsymbol sp = sc.parent; sp; sp = sp.parent)
+			{   
+				if (sp.isDeprecated())
+					goto L1;
+			}
+
+			for (; sc; sc = sc.enclosing)
+			{
+				if (sc.scopesym && sc.scopesym.isDeprecated())
+					goto L1;
+
+				// If inside a StorageClassDeclaration that is deprecated
+				if (sc.stc & STC.STCdeprecated)
+					goto L1;
+			}
+
+			error(loc, "is deprecated");
+		}
+		
+	L1:
+		Declaration d = isDeclaration();
+		if (d && d.storage_class & STCdisable)
+		{
+			if (!(sc.func && sc.func.storage_class & STCdisable))
+			{
+				if (d.ident == Id.cpctor && d.toParent())
+					d.toParent().error(loc, "is not copyable");
+				else
+					error(loc, "is not callable");
+			}
+		}
+	}
+	
+    Module getModule()
+	{
+		//printf("Dsymbol.getModule()\n");
+		Dsymbol s = this;
+		while (s)
+		{
+			//printf("\ts = '%s'\n", s.toChars());
+			Module m = s.isModule();
+			if (m)
+				return m;
+			s = s.parent;
+		}
+
+		return null;
+	}
+	
+    Dsymbol pastMixin()
+	{
+		 Dsymbol s = this;
+		//printf("Dsymbol::pastMixin() %s\n", toChars());
+		while (s && s.isTemplateMixin())
+			s = s.parent;
+		return s;
+	}
+	
+    Dsymbol toParent()
+	{
+		return parent ? parent.pastMixin() : null;
+	}
+
+	/**********************************
+	 * Use this instead of toParent() when looking for the
+	 * 'this' pointer of the enclosing function/class.
+	 */
+    Dsymbol toParent2()
+	{
+		Dsymbol s = parent;
+		while (s && s.isTemplateInstance())
+			s = s.parent;
+		return s;
+	}
+	
+    TemplateInstance inTemplateInstance()
+	{
+		for (Dsymbol parent = this.parent; parent; parent = parent.parent)
+		{
+			TemplateInstance ti = parent.isTemplateInstance();
+			if (ti)
+				return ti;
+		}
+
+		return null;
+	}
+
+    DYNCAST dyncast() { return DYNCAST.DYNCAST_DSYMBOL; }	// kludge for template.isSymbol()
+
+	/*************************************
+	 * Do syntax copy of an array of Dsymbol's.
+	 */
+    static Vector!Dsymbol arraySyntaxCopy(Vector!Dsymbol a)
+	{
+		Vector!Dsymbol b = null;
+		if (a)
+		{
+			b = a.copy();
+			for (int i = 0; i < b.dim; i++)
+			{
+				auto s = b[i];
+
+				s = s.syntaxCopy(null);
+				b[i] = s;
+			}
+		}
+		return b;
+	}
+
+    string toPrettyChars()
+	{
+		//printf("Dsymbol.toPrettyChars() '%s'\n", toChars());
+		if (!parent) {
+			return toChars();
+		}
+
+		size_t len = 0;
+		for (Dsymbol p = this; p; p = p.parent) {
+			len += p.toChars().length + 1;
+		}
+		--len;
+
+version (Bug4054)
+		char* s = cast(char*)GC.malloc(len);
+else
+		char* s = cast(char*)alloca(len);
+		char* q = s + len;
+
+		for (Dsymbol p = this; p; p = p.parent)
+		{
+			string t = p.toChars();
+			size_t length = t.length;
+			q -= length;
+
+			memcpy(q, t.ptr, length);
+			if (q is s)
+				break;
+			
+			q--;
+	version (TARGET_NET) {
+			if (AggregateDeclaration ad = p.isAggregateDeclaration())
+			{
+				if (ad.isNested() && p.parent && p.parent.isAggregateDeclaration())
+				{
+					*q = '/';
+					continue;
+				}
+			}
+	}
+			*q = '.';
+		}
+
+		return s[0..len].idup;
+	}
+	
+    string kind()
+	{
+		assert(false);
+	}
+	
+	/*********************************
+	 * If this symbol is really an alias for another,
+	 * return that other.
+	 */
+    Dsymbol toAlias()			// resolve real symbol
+	{
+		return this;
+	}
+	
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
+	{
+		//printf("Dsymbol.addMember('%s')\n", toChars());
+		//printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars());
+		assert(sd !is null);
+		parent = sd;
+		if (!isAnonymous())		// no name, so can't add it to symbol table
+		{
+			if (!sd.symtabInsert(this))	// if name is already defined
+			{
+				Dsymbol s2 = sd.symtab.lookup(ident);
+				if (!s2.overloadInsert(this))
+				{
+					sd.multiplyDefined(Loc(0), this, s2);
+				}
+			}
+			if (sd.isAggregateDeclaration() || sd.isEnumDeclaration())
+			{
+				if (ident is Id.__sizeof || ident is Id.alignof_ || ident is Id.mangleof_)
+					error(".%s property cannot be redefined", ident.toChars());
+			}
+			return true;
+		}
+
+		return false;
+	}
+	
+    void setScope(Scope sc)
+	{
+		//printf("Dsymbol.setScope() %p %s\n", this, toChars());
+		if (!sc.nofree)
+			sc.setNoFree();		// may need it even after semantic() finishes
+		scope_ = sc;
+	}
+    
+    void importAll(Scope sc)
+    {
+    }
+	
+    void semantic(Scope sc)
+	{
+    	error("%p has no semantic routine", this);
+	}
+	
+	/*************************************
+	 * Does semantic analysis on initializers and members of aggregates.
+	 */
+    void semantic2(Scope sc)
+	{
+		// Most Dsymbols have no further semantic analysis needed
+	}
+
+	/*************************************
+	 * Does semantic analysis on function bodies.
+	 */	
+    void semantic3(Scope sc)
+	{
+		// Most Dsymbols have no further semantic analysis needed
+	}
+	
+	/*************************************
+	 * Look for function inlining possibilities.
+	 */
+    void inlineScan()
+	{
+		// Most Dsymbols aren't functions
+	}
+	
+	/*********************************************
+	 * Search for ident as member of s.
+	 * Input:
+	 *	flags:	1	don't find private members
+	 *		2	don't give error messages
+	 *		4	return null if ambiguous
+	 * Returns:
+	 *	null if not found
+	 */
+    Dsymbol search(Loc loc, Identifier ident, int flags)
+	{
+		//printf("Dsymbol.search(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
+		return null;
+	}
+	
+	/***************************************
+	 * Search for identifier id as a member of 'this'.
+	 * id may be a template instance.
+	 * Returns:
+	 *	symbol found, null if not
+	 */
+    Dsymbol searchX(Loc loc, Scope sc, Object o)
+	{
+		//printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars());
+		Dsymbol s = toAlias();
+		Dsymbol sm;
+
+		if (auto ident = cast(Identifier)o)
+		{
+			sm = s.search(loc, ident, 0);
+		}
+		else if (auto st = cast(Dsymbol)o)
+		{
+			// It's a template instance
+			//printf("\ttemplate instance id\n");
+			TemplateInstance ti = st.isTemplateInstance();
+			Identifier id = ti.name;
+			sm = s.search(loc, cast(Identifier)id, 0);
+			if (!sm)
+			{   
+				error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.toChars());
+				return null;
+			}
+			sm = sm.toAlias();
+			TemplateDeclaration td = sm.isTemplateDeclaration();
+			if (!td)
+			{
+				error("%s is not a template, it is a %s", id.toChars(), sm.kind());
+				return null;
+			}
+
+			ti.tempdecl = td;
+			if (!ti.semanticRun)
+				ti.semantic(sc);
+
+			sm = ti.toAlias();
+		}
+		else
+		{
+			assert(0);
+		}
+		return sm;
+	}
+	
+    bool overloadInsert(Dsymbol s)
+	{
+		assert(false);
+	}
+	
+version (_DH)
+{
+    char* toHChars()
+	{
+		assert(false);
+	}
+	
+    void toHBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+}
+    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+	
+    void toDocBuffer(OutBuffer buf)
+	{
+		assert(false);
+	}
+    
+    void toJsonBuffer(OutBuffer buf)
+    {
+    }
+	
+    uint size(Loc loc)
+	{
+		assert(false);
+	}
+
+    int isforwardRef()
+	{
+		assert(false);
+	}
+	
+    void defineRef(Dsymbol s)
+	{
+		assert(false);
+	}
+	
+    AggregateDeclaration isThis()	// is a 'this' required to access the member
+	{
+		return null;
+	}
+	
+    ClassDeclaration isClassMember()	// are we a member of a class?
+	{
+		Dsymbol parent = toParent();
+		if (parent && parent.isClassDeclaration())
+			return cast(ClassDeclaration)parent;
+		return null;
+	}
+	
+    bool isExport()			// is Dsymbol exported?
+	{
+		return false;
+	}
+	
+    bool isImportedSymbol()		// is Dsymbol imported?
+	{
+		return false;
+	}
+	
+    bool isDeprecated()			// is Dsymbol deprecated?
+	{
+		return false;
+	}
+
+version (DMDV2) {
+    bool isOverloadable()
+	{
+		return false;
+	}
+}
+
+    LabelDsymbol isLabel()		// is this a LabelDsymbol?
+	{
+		return null;
+	}
+	
+    AggregateDeclaration isMember()	// is this symbol a member of an AggregateDeclaration?
+	{
+		//printf("Dsymbol::isMember() %s\n", toChars());
+		Dsymbol parent = toParent();
+		//printf("parent is %s %s\n", parent.kind(), parent.toChars());
+		return parent ? parent.isAggregateDeclaration() : null;
+	}
+
+    Type getType()			// is this a type?
+	{
+		return null;
+	}
+	
+    string mangle()
+	{
+		OutBuffer buf = new OutBuffer();
+		string id;
+
+static if (false) {
+		printf("Dsymbol::mangle() '%s'", toChars());
+		if (parent)
+			printf("  parent = %s %s", parent.kind(), parent.toChars());
+		printf("\n");
+}
+		id = ident ? ident.toChars() : toChars();
+		if (parent)
+		{
+			string p = parent.mangle();
+			if (p[0] == '_' && p[1] == 'D')
+				p =  p[2..$];
+			buf.writestring(p);
+		}
+		///buf.printf("%zu%s", id.length, id);
+		buf.printf("%d%s", id.length, id);
+		id = buf.toChars();
+		buf.data = null;
+		//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
+		return id;
+	}
+
+    bool needThis()			// need a 'this' pointer?
+	{
+		return false;
+	}
+
+    PROT prot()
+	{
+		assert(false);
+	}
+
+    Dsymbol syntaxCopy(Dsymbol s)	// copy only syntax trees
+	{
+		assert(false);
+	}
+
+	/**************************************
+	 * Determine if this symbol is only one.
+	 * Returns:
+	 *	false, *ps = null: There are 2 or more symbols
+	 *	true,  *ps = null: There are zero symbols
+	 *	true,  *ps = symbol: The one and only one symbol
+	 */
+    bool oneMember(Dsymbol* ps)
+	{
+		//printf("Dsymbol::oneMember()\n");
+		*ps = this;
+		return true;
+	}
+
+	/*****************************************
+	 * Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
+	 */
+    static bool oneMembers(Dsymbols members, Dsymbol* ps)
+	{
+		//printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0);
+		Dsymbol s = null;
+
+		if (members)
+		{
+			foreach(sx; members)
+			{   
+				bool x = sx.oneMember(ps);
+				//printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps);
+				if (!x)
+				{
+					//printf("\tfalse 1\n");
+					assert(*ps is null);
+					return false;
+				}
+				if (*ps)
+				{
+					if (s)			// more than one symbol
+					{   
+						*ps = null;
+						//printf("\tfalse 2\n");
+						return false;
+					}
+					s = *ps;
+				}
+			}
+		}
+
+		*ps = s;		// s is the one symbol, null if none
+		//printf("\ttrue\n");
+		return true;
+	}
+	
+	/*****************************************
+	 * Is Dsymbol a variable that contains pointers?
+	 */
+    bool hasPointers()
+	{
+		//printf("Dsymbol::hasPointers() %s\n", toChars());
+		return 0;
+	}
+
+    void addLocalClass(ClassDeclarations) { }
+    void checkCtorConstInit() { }
+
+    // since comment is stored immutable string is correct here
+    void addComment(string comment)
+	{
+		//if (comment)
+			//writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
+
+		if (this.comment is null)
+		{
+			this.comment = comment;
+		}
+		else
+		{
+static if (true)
+{
+			if (comment !is null && comment != this.comment)
+			{	// Concatenate the two
+				this.comment = Lexer.combineComments(this.comment, comment);
+			}
+}
+		}
+	}
+	
+    void emitComment(Scope sc)
+	{
+		assert(false);
+	}
+	
+    void emitDitto(Scope sc)
+	{
+		assert(false);
+	}
+
+    // Backend
+
+    Symbol* toSymbol()			// to backend symbol
+	{
+		assert(false);
+	}
+	
+    void toObjFile(int multiobj)			// compile to .obj file
+	{
+		//printf("Dsymbol::toObjFile('%s')\n", toChars());
+		// ignore
+	}
+	
+    int cvMember(ubyte* p)	// emit cv debug info for member
+	{
+		assert(false);
+	}
+
+	/*********************************
+	 * Generate import symbol from symbol.
+	 */
+    Symbol* toImport()				// to backend import symbol
+	{
+		if (!isym)
+		{
+			if (!csym)
+				csym = toSymbol();
+			isym = toImport(csym);
+		}
+
+		return isym;
+	}
+	
+    static Symbol* toImport(Symbol* sym)		// to backend import symbol
+	{
+		char* id;
+		char* n;
+		Symbol* s;
+		type* t;
+
+		//printf("Dsymbol::toImport('%s')\n", sym->Sident);
+		n = sym.Sident.ptr;
+version (Bug4054)
+		id = cast(char*) GC.malloc(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1);
+else
+		id = cast(char*) alloca(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1);
+		if (sym.Stype.Tmangle == mTYman_std && tyfunc(sym.Stype.Tty))
+		{
+			sprintf(id, "_imp__%s@%lu", n, type_paramsize_i(sym.Stype));
+		}
+		else if (sym.Stype.Tmangle == mTYman_d)
+			sprintf(id,"_imp_%s",n);
+		else
+			sprintf(id,"_imp__%s",n);
+		t = type_alloc(TYnptr | mTYconst);
+		t.Tnext = sym.Stype;
+		t.Tnext.Tcount++;
+		t.Tmangle = mTYman_c;
+		t.Tcount++;
+		s = symbol_calloc(id);
+		s.Stype = t;
+		s.Sclass = SCextern;
+		s.Sfl = FLextern;
+		slist_add(s);
+
+		return s;
+	}
+
+    Symbol* toSymbolX(string prefix, int sclass, TYPE* t, string suffix)	// helper
+	{
+		Symbol* s;
+		char* id;
+		string n;
+		size_t nlen;
+
+		//writef("Dsymbol::toSymbolX('%s', '%s')\n", prefix, this.classinfo.name);
+		n = mangle();
+		assert(n.length != 0);
+
+		nlen = n.length;
+static if (false) {
+		if (nlen > 2 && n[0] == '_' && n[1] == 'D')
+		{
+			nlen -= 2;
+			n += 2;
+		}
+}
+		version (Bug4054)
+		id = cast(char*) GC.malloc(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1);
+		else
+		id = cast(char*) alloca(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1);
+	    sprintf(id, "_D%.*s%zu%.*s%.*s", n, prefix.length, prefix, suffix);
+		
+	static if (false) {
+		if (global.params.isWindows && (type_mangle(t) == mTYman.mTYman_c || type_mangle(t) == mTYman.mTYman_std))
+			id++;			// Windows C mangling will put the '_' back in
+	}
+		s = symbol_name(id, sclass, t);
+		
+		//printf("-Dsymbol::toSymbolX() %s\n", id);
+		return s;
+	}
+
+    // Eliminate need for dynamic_cast
+    Package isPackage() { return null; }
+    Module isModule() { return null; }
+    EnumMember isEnumMember() { return null; }
+    TemplateDeclaration isTemplateDeclaration() { return null; }
+    TemplateInstance isTemplateInstance() { return null; }
+    TemplateMixin isTemplateMixin() { return null; }
+    Declaration isDeclaration() { return null; }
+    ThisDeclaration isThisDeclaration() { return null; }
+    TupleDeclaration isTupleDeclaration() { return null; }
+    TypedefDeclaration isTypedefDeclaration() { return null; }
+    AliasDeclaration isAliasDeclaration() { return null; }
+    AggregateDeclaration isAggregateDeclaration() { return null; }
+    FuncDeclaration isFuncDeclaration() { return null; }
+    FuncAliasDeclaration isFuncAliasDeclaration() { return null; }
+    FuncLiteralDeclaration isFuncLiteralDeclaration() { return null; }
+    CtorDeclaration isCtorDeclaration() { return null; }
+    PostBlitDeclaration isPostBlitDeclaration() { return null; }
+    DtorDeclaration isDtorDeclaration() { return null; }
+    StaticCtorDeclaration isStaticCtorDeclaration() { return null; }
+    StaticDtorDeclaration isStaticDtorDeclaration() { return null; }
+    SharedStaticCtorDeclaration isSharedStaticCtorDeclaration() { return null; }
+    SharedStaticDtorDeclaration isSharedStaticDtorDeclaration() { return null; }
+    InvariantDeclaration isInvariantDeclaration() { return null; }
+    UnitTestDeclaration isUnitTestDeclaration() { return null; }
+    NewDeclaration isNewDeclaration() { return null; }
+    VarDeclaration isVarDeclaration() { return null; }
+    ClassDeclaration isClassDeclaration() { return null; }
+    StructDeclaration isStructDeclaration() { return null; }
+    UnionDeclaration isUnionDeclaration() { return null; }
+    InterfaceDeclaration isInterfaceDeclaration() { return null; }
+    ScopeDsymbol isScopeDsymbol() { return null; }
+    WithScopeSymbol isWithScopeSymbol() { return null; }
+    ArrayScopeSymbol isArrayScopeSymbol() { return null; }
+    Import isImport() { return null; }
+    EnumDeclaration isEnumDeclaration() { return null; }
+version (_DH)
+{
+    DeleteDeclaration isDeleteDeclaration() { return null; }
+}
+    SymbolDeclaration isSymbolDeclaration() { return null; }
+    AttribDeclaration isAttribDeclaration() { return null; }
+    OverloadSet isOverloadSet() { return null; }
+version (TARGET_NET)
+{
+    PragmaScope isPragmaScope() { return null; }
+}
 }
\ No newline at end of file