changeset 683:1ae72234db26

Implemented some methods in SemanticPass1. Renamed Symbol.ident to name. Added a constructor to Symbol. Adapted constructors of classes that inherit from Symbol. Added Alias and OverloadSet Symbol classes. Renamed idents and values to names and inits in VariablesDeclaration.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Mon, 21 Jan 2008 17:10:12 +0100
parents 7541c64fc423
children 10b314bf37e3
files trunk/src/dil/SettingsLoader.d trunk/src/dil/ast/Declarations.d trunk/src/dil/ast/DefaultVisitor.d trunk/src/dil/ast/Types.d trunk/src/dil/parser/Parser.d trunk/src/dil/semantic/Module.d trunk/src/dil/semantic/Pass1.d trunk/src/dil/semantic/Scope.d trunk/src/dil/semantic/Symbol.d trunk/src/dil/semantic/Symbols.d trunk/src/dil/translator/German.d trunk/src/main.d
diffstat 12 files changed, 319 insertions(+), 349 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/dil/SettingsLoader.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/SettingsLoader.d	Mon Jan 21 17:10:12 2008 +0100
@@ -30,8 +30,8 @@
     if (v is null)
       continue;
 
-    auto variableName = v.idents[0].str;
-    auto e = v.values[0];
+    auto variableName = v.names[0].str;
+    auto e = v.inits[0];
     if (!e)
       throw new Exception(variableName ~ " variable has no value set.");
 
@@ -82,8 +82,8 @@
     if (v is null)
       continue;
 
-    auto variableName = v.idents[0].str;
-    auto e = v.values[0];
+    auto variableName = v.names[0].str;
+    auto e = v.inits[0];
     if (!e)
       throw new Exception(variableName~" variable in "~filePath~" has no value set.");
 
--- a/trunk/src/dil/ast/Declarations.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/ast/Declarations.d	Mon Jan 21 17:10:12 2008 +0100
@@ -189,6 +189,26 @@
   }
 }
 
+class TemplateDeclaration : Declaration
+{
+  Identifier* name;
+  TemplateParameters tparams;
+  CompoundDeclaration decls;
+  this(Identifier* name, TemplateParameters tparams, CompoundDeclaration decls)
+  {
+    super.hasBody = true;
+    mixin(set_kind);
+    addOptChild(tparams);
+    addChild(decls);
+
+    this.name = name;
+    this.tparams = tparams;
+    this.decls = decls;
+  }
+
+  Template symbol; /// The template symbol for this declaration.
+}
+
 abstract class AggregateDeclaration : Declaration
 {
   Identifier* name;
@@ -361,25 +381,26 @@
 class VariablesDeclaration : Declaration
 {
   TypeNode typeNode;
-  Identifier*[] idents;
-  Expression[] values;
-  LinkageType linkageType;
-  this(TypeNode typeNode, Identifier*[] idents, Expression[] values)
+  Identifier*[] names;
+  Expression[] inits;
+  this(TypeNode typeNode, Identifier*[] names, Expression[] values)
   {
     // No empty arrays allowed. Both arrays must be of same size.
-    assert(idents.length != 0 && idents.length == values.length);
+    assert(names.length != 0 && names.length == inits.length);
     // If no type (in case of AutoDeclaration), first value mustn't be null.
-    assert(typeNode ? 1 : values[0] !is null);
+    assert(typeNode ? 1 : inits[0] !is null);
     mixin(set_kind);
     addOptChild(typeNode);
-    foreach(value; values)
-      addOptChild(value);
+    foreach(init; inits)
+      addOptChild(init);
 
     this.typeNode = typeNode;
-    this.idents = idents;
-    this.values = values;
+    this.names = names;
+    this.inits = inits;
   }
 
+  LinkageType linkageType;
+
   void setLinkageType(LinkageType linkageType)
   {
     this.linkageType = linkageType;
@@ -484,24 +505,6 @@
   }
 }
 
-class TemplateDeclaration : Declaration
-{
-  Identifier* name;
-  TemplateParameters tparams;
-  CompoundDeclaration decls;
-  this(Identifier* name, TemplateParameters tparams, CompoundDeclaration decls)
-  {
-    super.hasBody = true;
-    mixin(set_kind);
-    addOptChild(tparams);
-    addChild(decls);
-
-    this.name = name;
-    this.tparams = tparams;
-    this.decls = decls;
-  }
-}
-
 class NewDeclaration : Declaration
 {
   Parameters params;
--- a/trunk/src/dil/ast/DefaultVisitor.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/ast/DefaultVisitor.d	Mon Jan 21 17:10:12 2008 +0100
@@ -72,8 +72,8 @@
     static if (is(D == VariablesDeclaration))
     {
       d.typeNode && visitT(d.typeNode);
-      foreach(value; d.values)
-        value && visitE(value);
+      foreach(init; d.inits)
+        init && visitE(init);
     }
     static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
       d.decls && visitD(d.decls),
--- a/trunk/src/dil/ast/Types.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/ast/Types.d	Mon Jan 21 17:10:12 2008 +0100
@@ -85,7 +85,7 @@
   }
 }
 
