# HG changeset patch # User Anders Halager # Date 1214073678 -7200 # Node ID ed815b31479bb4c60d169e152979fea7f83be19c # Parent 7264c61088c43bf1b45f77e36b71b0fc49e6ad4f Added a Symbol diff -r 7264c61088c4 -r ed815b31479b ast/Decl.d --- a/ast/Decl.d Sat Jun 21 17:32:27 2008 +0200 +++ b/ast/Decl.d Sat Jun 21 20:41:18 2008 +0200 @@ -8,6 +8,7 @@ import tango.io.Stdout; import sema.Scope, + sema.Symbol, sema.DType, basic.SmallArray, basic.Attribute; @@ -15,6 +16,7 @@ enum DeclType { VarDecl, + DummyDecl, ImportDecl, FuncDecl, StructDecl, @@ -31,13 +33,27 @@ { } - DType type() { return null; } + DType type() + { + if (sym !is null) + return sym.type; + return null; + } DeclType declType; Scope env; + Symbol sym; Attribute att; } +class DummyDecl : Decl +{ + this() + { + super(DeclType.DummyDecl); + } +} + class VarDecl : Decl { this(Identifier type, Identifier identifier, @@ -55,7 +71,7 @@ override DType type() { - return env.find(identifier).type; + return env.findType(varType); } Identifier varType, identifier; @@ -109,7 +125,8 @@ void simplify() { - if(auto t = cast(DFunction)env.find(identifier).type) + /* + if(auto t = env.find(identifier).type.asFunction()) { if(auto s = cast(DStruct)t.returnType) { @@ -131,6 +148,7 @@ myType = null; } } + */ foreach (funcArg; funcArgs) funcArg.simplify(); diff -r 7264c61088c4 -r ed815b31479b ast/Exp.d --- a/ast/Exp.d Sat Jun 21 17:32:27 2008 +0200 +++ b/ast/Exp.d Sat Jun 21 20:41:18 2008 +0200 @@ -1,6 +1,7 @@ module ast.Exp; -import tango.text.Util; +import tango.text.Util, + Integer = tango.text.convert.Integer; import tango.io.Stdout; import ast.Decl, @@ -9,6 +10,7 @@ import lexer.Token; import sema.Scope, + sema.Symbol, sema.DType; import basic.LiteralParsing; @@ -38,6 +40,23 @@ this.loc = loc; } + /** + Get the fully qualified name for the expression (if it can be resolved to + one) - otherwise null is returned + **/ + char[] getFQN() { return null; } + + /// The same as getFQN, except that the name is mangled + char[] getMangledFQN() { return null; } + + /** + Try to get the symbol the expression represents. + + Returns null for most expressions as they don't represent any symbol. + Identifiers and member references can have a sensible value. + **/ + Symbol getSymbol() { return null; } + /// Get the type of the expression abstract DType type(); @@ -47,6 +66,8 @@ /// The environment of the expression Scope env; + Symbol symbol; + int stmtIndex; /** @@ -96,6 +117,7 @@ Exp simplify() { + /* if(auto t = type.asStruct) { DFunction func_t = cast(DFunction)exp.type(); @@ -134,6 +156,7 @@ return i; } + */ return this; } } @@ -303,7 +326,7 @@ override DType type() { - return exp.type().asPointer.pointerOf; + return exp.type().asPointer().pointerOf; } override SourceRange sourceRange() @@ -370,6 +393,24 @@ this.child = child; } + override char[] getFQN() + { + return getSymbol().getFQN(); + } + + override char[] getMangledFQN() + { + return target.type.mangle() ~ child.getMangledFQN(); + } + + override Symbol getSymbol() + { + auto s = target.getSymbol(); + if (s !is null) + return s.findMember(child.get); + return null; + } + Exp simplify() { target = target.simplify; @@ -535,15 +576,33 @@ super(t, loc); } + override char[] getFQN() + { + return name; + } + + override char[] getMangledFQN() + { + return Integer.toString(name.length) ~ name; + } + + override Symbol getSymbol() + { + if (auto decl = env.find(this)) + return decl.sym; + else + return null; + } + override DType type() { if (myType !is null) return myType; - if(auto s = env.find(this)) - if(s.type) - myType = s.type; + else if (auto sym = getSymbol) + myType = sym.type; else myType = DType.Int; + return myType; } @@ -557,16 +616,6 @@ { return name; } - - char[] getMangled() - { - DType t = type; - - if(name == "main") - return "main"; - - return "_D"~name~t.mangle; - } hash_t toHash() { diff -r 7264c61088c4 -r ed815b31479b ast/Module.d --- a/ast/Module.d Sat Jun 21 17:32:27 2008 +0200 +++ b/ast/Module.d Sat Jun 21 20:41:18 2008 +0200 @@ -1,6 +1,7 @@ module ast.Module; -import sema.Scope; +import sema.Scope, + sema.Symbol; import ast.Decl; @@ -19,4 +20,6 @@ Decl[] decls; char[] moduleName; Scope env; + Symbol symbol; } + diff -r 7264c61088c4 -r ed815b31479b basic/SmallArray.d --- a/basic/SmallArray.d Sat Jun 21 17:32:27 2008 +0200 +++ b/basic/SmallArray.d Sat Jun 21 20:41:18 2008 +0200 @@ -84,6 +84,19 @@ else ptr = array.ptr; } + alias opCatAssign push; + + T pop() + { + assert(len > 0, "Can't remove from an empty array"); + return ptr[--len]; + } + + T peek() + { + assert(len > 0, "Array is empty"); + return ptr[len - 1]; + } size_t length() { return len; } diff -r 7264c61088c4 -r ed815b31479b gen/CodeGen.d --- a/gen/CodeGen.d Sat Jun 21 17:32:27 2008 +0200 +++ b/gen/CodeGen.d Sat Jun 21 20:41:18 2008 +0200 @@ -96,7 +96,7 @@ Type[] param_types; foreach (i, p; fd.funcArgs) { - DType t = p.env.find(p.identifier).type; + DType t = p.identifier.type; if (auto st = t.asStruct()) { Type pointer = PointerType.Get(llvm(st)); @@ -110,20 +110,20 @@ else param_types ~= llvm(t); } - auto ret_t = fd.env.find(fd.identifier).type; + auto ret_t = fd.identifier.type; if(auto st = cast(DStruct)ret_t) ret_t = DType.Void; else if(auto f = cast(DFunction)ret_t) ret_t = f.returnType; auto func_t = FunctionType.Get(llvm(ret_t), param_types); - auto llfunc = m.addFunction(func_t, fd.identifier.getMangled); + auto llfunc = m.addFunction(func_t, fd.sym.getMangledFQN()); foreach (i, p; fd.funcArgs) { if(i == 0 && fd.sret) llfunc.addParamAttr(0, ParamAttr.StructRet); - DType t = p.env.find(p.identifier).type; + DType t = p.identifier.type; if (auto st = t.asStruct) { if (i == 0 && fd.sret) @@ -173,7 +173,7 @@ return; llvm(funcDecl.type); - auto llfunc = m.getNamedFunction(funcDecl.identifier.getMangled); + auto llfunc = m.getNamedFunction(funcDecl.sym.getMangledFQN()); auto func_tp = cast(PointerType)llfunc.type; auto func_t = cast(FunctionType)func_tp.elementType(); auto ret_t = func_t.returnType(); @@ -214,7 +214,7 @@ case DeclType.VarDecl: auto varDecl = cast(VarDecl)decl; - auto id = varDecl.env.find(varDecl.identifier); + auto id = varDecl.identifier; Type t = llvm(id.type); GlobalVariable g = m.addGlobal(t, id.get); g.initializer = ConstantInt.GetS(t, 0); @@ -241,17 +241,21 @@ { case DeclType.VarDecl: auto varDecl = cast(VarDecl)decl; - auto name = varDecl.identifier.get; - auto sym = varDecl.env.find(varDecl.identifier); - auto AI = b.buildAlloca(llvm(sym.type), name); + auto id = varDecl.identifier; + auto name = id.get; + auto AI = b.buildAlloca(llvm(id.type), name); table[name] = AI; if (varDecl.init) { LValue dst = genLValue(varDecl.identifier); RValue src = genExpression(varDecl.init); - storeThroughLValue(dst, src, sym.type); + storeThroughLValue(dst, src, id.type); } break; + + case DeclType.FuncDecl: + genRootDecl(decl); + break; default: } @@ -344,13 +348,20 @@ auto callExp = cast(CallExp)exp; // BUG: Might not be a simple identifier, a.foo(x) is also a // valid call - or foo(x)(y) for that matter. - auto id = exp.env.find(cast(Identifier)callExp.exp); + + // if type of exp is DFunction - safe to call getSymbol and FQN + // if function ptr: do something else + // if delegate do a third thing + // if struct/class check for opCall + DType type = callExp.exp.type; + assert (type.isFunction(), "Can only call functions"); + auto sym = callExp.exp.getSymbol(); scope args = new Value[callExp.args.length]; foreach (i, arg; callExp.args) args[i] = genExpression(arg).value; - llvm(id.type); - auto f = m.getNamedFunction(id.getMangled); - DFunction f_type = cast(DFunction)id.type; + llvm(type); + auto f = m.getNamedFunction(sym.getMangledFQN()); + DFunction f_type = type.asFunction(); bool isVoid = f_type.returnType is DType.Void; // BUG: doesn't do implicit type-conversion on args auto r = b.buildCall(f, args, isVoid? "" : "call"); @@ -366,8 +377,7 @@ return genTypeCast(value, exp.type, castExp.type); case ExpType.Identifier: - auto identifier = cast(Identifier)exp; - auto id = exp.env.find(identifier); + auto id = cast(Identifier)exp; if(id.type.isStruct() || id.type.isArray()) return RValue(table.find(id.get)); else @@ -518,7 +528,7 @@ Value False = ConstantInt.GetS(cond.type, 0); cond = b.buildICmp(IntPredicate.NE, cond, False, ".cond"); } - auto func_name = stmt.env.parentFunction().identifier.getMangled; + auto func_name = symbolName(stmt.env.parentFunction()); Function func = m.getNamedFunction(func_name); bool has_else = (ifStmt.else_body !is null); @@ -546,8 +556,8 @@ break; case StmtType.While: auto wStmt = cast(WhileStmt)stmt; - auto func_name = stmt.env.parentFunction().identifier.get; - Function func = m.getNamedFunction(func_name); + auto fd = stmt.env.parentFunction(); + Function func = m.getNamedFunction(symbolName(fd)); auto condBB = func.appendBasicBlock("cond"); auto bodyBB = func.appendBasicBlock("body"); @@ -632,8 +642,7 @@ switch(exp.expType) { case ExpType.Identifier: - auto identifier = cast(Identifier)exp; - auto id = exp.env.find(identifier); + auto id = cast(Identifier)exp; return LValue(table.find(id.get)); case ExpType.Deref: // LValue(*x): load(x) @@ -663,9 +672,8 @@ switch (mem.target.expType) { case ExpType.Identifier: - auto identifier = cast(Identifier)mem.target; + auto id = cast(Identifier)mem.target; auto child = mem.child; - auto id = exp.env.find(identifier); Value v = table.find(id.get); DType t = id.type; auto st = t.asStruct; @@ -682,11 +690,9 @@ case ExpType.MemberReference: auto addr = genLValue(mem.target).getAddress(); auto child = mem.child; - auto symChild = child.env.find(child); - DType t = mem.target.type; - auto st = t.asStruct; + DStruct t = mem.target.type.asStruct(); - int i = st.indexOf(child.get); + int i = t.indexOf(child.get); Value[2] vals; vals[0] = ZeroIndex; @@ -785,6 +791,12 @@ return RValue(res); } + /// Get the mangled name of a function + char[] symbolName(FuncDecl f) + { + return f.sym.getMangledFQN(); + } + /** Get the LLVM Type corresponding to a DType. @@ -846,13 +858,17 @@ Type res = FunctionType.Get(ret_t, params.unsafe()); type_map[t] = res; + /* + //TODO: create own DType -> FunctionType mapping without names auto id = new Identifier(f.name); id.setType(f); - auto f_t = m.getNamedFunction(id.getMangled); + auto f_name = symbolName(id); + auto f_t = m.getNamedFunction(f_name); if(f_t is null) { - auto llfunc = m.addFunction(res, id.getMangled); + Stdout("oh noes").newline; + auto llfunc = m.addFunction(res, f_name); foreach (i, param; f.params) if (param.isStruct) @@ -864,6 +880,7 @@ llfunc.addParamAttr(0, ParamAttr.StructRet); } } + */ return res; } else if (auto f = t.asPointer) @@ -901,8 +918,8 @@ type_map[DType.Real] = Type.X86_FP80; type_map[DType.Char] = Type.Int8; - type_map[DType.WChar] = Type.Int16; - type_map[DType.DChar] = Type.Int32; + type_map[DType.WChar] = Type.Int16; + type_map[DType.DChar] = Type.Int32; } private: @@ -916,8 +933,6 @@ Type BytePtr; Type[DType] type_map; - FuncDecl[char[]] functions; - SimpleSymbolTable table; } @@ -1009,11 +1024,9 @@ this.dg = dg; } - override void visitModule(DModule m) + override void visitFuncDecl(FuncDecl fd) { - foreach (decl; m.decls) - if (auto f = cast(FuncDecl)decl) - dg(f); + dg(fd); } } diff -r 7264c61088c4 -r ed815b31479b sema/DType.d --- a/sema/DType.d Sat Jun 21 17:32:27 2008 +0200 +++ b/sema/DType.d Sat Jun 21 20:41:18 2008 +0200 @@ -6,6 +6,7 @@ public import sema.Operation; +/// class DType { private char[] id; @@ -154,7 +155,7 @@ { Void = new DType("void"); - Bool = new DInteger("bool", 1, false); + Bool = new DInteger("bool", 1, true); Byte = new DInteger("byte", 8, false); UByte = new DInteger("ubyte", 8, true); Short = new DInteger("short", 16, false); @@ -386,12 +387,14 @@ override char[] mangle() { char[] res; + res ~= "F"; foreach(param ; params) - res ~= "J" ~ param.mangle; + res ~= param.mangle; - res ~= "Z" ~ returnType.mangle; + res ~= "Z"; + res ~= returnType.mangle; return res; } diff -r 7264c61088c4 -r ed815b31479b sema/Operation.d --- a/sema/Operation.d Sat Jun 21 17:32:27 2008 +0200 +++ b/sema/Operation.d Sat Jun 21 20:41:18 2008 +0200 @@ -21,7 +21,8 @@ { Add, Sub, Mul, SDiv, UDiv, FDiv, SRem, URem, FRem, - Shl, LShr, AShr, + // FShr is a dummy element to avoid special case for signed >> unsigned + Shl, LShr, AShr, FShr, And, Or, Xor, Eq, Ne, diff -r 7264c61088c4 -r ed815b31479b sema/Scope.d --- a/sema/Scope.d Sat Jun 21 17:32:27 2008 +0200 +++ b/sema/Scope.d Sat Jun 21 20:41:18 2008 +0200 @@ -8,7 +8,8 @@ ast.Exp; public -import sema.DType; +import sema.DType, + sema.Symbol; class Scope { @@ -28,24 +29,23 @@ ImportDecl[] imports; - - void add(Identifier id) + void put(Identifier id, Decl d) { - symbols[id] = id; + symbols[id] = d; } - Identifier find(Identifier id) + Decl find(Identifier id) { if(id is null) return null; - if (auto sym = id in symbols) + else if (auto sym = id in symbols) return *sym; - if (enclosing !is null) + else if (enclosing !is null) { - auto type = enclosing.find(id); - if(type is null) + auto res = enclosing.find(id); + if (res is null) return mHandle.find(getImports, id); - return type; + return res; } return null; } @@ -60,7 +60,7 @@ DType findType(Identifier id) { if (auto type = id.get in types) - return *type; + return *type; if (enclosing !is null) { auto type = enclosing.findType(id); @@ -71,6 +71,7 @@ return null; } + /* char[][] names() { char[][] res; @@ -82,6 +83,7 @@ res ~= sym.name ~ " : " ~ (sym.type is null? "?" : sym.type.name); return res; } + */ FuncDecl parentFunction() { @@ -123,7 +125,7 @@ DType[char[]] types; int currentStmtIndex = -1; private: - Identifier[Identifier] symbols; + Decl[Identifier] symbols; FuncDecl func; } @@ -151,7 +153,7 @@ return null; } - Identifier find(ImportDecl[] imports, Identifier id) + Decl find(ImportDecl[] imports, Identifier id) { foreach(i ; imports) if(i.get in modules) diff -r 7264c61088c4 -r ed815b31479b sema/ScopeBuilder.d --- a/sema/ScopeBuilder.d Sat Jun 21 17:32:27 2008 +0200 +++ b/sema/ScopeBuilder.d Sat Jun 21 20:41:18 2008 +0200 @@ -4,7 +4,8 @@ tango.core.Array : find; public -import sema.Scope; +import sema.Scope, + sema.Symbol; import sema.Visitor, basic.SmallArray; @@ -14,19 +15,31 @@ override void visit(Module[] modules) { this.modules = modules; - super.visit(modules); + inFunctionBodyStack.push(false); + foreach (mod; modules) + { + current = mod; + foreach (decl; mod.decls) + visitDecl(decl); + } } override void visitFuncDecl(FuncDecl d) { + visitExp(d.returnType); visitExp(d.identifier); foreach (arg; d.funcArgs) visitDecl(arg); + + inFunctionBodyStack.push(true); + foreach (stmt; d.statements) visitStmt(stmt); - d.env.find(d.identifier).setType(d.type); + inFunctionBodyStack.pop(); + + d.sym = current.symbol.createMember(d.identifier.get, d.type); } override void visitVarDecl(VarDecl d) @@ -37,35 +50,68 @@ if (d.init) visitExp(d.init); - d.env.find(d.identifier).setType( typeOf(d.varType, d.env) ); + DType t = typeOf(d.varType, d.env); + /* + if (inFunctionBodyStack.peek()) + { + Stdout.formatln("?? {}, {}, {}", d.varType.get, d.identifier.get, t); + auto find = d.env.find(d.varType); + d.sym = d.env.find(d.varType).sym; + } + else + */ + d.sym = current.symbol.createMember(d.identifier.get, t); } override void visitStructDecl(StructDecl s) { - super.visitStructDecl(s); + auto st = s.env.findType(s.identifier).asStruct; + s.sym = current.symbol.createMember(s.identifier.get, st); + //s.env.set(s.identifier, s); - DType[char[]] types; + auto old = current.symbol; + current.symbol = s.sym; + inFunctionBodyStack.push(false); + super.visitStructDecl(s); + inFunctionBodyStack.pop(); + current.symbol = old; - auto st = s.env.types[s.identifier.get].asStruct; foreach (decl; s.decls) + { + DType type; + char[] name; if (auto varDecl = cast(VarDecl)decl) - st.addMember(typeOf(varDecl.varType, varDecl.env), varDecl.identifier.get); + { + type = typeOf(varDecl.varType, varDecl.env); + name = varDecl.identifier.get; + } else if (auto fd = cast(FuncDecl)decl) - st.addMember(fd.type, fd.identifier.get); + { + type = fd.type; + name = fd.identifier.get; + } + st.addMember(type, name); + } } DType typeOf(Identifier id, Scope sc) { if(auto i = cast(PointerIdentifier)id) return (typeOf(i.pointerOf, sc)).getPointerTo(); - if(auto i = cast(ArrayIdentifier)id) + else if(auto i = cast(ArrayIdentifier)id) return typeOf(i.arrayOf, sc).getAsArray(i.size); return sc.findType(id); } Module[] modules; + Module current; + SmallArray!(bool) inFunctionBodyStack; } +/** + Add scopes to everything, and add all identifiers that correspond to types. + Types/Symbols are added by ForwardReference. + **/ class ScopeBuilder : Visitor!(void) { static ModuleHandler mHandle; @@ -89,26 +135,43 @@ fr.visit(modules); } + private void registerBasicTypeTo(char[] n, DType t, Scope sc, Module m) + { + sc.types[n] = t; + auto sym = m.symbol.createMember(n, t); + auto id = new Identifier(n); + id.env = sc; + auto decl = new DummyDecl(); + decl.sym = sym; + decl.env = sc; + sc.put(id, decl); + } + override void visitModule(Module m) { - table ~= new Scope; - table[table.length-1].types["void"] = DType.Void; - table[table.length-1].types["bool"] = DType.Bool; - table[table.length-1].types["byte"] = DType.Byte; - table[table.length-1].types["ubyte"] = DType.UByte; - table[table.length-1].types["short"] = DType.Short; - table[table.length-1].types["ushort"] = DType.UShort; - table[table.length-1].types["int"] = DType.Int; - table[table.length-1].types["uint"] = DType.UInt; - table[table.length-1].types["long"] = DType.Long; - table[table.length-1].types["ulong"] = DType.ULong; - table[table.length-1].types["char"] = DType.Char; - table[table.length-1].types["wchar"] = DType.WChar; - table[table.length-1].types["dchar"] = DType.DChar; + auto root = new Scope; + table ~= root; + + m.symbol = new Symbol; - table[table.length-1].types["float"] = DType.Float; - table[table.length-1].types["double"] = DType.Double; - table[table.length-1].types["real"] = DType.Real; + registerBasicTypeTo("void", DType.Void, root, m); + registerBasicTypeTo("bool", DType.Bool, root, m); + registerBasicTypeTo("byte", DType.Byte, root, m); + registerBasicTypeTo("ubyte", DType.UByte, root, m); + registerBasicTypeTo("short", DType.Short, root, m); + registerBasicTypeTo("ushort", DType.UShort, root, m); + registerBasicTypeTo("int", DType.Int, root, m); + registerBasicTypeTo("uint", DType.UInt, root, m); + registerBasicTypeTo("long", DType.Long, root, m); + registerBasicTypeTo("ulong", DType.ULong, root, m); + + registerBasicTypeTo("char", DType.Char, root, m); + registerBasicTypeTo("wchar", DType.WChar, root, m); + registerBasicTypeTo("dchar", DType.DChar, root, m); + + registerBasicTypeTo("float", DType.Float, root, m); + registerBasicTypeTo("double", DType.Double, root, m); + registerBasicTypeTo("real", DType.Real, root, m); current().inModule = m; current().mHandle = mHandle; @@ -145,7 +208,7 @@ override void visitFuncDecl(FuncDecl d) { - current().add(d.identifier); + current().put(d.identifier, d); auto sc = push(); visitExp(d.returnType); @@ -173,7 +236,7 @@ } auto sc = current(); - sc.add(d.identifier); + sc.put(d.identifier, d); d.env = sc; visitExp(d.varType); visitExp(d.identifier); @@ -182,10 +245,10 @@ override void visitStructDecl(StructDecl s) { auto sc = current(); - sc.add(s.identifier); + sc.put(s.identifier, s); s.env = sc; auto type = new DStruct(s.identifier); - + sc.types[s.identifier.get] = type; sc = push(); diff -r 7264c61088c4 -r ed815b31479b sema/Symbol.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/Symbol.d Sat Jun 21 20:41:18 2008 +0200 @@ -0,0 +1,133 @@ +module sema.Symbol; + +import tango.text.convert.Integer : format; +import tango.io.Stdout; + +import sema.DType; + +/// +class Symbol +{ + /// Create a root symbol - representing a module + this() { actual = this; } + + /// Get a simple human readable name (bar) + char[] getName() { return name; } + + /// Get a human readable name (foo.bar) + char[] getFQN() + { + char[] prefix; + if (parent !is null && parent.name !is null) + prefix ~= parent.getFQN() ~ "."; + return prefix ~ name; + } + + /// Get a machine readable name (_D3foo3barFZi) + char[] getMangledFQN() + { + char[] n = `_D`; + Symbol p = parent; + while (p !is null) { + n ~= p.internalFQN(); + p = p.parent; + } + n ~= internalFQN(); + n ~= type.mangle(); + return n; + } + + /** + Try to find a contained symbol with the given name - returns null if not + found + **/ + Symbol findMember(char[] member) + { + Stdout.formatln("Trying to find {} in {}", member, name); + foreach (possible; contained) + if (possible.name == member) + { + Stdout.formatln(" - found it: {} ({})", possible.getFQN(), possible.getMangledFQN()); + return possible; + } + return null; + } + + void dump() + { + Stdout("Symbol: "); + Symbol p = parent; + while (p !is null) { + Stdout.format("{}.", p.name); + p = p.parent; + } + Stdout.formatln("{}", name); + } + + /// Create a member with the given name and type + Symbol createMember(char[] member, DType type) + { + //Stdout.formatln("Creating {} of type {} in {}", member, type.mangle, name); + auto res = new Symbol(member, type, this); + contained ~= res; + return res; + } + + /** + Create an alias of another symbol with the given name. + + The target symbol can be a member of another symbol + **/ + Symbol createAlias(char[] aliasedName, Symbol target) + { + auto res = new Symbol(aliasedName, target, this); + contained ~= res; + return res; + } + + // The type of this symbol + DType type; + +private: + // Helper for getMangledFQN - gets the FQN without _D and the type + char[] internalFQN() + { + if (actual.name !is null && actual.name.length > 0) + { + char[32] len; + return format(len, actual.name.length) ~ actual.name; + } + return ""; + } + + this(char[] name, Symbol actual, Symbol parent) + { + this.name = name; + this.actual = actual; + this.parent = parent; + this.type = actual.type; + } + + this(char[] name, DType type, Symbol parent) + { + this.name = name; + this.actual = this; + this.parent = parent; + this.type = type; + } + +private: + char[] name; + + // If the symbol is an alias, this will point to the actual symbol + Symbol actual; + // If this symbol is contained within a struct or similar this will point + // to that symbol + Symbol parent; + // All the symbols contained within this symbol + Symbol[] contained; + + // The module that contains this symbol (root of the parent-chain) + // DModule mod; +} +