-/// "typeof" "(" Expression ")
+/// "typeof" "(" Expression ")"
 class TypeofType : TypeNode
 {
   Expression e;
--- a/trunk/src/dil/parser/Parser.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/parser/Parser.d	Mon Jan 21 17:10:12 2008 +0100
@@ -34,6 +34,7 @@
   ImportDeclaration[] imports; /// ImportDeclarations in the source text.
 
   // Attributes are evaluated in the parsing phase.
+  // Will probably be moved to class SemanticPass1.
   LinkageType linkageType;
   Protection protection;
   StorageClass storageClass;
--- a/trunk/src/dil/semantic/Module.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/semantic/Module.d	Mon Jan 21 17:10:12 2008 +0100
@@ -39,7 +39,7 @@
 
   this(string filePath, bool isLightweight = false)
   {
-    this.sid = SYM.Module;
+    super(SYM.Module, null, null);
 
     this.filePath = filePath;
     this.isLightweight = isLightweight;
--- a/trunk/src/dil/semantic/Pass1.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/semantic/Pass1.d	Mon Jan 21 17:10:12 2008 +0100
@@ -11,6 +11,7 @@
        dil.ast.Statements,
        dil.ast.Types,
        dil.ast.Parameters;
+import dil.lexer.Identifier;
 import dil.semantic.Symbol,
        dil.semantic.Symbols,
        dil.semantic.Types,
@@ -20,6 +21,8 @@
 import dil.Location;
 import dil.Information;
 import dil.Messages;
+import dil.Enums;
+import dil.CompilerInfo;
 import common;
 
 class SemanticPass1 : Visitor
@@ -27,6 +30,12 @@
   Scope scop; /// The current scope.
   Module modul; /// The module to be semantically checked.
 
+  // Attributes:
+  LinkageType linkageType;
+  Protection protection;
+  StorageClass storageClass;
+  uint alignSize = DEFAULT_ALIGN_SIZE;
+
   this(Module modul)
   {
     this.modul = modul;
@@ -40,7 +49,7 @@
     scop = new Scope();
     scop.symbol = modul; // Set this module as the scope's symbol.
     scop.infoMan = modul.infoMan;
-    visitN(modul.root);
+    visit(modul.root);
   }
 
   void enterScope(ScopeSymbol s)
@@ -53,6 +62,44 @@
     scop = scop.exit();
   }
 
+  /// Insert a symbol into the current scope.
+  void insert(Symbol sym, Identifier* ident)
+  {
+    auto sym2 = scop.symbol.lookup(ident);
+    if (sym2)
+      reportSymbolConflict(sym, sym2, ident);
+    else
+      scop.symbol.insert(sym, ident);
+    // Set the current scope symbol as the parent.
+    sym.parent = scop.symbol;
+  }
+
+  /// Insert a symbol, overloading on the name, into the current scope.
+  void insertOverload(Symbol sym, Identifier* ident)
+  {
+    auto sym2 = scop.symbol.lookup(ident);
+    if (sym2)
+    {
+      if (sym2.isOverloadSet)
+        (cast(OverloadSet)cast(void*)sym2).add(sym);
+      else
+        reportSymbolConflict(sym, sym2, ident);
+    }
+    else
+      // Create a new overload set.
+      scop.symbol.insert(new OverloadSet(ident, sym.node), ident);
+    // Set the current scope symbol as the parent.
+    sym.parent = scop.symbol;
+  }
+
+  /// Report error: new symbol s1 conflicts with existing symbol s2.
+  void reportSymbolConflict(Symbol s1, Symbol s2, Identifier* ident)
+  {
+    auto loc = s2.node.begin.getErrorLocation();
+    auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum);
+    error(s1.node.begin, MSG.DeclConflictsWithDecl, ident.str, locString);
+  }
+
   void error(Token* token, char[] formatMsg, ...)
   {
     auto location = token.getErrorLocation();
@@ -60,9 +107,11 @@
     modul.infoMan ~= new SemanticError(location, msg);
   }
 
+  private alias Declaration D;
+
 override
 {
-  Declaration visit(CompoundDeclaration d)
+  D visit(CompoundDeclaration d)
   {
     foreach (node; d.children)
     {
@@ -72,18 +121,18 @@
     return d;
   }
 
-  Declaration visit(IllegalDeclaration)
+  D visit(IllegalDeclaration)
   { assert(0, "semantic pass on invalid AST"); return null; }
 
-  Declaration visit(EmptyDeclaration ed)
+  D visit(EmptyDeclaration ed)
   { return ed; }
 
-  Declaration visit(ModuleDeclaration)
+  D visit(ModuleDeclaration)
   { return null; }
-  Declaration visit(ImportDeclaration)
+  D visit(ImportDeclaration)
   { return null; }
 
-  Declaration visit(AliasDeclaration ad)
+  D visit(AliasDeclaration ad)
   {
     /+
     decl.semantic(scop); // call semantic() or do SA in if statements?
@@ -99,7 +148,7 @@
     return ad;
   }
 
-  Declaration visit(TypedefDeclaration td)
+  D visit(TypedefDeclaration td)
   {
     /+
     decl.semantic(scop); // call semantic() or do SA in if statements?
@@ -115,52 +164,39 @@
     return td;
   }
 
-  Declaration visit(EnumDeclaration ed)
+  D visit(EnumDeclaration d)
   {
-    /+
     // Create the symbol.
-    symbol = new Enum(name, this);
-    // Type semantics.
-    Type type = Types.Int; // Default to integer.
-    if (baseType)
-      type = baseType.semantic(scop);
-    auto enumType = new EnumType(symbol, type);
-    // Set the base type of the enum symbol.
-    symbol.setType(enumType);
-    if (name)
-    { // Insert named enum into scope.
-      scop.insert(symbol, symbol.ident);
-      // Create new scope.
-      scop = scop.push(symbol);
+    d.symbol = new Enum(d.name, d);
+    if (d.name)
+    { // Declare named enum.
+      insert(d.symbol, d.name);
+      enterScope(d.symbol);
     }
-    // Semantic on members.
-    foreach (member; members)
+    // Declare members.
+    foreach (member; d.members)
     {
-      auto value = member.value;
-      if (value)
-      {
-        // value = value.semantic(scop);
-        // value = value.evaluate();
-      }
-      auto variable = new Variable(StorageClass.Const, LinkageType.None, type, member.name, member);
-      scop.insert(variable, variable.ident);
+      auto variable = new Variable(member.name, protection, storageClass, linkageType, member);
+      insert(variable, variable.name);
     }
-    if (name)
-      scop.pop();
-    +/
-    return ed;
+    if (d.name)
+      exitScope();
+    return d;
   }
 
-  Declaration visit(EnumMemberDeclaration)
+  D visit(EnumMemberDeclaration)
   { return null; }
 
-  Declaration visit(ClassDeclaration d)
+  D visit(ClassDeclaration d)
   {
     if (d.symbol)
       return d;
     d.symbol = new Class(d.name, d);
     // Insert into current scope.
-    scop.insert(d.symbol, d.name);
+    if (d.tparams)
+      insertOverload(d.symbol, d.name);
+    else
+      insert(d.symbol, d.name);
     enterScope(d.symbol);
     // Continue semantic analysis.
     d.decls && visitD(d.decls);
@@ -168,13 +204,16 @@
     return d;
   }
 
-  Declaration visit(InterfaceDeclaration d)
+  D visit(InterfaceDeclaration d)
   {
     if (d.symbol)
       return d;
     d.symbol = new dil.semantic.Symbols.Interface(d.name, d);
     // Insert into current scope.
-    scop.insert(d.symbol, d.name);
+    if (d.tparams)
+      insertOverload(d.symbol, d.name);
+    else
+      insert(d.symbol, d.name);
     enterScope(d.symbol);
     // Continue semantic analysis.
     d.decls && visitD(d.decls);
@@ -182,14 +221,39 @@
     return d;
   }
 
-  Declaration visit(StructDeclaration d)
+  D visit(StructDeclaration d)
   {
     if (d.symbol)
       return d;
     d.symbol = new Struct(d.name, d);
     // Insert into current scope.
     if (d.name)
-      scop.insert(d.symbol, d.name);
+    {
+      if (d.tparams)
+        insertOverload(d.symbol, d.name);
+      else
+        insert(d.symbol, d.name);
+    }
+    enterScope(d.symbol);
+    // Continue semantic analysis.
+    d.decls && visitD(d.decls);
+    exitScope();
+    return d;
+  }
+
+  D visit(UnionDeclaration d)
+  {
+    if (d.symbol)
+      return d;
+    d.symbol = new Union(d.name, d);
+    // Insert into current scope.
+    if (d.name)
+    {
+      if (d.tparams)
+        insertOverload(d.symbol, d.name);
+      else
+        insert(d.symbol, d.name);
+    }
     enterScope(d.symbol);
     // Continue semantic analysis.
     d.decls && visitD(d.decls);
@@ -197,96 +261,109 @@
     return d;
   }
 
-  Declaration visit(UnionDeclaration d)
+  D visit(ConstructorDeclaration)
+  { return null; }
+  D visit(StaticConstructorDeclaration)
+  { return null; }
+  D visit(DestructorDeclaration)
+  { return null; }
+  D visit(StaticDestructorDeclaration)
+  { return null; }
+  D visit(FunctionDeclaration)
+  { return null; }
+
+  D visit(VariablesDeclaration vd)
+  {
+    // Error if we are in an interface.
+    if (scop.isInterface)
+      return error(vd.begin, MSG.InterfaceCantHaveVariables), vd;
+
+    // Insert variable symbols in this declaration into the symbol table.
+    foreach (name; vd.names)
+    {
+      auto variable = new Variable(name, protection, storageClass, linkageType, vd);
+      vd.variables ~= variable;
+      insert(variable, name);
+    }
+    return vd;
+  }
+
+  D visit(InvariantDeclaration)
+  { return null; }
+  D visit(UnittestDeclaration)
+  { return null; }
+  D visit(DebugDeclaration)
+  { return null; }
+  D visit(VersionDeclaration)
+  { return null; }
+
+  D visit(StaticIfDeclaration d)
+  {
+    visitE(d.condition);
+    visitD(d.ifDecls);
+    d.elseDecls && visitD(d.elseDecls);
+    return null;
+  }
+
+  D visit(StaticAssertDeclaration d)
+  { return d; } // SP2
+
+  D visit(TemplateDeclaration d)
   {
     if (d.symbol)
       return d;
-    d.symbol = new Union(d.name, d);
+    d.symbol = new Template(d.name, d);
     // Insert into current scope.
-    if (d.name)
-      scop.insert(d.symbol, d.name);
+    insertOverload(d.symbol, d.name);
     enterScope(d.symbol);
     // Continue semantic analysis.
-    d.decls && visitD(d.decls);
+    visitD(d.decls);
     exitScope();
     return d;
   }
 
-  Declaration visit(ConstructorDeclaration)
-  { return null; }
-  Declaration visit(StaticConstructorDeclaration)
-  { return null; }
-  Declaration visit(DestructorDeclaration)
-  { return null; }
-  Declaration visit(StaticDestructorDeclaration)
-  { return null; }
-  Declaration visit(FunctionDeclaration)
-  { return null; }
-
-  Declaration visit(VariablesDeclaration vd)
-  {
-    Type type = Types.Undefined;
+  D visit(NewDeclaration)
+  { /*add id to env*/return null; }
+  D visit(DeleteDeclaration)
+  { /*add id to env*/return null; }
 
-    if (vd.typeNode)
-      // Get type from typeNode.
-      type = visitT(vd.typeNode).type;
-    else
-    { // Infer type from first initializer.
-      auto firstInit = vd.values[0];
-      firstInit = visitE(firstInit);
-      type = firstInit.type;
-    }
-    //assert(type !is null);
-
-    // Check if we are in an interface.
-    if (scop.isInterface)
-      return error(vd.begin, MSG.InterfaceCantHaveVariables), vd;
-
-    // Iterate over variable identifiers in this declaration.
-    foreach (i, ident; vd.idents)
-    {
-      // Perform semantic analysis on value.
-      if (vd.values[i])
-        vd.values[i] = visitE(vd.values[i]);
-      // Create a new variable symbol.
-      // TODO: pass 'prot' to constructor.
-      auto variable = new Variable(vd.stc, vd.linkageType, type, ident, vd);
-      vd.variables ~= variable;
-      // Add to scope.
-      scop.insert(variable);
-    }
-    return vd;
+  D visit(ProtectionDeclaration d)
+  {
+    auto saved = protection; // Save.
+    protection = d.prot; // Set.
+    visitD(d.decls);
+    protection = saved; // Restore.
+    return d;
   }
 
-  Declaration visit(InvariantDeclaration)
-  { return null; }
-  Declaration visit(UnittestDeclaration)
-  { return null; }
-  Declaration visit(DebugDeclaration)
-  { return null; }
-  Declaration visit(VersionDeclaration)
-  { return null; }
-  Declaration visit(StaticIfDeclaration)
-  { return null; }
-  Declaration visit(StaticAssertDeclaration)
-  { return null; }
-  Declaration visit(TemplateDeclaration)
-  { return null; }
-  Declaration visit(NewDeclaration)
-  { return null; }
-  Declaration visit(DeleteDeclaration)
-  { return null; }
+  D visit(StorageClassDeclaration d)
+  {
+    auto saved = storageClass; // Save.
+    storageClass = d.storageClass; // Set.
+    visitD(d.decls);
+    storageClass = saved; // Restore.
+    return d;
+  }
 
-  Declaration visit(ProtectionDeclaration d)
-  { visitD(d.decls); return d; }
-  Declaration visit(StorageClassDeclaration d)
-  { visitD(d.decls); return d; }
-  Declaration visit(LinkageDeclaration d)
-  { visitD(d.decls); return d; }
-  Declaration visit(AlignDeclaration d)
-  { visitD(d.decls); return d; }
+  D visit(LinkageDeclaration d)
+  {
+    auto saved = linkageType; // Save.
+    linkageType = d.linkageType; // Set.
+    visitD(d.decls);
+    linkageType = saved; // Restore.
+    return d;
+  }
 
-  Declaration visit(PragmaDeclaration d)
+  D visit(AlignDeclaration d)
+  {
+    auto saved = alignSize; // Save.
+    alignSize = d.size; // Set.
+    visitD(d.decls);
+    alignSize = saved; // Restore.
+    return d;
+  }
+
+  D visit(PragmaDeclaration d)
   {
     pragmaSemantic(scop, d.begin, d.ident, d.args);
     visitD(d.decls);
@@ -300,155 +377,13 @@
     return s;
   }
 
-  Declaration visit(MixinDeclaration)
-  { return null; }
-
-  Expression visit(ParenExpression e)
-  {
-    if (!e.type)
-    {
-      e.next = visitE(e.next);
-      e.type = e.next.type;
-    }
-    return e;
-  }
-
-  Expression visit(CommaExpression e)
-  {
-    if (!e.type)
-    {
-      e.left = visitE(e.left);
-      e.right = visitE(e.right);
-      e.type = e.right.type;
-    }
-    return e;
-  }
-
-  Expression visit(OrOrExpression)
-  { return null; }
-
-  Expression visit(AndAndExpression)
-  { return null; }
-
-  Expression visit(SpecialTokenExpression e)
-  {
-    if (e.type)
-      return e.value;
-    switch (e.specialToken.kind)
-    {
-    case TOK.LINE, TOK.VERSION:
-      e.value = new IntExpression(e.specialToken.uint_, Types.Uint);
-      break;
-    case TOK.FILE, TOK.DATE, TOK.TIME, TOK.TIMESTAMP, TOK.VENDOR:
-      e.value = new StringExpression(e.specialToken.str);
-      break;
-    default:
-      assert(0);
-    }
-    e.type = e.value.type;
-    return e.value;
-  }
-
-  Expression visit(DollarExpression e)
-  {
-    if (e.type)
-      return e;
-    e.type = Types.Size_t;
-    // if (!inArraySubscript)
-    //   error("$ can only be in an array subscript.");
-    return e;
-  }
-
-  Expression visit(NullExpression e)
-  {
-    if (!e.type)
-      e.type = Types.Void_ptr;
-    return e;
-  }
-
-  Expression visit(BoolExpression e)
+  D visit(MixinDeclaration md)
   {
-    if (e.type)
-      return e;
-    e.value = new IntExpression(e.toBool(), Types.Bool);
-    e.type = Types.Bool;
-    return e;
-  }
-
-  Expression visit(IntExpression e)
-  {
-    if (e.type)
-      return e;
-
-    if (e.number & 0x8000_0000_0000_0000)
-      e.type = Types.Ulong; // 0xFFFF_FFFF_FFFF_FFFF
-    else if (e.number & 0xFFFF_FFFF_0000_0000)
-      e.type = Types.Long; // 0x7FFF_FFFF_FFFF_FFFF
-    else if (e.number & 0x8000_0000)
-      e.type = Types.Uint; // 0xFFFF_FFFF
-    else
-      e.type = Types.Int; // 0x7FFF_FFFF
-    return e;
-  }
-
-  Expression visit(RealExpression e)
-  {
-    if (e.type)
-      e.type = Types.Double;
-    return e;
-  }
-
-  Expression visit(ComplexExpression e)
-  {
-    if (!e.type)
-      e.type = Types.Cdouble;
-    return e;
-  }
-
-  Expression visit(CharExpression e)
-  {
-    if (e.type)
-      return e;
-    if (e.character <= 0xFF)
-      e.type = Types.Char;
-    else if (e.character <= 0xFFFF)
-      e.type = Types.Wchar;
-    else
-      e.type = Types.Dchar;
-    return e;
-  }
-
-  Expression visit(StringExpression e)
-  {
-    return e;
-  }
-
-  Expression visit(MixinExpression me)
-  {
-    /+
-    if (type)
-      return this.expr;
-    // TODO:
-    auto expr = this.expr.semantic(scop);
-    expr = expr.evaluate();
-    if (expr is null)
-      return this;
-    auto strExpr = TryCast!(StringExpression)(expr);
-    if (strExpr is null)
-     error(scop, MSG.MixinArgumentMustBeString);
-    else
-    {
-      auto loc = this.begin.getErrorLocation();
-      auto filePath = loc.filePath;
-      auto parser = new_ExpressionParser(strExpr.getString(), filePath, scop.infoMan);
-      expr = parser.parse();
-      expr = expr.semantic(scop);
-    }
-    this.expr = expr;
-    this.type = expr.type;
-    return expr;
-    +/
-    return null;
+    // Add md to vector of (Scope, MixinDeclaration)
+    // and evaluate them in 2nd pass?
+    // TODO: store all attributes in md; they have to be applied
+    // to the content that is mixed in.
+    return md;
   }
 } // override
 }
--- a/trunk/src/dil/semantic/Scope.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/semantic/Scope.d	Mon Jan 21 17:10:12 2008 +0100
@@ -50,15 +50,15 @@
   /// Insert a new variable symbol into this scope.
   void insert(Variable var)
   {
-    auto sym = symbol.lookup(var.ident);
+    auto sym = symbol.lookup(var.name);
     if (sym)
     {
       auto loc = sym.node.begin.getErrorLocation();
       auto locString = Format("{}({},{})", loc.filePath, loc.lineNum, loc.colNum);
-      error(var.node.begin, MSG.VariableConflictsWithDecl, var.ident.str, locString);
+      error(var.node.begin, MSG.VariableConflictsWithDecl, var.name.str, locString);
     }
     else
-      symbol.insert(var, var.ident);
+      symbol.insert(var, var.name);
     // Set the current scope symbol as the parent.
     var.parent = symbol;
   }
--- a/trunk/src/dil/semantic/Symbol.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/semantic/Symbol.d	Mon Jan 21 17:10:12 2008 +0100
@@ -20,6 +20,8 @@
   Template,
   Variable,
   Function,
+  Alias,
+  OverloadSet,
 //   Type,
 }
 
@@ -30,11 +32,18 @@
 {
   SYM sid;
   Symbol parent; /// The parent this symbol belongs to.
-  Identifier* ident; /// The name of this symbol.
+  Identifier* name; /// The name of this symbol.
   /// The AST node that produced this symbol.
   /// Useful for source code location info and retrieval of doc comments.
   Node node;
 
+  this(SYM sid, Identifier* name, Node node)
+  {
+    this.sid = sid;
+    this.name = name;
+    this.node = node;
+  }
+
   // A template macro for building isXYZ() methods.
   private template is_(char[] kind)
   {
@@ -49,5 +58,7 @@
   mixin(is_!("Template"));
   mixin(is_!("Variable"));
   mixin(is_!("Function"));
+  mixin(is_!("Alias"));
+  mixin(is_!("OverloadSet"));
 //   mixin(is_!("Type"));
 }
--- a/trunk/src/dil/semantic/Symbols.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/semantic/Symbols.d	Mon Jan 21 17:10:12 2008 +0100
@@ -18,20 +18,21 @@
   SymbolTable symbolTable; /// The symbol table.
   Symbol[] members; /// The member symbols (in lexical order.)
 
-  this()
+  this(SYM sid, Identifier* name, Node node)
   {
+    super(sid, name, node);
   }
 
   /// Look up ident in the table.
-  Symbol lookup(Identifier* ident)
+  Symbol lookup(Identifier* name)
   {
-    return symbolTable.lookup(ident);
+    return symbolTable.lookup(name);
   }
 
   /// Insert a symbol into the table.
-  void insert(Symbol s, Identifier* ident)
+  void insert(Symbol s, Identifier* name)
   {
-    symbolTable.insert(s, ident);
+    symbolTable.insert(s, name);
     members ~= s;
   }
 }
@@ -42,6 +43,11 @@
   Function[] funcs;
   Variable[] fields;
 
+  this(SYM sid, Identifier* name, Node node)
+  {
+    super(sid, name, node);
+  }
+
   override void insert(Symbol s, Identifier* ident)
   {
     if (s.isVariable)
@@ -56,52 +62,42 @@
 
 class Class : Aggregate
 {
-  this(Identifier* ident, Node classNode)
+  this(Identifier* name, Node classNode)
   {
-    this.sid = SYM.Class;
-    this.ident = ident;
-    this.node = classNode;
+    super(SYM.Class, name, classNode);
   }
 }
 
 class Interface : Aggregate
 {
-  this(Identifier* ident, Node interfaceNode)
+  this(Identifier* name, Node interfaceNode)
   {
-    this.sid = SYM.Interface;
-    this.ident = ident;
-    this.node = interfaceNode;
+    super(SYM.Interface, name, interfaceNode);
   }
 }
 
 class Union : Aggregate
 {
-  this(Identifier* ident, Node unionNode)
+  this(Identifier* name, Node unionNode)
   {
-    this.sid = SYM.Union;
-    this.ident = ident;
-    this.node = unionNode;
+    super(SYM.Union, name, unionNode);
   }
 }
 
 class Struct : Aggregate
 {
-  this(Identifier* ident, Node structNode)
+  this(Identifier* name, Node structNode)
   {
-    this.sid = SYM.Struct;
-    this.ident = ident;
-    this.node = structNode;
+    super(SYM.Struct, name, structNode);
   }
 }
 
 class Enum : ScopeSymbol
 {
   EnumType type;
-  this(Identifier* ident, Node enumNode)
+  this(Identifier* name, Node enumNode)
   {
-    this.sid = SYM.Enum;
-    this.ident = ident;
-    this.node = enumNode;
+    super(SYM.Enum, name, enumNode);
   }
 
   void setType(EnumType type)
@@ -112,45 +108,69 @@
 
 class Template : ScopeSymbol
 {
-  this(Identifier* ident, Node templateNode)
+  this(Identifier* name, Node templateNode)
   {
-    this.sid = SYM.Template;
-    this.ident = ident;
-    this.node = templateNode;
+    super(SYM.Template, name, templateNode);
   }
 }
 
 class Function : ScopeSymbol
 {
-  StorageClass stc;
-  LinkageType linkType;
+  Protection prot; /// The protection.
+  StorageClass stc; /// The storage classes.
+  LinkageType linkType; /// The linkage type.
 
   Type returnType;
-  Identifier* ident;
   Variable[] params;
 
-  this()
+  this(Identifier* name, Node functionNode)
   {
-    this.sid = SYM.Function;
+    super(SYM.Function, name, functionNode);
   }
 }
 
 class Variable : Symbol
 {
+  Protection prot; /// The protection.
   StorageClass stc; /// The storage classes.
   LinkageType linkType; /// The linkage type.
 
   Type type; /// The type of this variable.
 
-  this(StorageClass stc, LinkageType linkType,
-       Type type, Identifier* ident, Node varDecl)
+  this(Identifier* name,
+       Protection prot, StorageClass stc, LinkageType linkType,
+       Node variableNode)
   {
-    this.sid = SYM.Variable;
+    super(SYM.Variable, name, variableNode);
 
     this.stc = stc;
     this.linkType = linkType;
-    this.type = type;
-    this.ident = ident;
-    this.node = varDecl;
+  }
+}
+
+class Alias : Symbol
+{
+  this(Identifier* name, Node aliasNode)
+  {
+    super(SYM.Alias, name, aliasNode);
   }
 }
+
+/++
+  A list of symbols that share the same identifier.
+  These can be functions, templates and aggregates with template parameter lists.
++/
+class OverloadSet : Symbol
+{
+  Symbol[] symbols;
+
+  this(Identifier* name, Node node)
+  {
+    super(SYM.OverloadSet, name, node);
+  }
+
+  void add(Symbol s)
+  {
+    symbols ~= s;
+  }
+}
--- a/trunk/src/dil/translator/German.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/dil/translator/German.d	Mon Jan 21 17:10:12 2008 +0100
@@ -174,7 +174,7 @@
       was = "lokale Variable";
     else
       was = "globale Variable";
-    foreach (name; n.idents)
+    foreach (name; n.names)
     {
       put(indent).format("'{}' ist eine {} des Typs: ", name.str, was);
       if (n.typeNode)
--- a/trunk/src/main.d	Sat Jan 19 20:35:45 2008 +0100
+++ b/trunk/src/main.d	Mon Jan 21 17:10:12 2008 +0100
@@ -70,7 +70,7 @@
           char[] docText;
           foreach (token; tokens)
             docText ~= token.srcText;
-          Stdout.formatln("Id:{}, Symbol:{}, DocText:{}", member.ident.str, member.classinfo.name, docText);
+          Stdout.formatln("Id:{}, Symbol:{}, DocText:{}", member.name.str, member.classinfo.name, docText);
         }
       }