changeset 194:08f68d684047

Rename some files. Hopefully we can get a more iterative sema pass, that's a lot easier to "get startet with". Also added support for alias.
author Anders Johnsen <skabet@gmail.com>
date Tue, 29 Jul 2008 13:54:44 +0200
parents 658178183018
children 4e1a7265d620
files ast/Decl.d ast/Exp.d ast/Module.d dang/compiler.d lexer/Keyword.d lexer/Token.d parser/Action.d parser/Parser.d sema/AstAction.d sema/BuildScopes.d sema/BuildSymbols.d sema/CheckScopes.d sema/CheckTypes.d sema/ScopeBuilder.d sema/ScopeCheck.d sema/TypeCheck.d sema/Visitor.d tests/parser/alias_1.d tests/parser/null_1.d
diffstat 19 files changed, 1275 insertions(+), 1176 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Decl.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/ast/Decl.d	Tue Jul 29 13:54:44 2008 +0200
@@ -23,6 +23,7 @@
     StructDecl,
     ClassDecl,
     InterfaceDecl,
+    AliasDecl,
 }
 
 class Decl
@@ -309,3 +310,14 @@
     private DType myType;
 }
 
+class AliasDecl : Decl
+{
+    this(Decl decl)
+    {
+        super(DeclType.AliasDecl);
+        this.decl = decl;
+    }
+
+    Decl decl;
+}
+
--- a/ast/Exp.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/ast/Exp.d	Tue Jul 29 13:54:44 2008 +0200
@@ -30,13 +30,14 @@
     CastExp,
     StringExp,
     NewExp,
+    NullExp,
+    ArrayLiteralExp,
 
     IdentifierTypeExp,
     ArrayTypeExp,
     StaticArrayTypeExp,
     PointerTypeExp,
     FunctionTypeExp,
-    ArrayLiteralExp,
 }
 
 abstract class Exp
@@ -579,6 +580,19 @@
     Symbol callSym;
 }
 
+class NullExp : Exp
+{
+    this(SLoc loc)
+    {
+        super(ExpType.NullExp, loc);
+    }
+
+    override DType type() 
+    { 
+        return new DPointer(DType.Int); 
+    }
+}
+
 class Identifier : Exp
 {
     this(SLoc loc, char[] name)
--- a/ast/Module.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/ast/Module.d	Tue Jul 29 13:54:44 2008 +0200
@@ -15,6 +15,8 @@
 
     void addDecl(Decl decl)
     {
+        if(!decl)
+            return;
         switch(decl.declType)
         {
             case DeclType.FuncDecl:
@@ -32,6 +34,9 @@
             case DeclType.InterfaceDecl:
                 interfaces ~= cast(InterfaceDecl)decl;
                 break;
+            case DeclType.AliasDecl:
+                aliases ~= cast(AliasDecl)decl;
+                break;
             default:
                 assert(0, "DeclType not implemented");
         }
@@ -49,6 +54,7 @@
     StructDecl[]    structs;
     ClassDecl[]     classes;
     InterfaceDecl[] interfaces;
+    AliasDecl[]     aliases;
     Decl[] decls;
 
     char[] moduleName;
--- a/dang/compiler.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/dang/compiler.d	Tue Jul 29 13:54:44 2008 +0200
@@ -25,12 +25,13 @@
 
 import sema.Visitor,
        sema.AstAction,
-       sema.ScopeBuilder,
+       sema.BuildScopes,
+       sema.BuildSymbols,
+       sema.CheckScopes,
+       sema.CheckTypes,
        sema.LiteralInterpreter,
-       sema.ScopeCheck,
        sema.VC,
-       sema.ObjectOriented,
-       sema.TypeCheck;
+       sema.ObjectOriented;
 
 import tango.stdc.posix.unistd;
 import tango.stdc.stdlib;
@@ -314,16 +315,17 @@
     modules = (new ModuleLoader()).visit(modules, messages, src_mgr);
     messages.checkErrors;
 
-    (new ScopeBuilder).visit(modules);
+    (new BuildScopes).visit(modules);
+    (new BuildSymbols).visit(modules);
     StopWatch watch2;
     watch.start;
     watch2.start;
-    (new ScopeCheck(messages)).visit(modules);
+    (new CheckScopes(messages)).visit(modules);
     messages.checkErrors;
     auto scope_check = watch2.stop;
 
     watch2.start;
-    (new TypeCheck(messages)).visit(modules);
+    (new CheckTypes(messages)).visit(modules);
     messages.checkErrors;
     auto type_check = watch2.stop;
 
--- a/lexer/Keyword.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/lexer/Keyword.d	Tue Jul 29 13:54:44 2008 +0200
@@ -47,6 +47,7 @@
         "alias"     : Tok.Alias,
         "this"      : Tok.This,
         "new"       : Tok.New,
+        "null"      : Tok.Null,
 //        "super"     : Tok.Super,
 
         // control flow
--- a/lexer/Token.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/lexer/Token.d	Tue Jul 29 13:54:44 2008 +0200
@@ -212,7 +212,7 @@
 
     Module, Import,
 
-    New,
+    New, Null,
 
     /* Attributes */
     Public, Private, Package, Export, Protected,
@@ -321,6 +321,8 @@
         Tok.Deprecated:"deprecated",
         Tok.Auto:"auto",
         Tok.Extern:"extern",
-        Tok.New:"new"
+        Tok.New:"new",
+        Tok.Null:"null",
+        Tok.Alias:"alias"
     ];
 }
--- a/parser/Action.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/parser/Action.d	Tue Jul 29 13:54:44 2008 +0200
@@ -175,6 +175,11 @@
         return null;
     }
 
+    DeclT actOnAliasDecl(DeclT decl, Attribute att)
+    {
+        return null;
+    }
+
     /**
       Add a struct member to a struct.
      */
@@ -430,6 +435,14 @@
     {
         return null;
     }
+
+    /**
+      Null expression.
+     */
+    ExprT actOnNullExpr(SLoc pos)
+    {
+        return null;
+    }
 }
 
 /**
--- a/parser/Parser.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/parser/Parser.d	Tue Jul 29 13:54:44 2008 +0200
@@ -91,6 +91,11 @@
                 Id iden = Id(require(Tok.Identifier));
                 return parseInterface(type, iden, att);
 
+            case Tok.Alias:
+                next();
+                auto decl = parseDecl(Attribute());
+                return action.actOnAliasDecl(decl, att);
+
             case Tok.Identifier:
                 Id type = parseType;
                 Id iden = Id(require(Tok.Identifier));
@@ -126,6 +131,7 @@
                 messages.report(UnexpectedTok, peek.location)
                     .arg(sm.getText(peek.asRange));
 
+                next();
                 return null;
         }
         messages.report(UnexpectedTok, peek.location)
@@ -961,6 +967,8 @@
                     return iden;
             }
         }
+        else if (n.type == Tok.Null)
+            return action.actOnNullExpr(n.location);
         else if (n.type == Tok.Cast)
             return parseCast(n);
         else if (n.type == Tok.Integer)
--- a/sema/AstAction.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/sema/AstAction.d	Tue Jul 29 13:54:44 2008 +0200
@@ -102,6 +102,13 @@
         d.att = att;
         return d;
     }
+
+    DeclT actOnAliasDecl(DeclT decl, Attribute att)
+    {
+        auto a = new AliasDecl(cast(Decl)decl);
+        a.att = att;
+        return a;
+    }
     
     void actOnStructMember(DeclT st_decl, DeclT m_decl) //ref Id type, ref Id name, ExprT init)
     {
@@ -311,6 +318,11 @@
     {
         return new ArrayLiteralExp(cast(Exp[])exps, start, end);
     }
+
+    ExprT actOnNullExpr(SLoc pos)
+    {
+        return new NullExp(pos);
+    }
 }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/BuildScopes.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,265 @@
+module sema.BuildScopes;
+
+import tango.io.Stdout,
+       tango.core.Array : find;
+
+import sema.Scope;
+
+import sema.Visitor;
+
+/**
+  Add scopes to everything, and add all identifiers that correspond to types.
+  Types/Symbols are added by ForwardReference.
+ **/
+class BuildScopes : Visitor!(void)
+{
+    static ModuleHandler mHandle;
+
+    static this()
+    {
+        mHandle = new ModuleHandler;
+    }
+
+    override void visit(Module[] modules)
+    {
+        foreach(m ; modules)
+            visitModule(m);
+    }
+
+    private void registerBasicTypeTo(char[] n, DType t, Scope sc, Module m)
+    {
+        sc.types[n] = t;
+        auto id = new Identifier(n);
+        id.env = sc;
+        auto decl = new DummyDecl();
+        auto sym = m.symbol.createMember(n, t, decl);
+        sym.decl = decl;
+        decl.sym = sym;
+        decl.env = sc;
+        sc.put(id.get, decl);
+    }
+
+    override void visitModule(Module m)
+    {
+        auto root = new Scope;
+        table ~= root;
+
+        m.symbol = new Symbol;
+
+        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;
+        mHandle.add(m);
+        m.env = current();
+        super.visitModule(m);
+    }
+
+    override void visitDecl(Decl d)
+    {
+        d.env = current();
+        super.visitDecl(d);
+    }
+
+    override void visitImportDecl(ImportDecl i)
+    {
+        i.env.imports ~= i;
+        super.visitImportDecl(i);
+    }
+
+    override void visitStmt(Stmt s)
+    {
+        s.env = current();
+        s.stmtIndex = s.env.stmtIndex;
+        super.visitStmt(s);
+    }
+
+    override void visitExp(Exp e)
+    {
+        e.env = current();
+        e.stmtIndex = e.env.stmtIndex;
+        super.visitExp(e);
+    }
+
+    override void visitFuncDecl(FuncDecl d)
+    {
+        current().put(d.identifier.get, d);
+        d.env = current();
+        auto sc = push();
+
+        visitExp(d.returnType);
+        visitExp(d.identifier);
+        sc.parentFunction = d;
+        foreach (arg; d.funcArgs)
+            visitDecl(arg);
+        foreach (stmt; d.statements)
+        {
+            sc.currentStmtIndex++;
+            visitStmt(stmt);
+        }
+        pop(sc);
+    }
+
+    override void visitVarDecl(VarDecl d)
+    {
+        if (d.init)
+            visitExp(d.init);
+
+        if (need_push > 0 && current().parentFunction !is null) {
+            push();
+            --need_push;
+        }
+
+        if(d.identifier)
+        {
+            auto sc = current();
+            sc.put(d.identifier.get, d);
+            d.env = sc;
+            visitExp(d.varType);
+            visitExp(d.identifier);
+        }
+    }
+
+    override void visitStructDecl(StructDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DStruct(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitStructDecl(s);
+        pop(sc);
+    }
+
+    override void visitClassDecl(ClassDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DClass(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitClassDecl(s);
+        pop(sc);
+    }
+
+    override void visitInterfaceDecl(InterfaceDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DInterface(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitInterfaceDecl(s);
+        pop(sc);
+    }
+    
+    override void visitAliasDecl(AliasDecl a)
+    {
+        a.env = current();
+//        auto decl = cast(VarDecl)a.decl;
+//        auto sc = current();
+//        super.visitDecl(a.decl);
+    }
+
+    override void visitDeclStmt(DeclStmt d)
+    {
+        ++need_push;
+        super.visitDeclStmt(d);
+    }
+    private uint need_push = 0;
+
+    override void visitIfStmt(IfStmt s)
+    {
+        s.env = current();
+        visitExp(s.cond);
+        auto sc = push();
+        visitStmt(s.then_body);
+        pop(sc);
+
+        if (s.else_body !is null)
+        {
+            sc = push();
+            visitStmt(s.else_body);
+            pop(sc);
+        }
+    }
+
+    override void visitWhileStmt(WhileStmt s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitWhileStmt(s);
+        pop(sc);
+    }
+
+    override void visitForStmt(ForStmt s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitForStmt(s);
+        pop(sc);
+    }
+
+    override void visitCompoundStmt(CompoundStatement s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitCompoundStmt(s);
+        pop(sc);
+    }
+
+private:
+    Scope[] table;
+
+    Scope push()
+    {
+        auto sc = new Scope(current());
+        table ~= sc;
+        return sc;
+    }
+
+    Scope pop(Scope sc = null)
+    {
+        if (sc !is null)
+        {
+            table.length = table.find(sc);
+            return sc;
+        }
+
+        auto res = table[$ - 1];
+        table.length = table.length - 1;
+        return res;
+    }
+
+    Scope current()
+    {
+        return table[$ - 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/BuildSymbols.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,247 @@
+module sema.BuildSymbols;
+
+import tango.io.Stdout,
+       tango.core.Array : find;
+
+import sema.Scope,
+       sema.Symbol;
+
+import sema.Visitor,
+       basic.SmallArray;
+
+class SymbolFactory
+{
+    void put(Symbol symbol, DType type)
+    {
+        types[type] = symbol;
+    }
+
+    Symbol get(Symbol owner, DType type, Identifier i, Decl decl)
+    {
+        if (type in types)
+            return owner.createAlias(i.get, types[type], decl);
+        else
+            return owner.createMember(i.get, type, decl);
+    }
+
+    Symbol[DType] types;
+}
+
+class BuildSymbols : Visitor!(void)
+{
+    this()
+    {
+        this.sf = new SymbolFactory;
+    }
+
+    override void visit(Module[] modules)
+    {
+//        (new BuildSymbolTypes(sf)).visit(modules);
+        this.modules = 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);
+
+        d.sym = current.symbol.createMember(
+                d.identifier.get, 
+                d.type, 
+                d);
+
+        auto old = current.symbol;
+        current.symbol = d.sym;
+
+        foreach (arg; d.funcArgs)
+            visitDecl(arg);
+
+        inFunctionBodyStack.push(true);
+
+        foreach (stmt; d.statements)
+            visitStmt(stmt);
+
+        inFunctionBodyStack.pop();
+
+        current.symbol = old;
+
+    }
+
+    override void visitVarDecl(VarDecl d)
+    {
+        visitExp(d.varType);
+        if(d.identifier)
+            visitExp(d.identifier);
+        
+        if (d.init)
+            visitExp(d.init);
+
+        if(d.identifier)
+        {
+            DType t = typeOf(d.varType, d.env);
+            d.sym = sf.get(current.symbol, t, d.identifier, d);
+            d.sym.type = t;
+        }
+    }
+
+    override void visitAliasDecl(AliasDecl a)
+    {
+        auto decl = cast(VarDecl)a.decl;
+
+        if (a.env.findType(decl.varType.get)) // Alias "type" is a type.
+        {
+            auto t = typeOf(decl.varType, a.env);
+            a.sym = sf.get(current.symbol, t,
+                    decl.identifier, a);
+            a.env.types[decl.identifier.get] = t;
+        }
+        else if(auto aliasOf = a.env.find(decl.varType.get)[0])
+        {
+            a.env.put(decl.identifier.get, aliasOf);
+            a.sym = current.symbol.createAlias(
+                    decl.identifier.get, 
+                    aliasOf.sym, 
+                    a);
+        }
+        decl.env = a.env;
+    }
+
+
+    override void visitStructDecl(StructDecl s)
+    {
+        auto st = s.env.findType(s.identifier.get).asStruct;
+        s.sym = current.symbol.createMember(
+                s.identifier.get, 
+                st,
+                s.env.find(s.identifier.get)[0]);
+        sf.put(s.sym, st);
+
+        foreach (decl; s.decls)
+        {
+            DType type;
+            char[] name;
+            if (auto varDecl = cast(VarDecl)decl)
+            {
+                type = typeOf(varDecl.varType, varDecl.env);
+                name = varDecl.identifier.get;
+                st.addMember(type, name);
+            }
+            /*
+            else if (auto fd = cast(FuncDecl)decl)
+            {
+                type = fd.type;
+                name = fd.identifier.get;
+            }*/
+        }
+        auto old = current.symbol;
+        current.symbol = s.sym;
+        inFunctionBodyStack.push(false);
+        super.visitStructDecl(s);
+        inFunctionBodyStack.pop();
+        current.symbol = old;
+    }
+
+    override void visitClassDecl(ClassDecl s)
+    {
+        auto st = s.env.findType(s.identifier.get).asClass;
+        s.sym = current.symbol.createMember(
+                s.identifier.get, 
+                st,
+                s.env.find(s.identifier.get)[0]);
+
+        sf.put(s.sym, st);
+
+        foreach (decl; s.decls)
+        {
+            DType type;
+            char[] name;
+            if (auto varDecl = cast(VarDecl)decl)
+            {
+                type = typeOf(varDecl.varType, varDecl.env);
+                name = varDecl.identifier.get;
+                st.addMember(type, name);
+            }
+            /*
+            else if (auto fd = cast(FuncDecl)decl)
+            {
+                type = fd.type;
+                name = fd.identifier.get;
+            }*/
+        }
+        auto old = current.symbol;
+        current.symbol = s.sym;
+        inFunctionBodyStack.push(false);
+        super.visitClassDecl(s);
+        inFunctionBodyStack.pop();
+        current.symbol = old;
+    }
+
+    override void visitInterfaceDecl(InterfaceDecl s)
+    {
+        auto st = s.env.findType(s.identifier.get).asInterface;
+        s.sym = current.symbol.createMember(
+                s.identifier.get, 
+                st,
+                s.env.find(s.identifier.get)[0]);
+        sf.put(s.sym, st);
+
+        foreach (decl; s.decls)
+        {
+            DType type;
+            char[] name;
+            if (auto varDecl = cast(VarDecl)decl)
+            {
+                type = typeOf(varDecl.varType, varDecl.env);
+                name = varDecl.identifier.get;
+                st.addMember(type, name);
+            }
+            /*
+            else if (auto fd = cast(FuncDecl)decl)
+            {
+                type = fd.type;
+                name = fd.identifier.get;
+            }*/
+        }
+        auto old = current.symbol;
+        current.symbol = s.sym;
+        inFunctionBodyStack.push(false);
+        super.visitInterfaceDecl(s);
+        inFunctionBodyStack.pop();
+        current.symbol = old;
+    }
+
+    override void visitFunctionTypeExp(FunctionTypeExp f)
+    {
+    }
+
+    DType typeOf(Identifier id, Scope sc)
+    {
+        if(auto i = cast(PointerTypeExp)id)
+            return (typeOf(i.pointerOf, sc)).getPointerTo();
+        else if(auto i = cast(StaticArrayTypeExp)id)
+            return typeOf(i.arrayOf, sc).getAsStaticArray(i.size);
+        else if(auto i = cast(FunctionTypeExp)id)
+        {
+            auto d = new DFunction(id);
+            d.returnType = typeOf(i.returnType, sc);
+            foreach (decl ; i.decls)
+                d.params ~= typeOf(decl.varType, sc);
+            return d.getPointerTo;
+        }
+        return sc.findType(id.get);
+    }
+
+    Module[] modules;
+    Module current;
+    SmallArray!(bool) inFunctionBodyStack;
+    SymbolFactory sf;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/CheckScopes.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,158 @@
+module sema.CheckScopes;
+
+import sema.Visitor,
+       sema.Symbol,
+       sema.Scope,
+       sema.DType;
+
+import basic.Message,
+       basic.Attribute;
+
+import tango.io.Stdout;
+
+class CheckScopes : Visitor!(void)
+{
+
+    this(MessageHandler messages)
+    {
+        this.messages = messages;
+    }
+
+    override void visitIdentifier(Identifier i)
+    {
+        auto symbol = i.env.find(i.get);
+
+        if(symbol is null)
+            messages.report(UndefinedIdentifier, i.loc)
+                .arg(i.get);
+    }
+
+    override void visitVarDecl(VarDecl d)
+    {
+        if(d.identifier.get is null)
+            messages.report(UndefinedType, d.varType.loc)
+                .arg(d.varType.get);
+
+        auto env = d.env;
+        if (d.env.enclosing)
+            if (d.env.enclosing.find(d.identifier.get) !is null)
+                if (d.env.parentFunction !is null)
+                    while( d.env.parentFunction.env !is env)
+                    {
+                        if (d.env.enclosing.find(d.identifier.get)[0].env == env)
+                            messages.report(CannotRedeclare, d.identifier.loc)
+                                .arg(d.identifier.get);
+                        env = env.enclosing;
+                    }
+
+        visitExp(d.identifier);
+        if (d.init)
+            visitExp(d.init);
+    }
+
+    override void visitFuncDecl(FuncDecl f)
+    {
+        visitExp(f.identifier);
+
+        inFunction = true;
+        foreach (stmt; f.statements)
+            visitStmt(stmt);
+        inFunction = false;
+    }
+
+    override void visitImportDecl(ImportDecl) { }
+
+    override void visitCastExp(CastExp exp)
+    {
+        visitExp(exp.exp);
+    }
+
+    override void visitMemberReference(MemberReference m)
+    {
+        internalVisitMemberRef(m);
+    }
+
+    private Symbol internalVisitMemberRef(MemberReference m)
+    {
+        Symbol visitRef(MemberReference m, Identifier target, Symbol st)
+        {
+            auto child = m.child;
+            auto res = st.findMembers(child.get);
+
+            if(!res.length)
+                messages.report(MissingMember, m.loc)
+                    .arg(st.type.name)
+                    .arg(target.get)
+                    .arg(child.get);
+            else
+                internalCheckProtection(res[0], child);
+
+            return res.length ? res[0] : null;
+        }
+        switch(m.target.expType)
+        {
+            case ExpType.Identifier:
+                return visitRef(m, cast(Identifier)m.target,
+                        (cast(Identifier)m.target).getSymbol);
+            case ExpType.MemberReference:
+                Symbol s = internalVisitMemberRef(cast(MemberReference)m.target);
+                if(!s)
+                    return null;
+                return visitRef(m, cast(Identifier)m.target, s);
+        }
+    }
+
+    override void visitExp(Exp exp)
+    {
+        if (exp.expType == ExpType.Identifier && inFunction
+            && exp.env.find((cast(Identifier)exp).get) !is null)
+        {
+            if (exp.env.findType((cast(Identifier)exp).get) is null)
+                internalCheckProtection(
+                    exp.env.find((cast(Identifier)exp).get)[0].sym, 
+                    cast(Identifier)exp);
+        }
+
+        super.visitExp(exp);
+    }
+
+    private void internalCheckProtection(Symbol sym, Identifier iden)
+    {
+        if (isChildOf(sym.decl.env, iden.env))
+            return;
+
+        switch(sym.decl.att.getProtection)
+        {
+            case Protection.Private:
+/*                if (iden.env.inModule == sym.decl.getIdentifier.env.inModule
+                    && sym.decl.getIdentifier.env.enclosing == iden.env.inModule)
+                {}
+                else*/
+                messages.report(CannotAccessPrivate, iden.loc);
+                return;
+            default:
+                return;
+        }
+    }
+
+    private bool isChildOf(Scope parent, Scope child)
+    {
+        if (child is parent)
+            return true;
+
+        if (child.enclosing !is null)
+            return isChildOf(parent, child.enclosing);
+
+        return false;
+    }
+
+    private bool isType(char[] s)
+    {
+        return (s in types? true : false);
+    }
+
+    int[char[]] types;
+    MessageHandler messages;
+    bool inFunction;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/CheckTypes.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,477 @@
+module sema.CheckTypes;
+
+import sema.Visitor,
+       sema.Symbol,
+       sema.DType;
+
+import tango.io.Stdout,
+       Integer = tango.text.convert.Integer;
+
+import basic.SourceLocation,
+       basic.Message;
+
+class CheckTypes : Visitor!(void)
+{
+    this(MessageHandler messages)
+    {
+        this.messages = messages;
+    }
+
+    override void visitBinaryExp(BinaryExp exp)
+    {
+        super.visitBinaryExp(exp);
+
+        if(!(exp.left.type is exp.right.type))
+        {
+            if (!exp.right.type.hasImplicitConversionTo(exp.left.type) &&
+                !exp.left.type.hasImplicitConversionTo(exp.right.type))
+                messages.report(InvalidImplicitCast, exp.loc)
+                    .arg(exp.right.type.toString)
+                    .arg(exp.left.type.toString);
+            else
+            {
+                CastExp castExp;
+                if(exp.left.type.isReal && exp.right.type.isReal)
+                    if(exp.left.type.byteSize > exp.right.type.byteSize)
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.left.type.name),
+                            exp.right);
+                    else
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.right.type.name),
+                            exp.left);
+                else if(exp.left.type.isReal || exp.right.type.isReal)
+                    if(exp.left.type.isReal)
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.left.type.name),
+                            exp.right);
+                    else
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.right.type.name),
+                            exp.left);
+                else
+                    if(exp.left.type.byteSize > exp.right.type.byteSize)
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.left.type.name),
+                            exp.right);
+                    else if(exp.left.type.byteSize > exp.right.type.byteSize)
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.right.type.name),
+                            exp.left);
+                    else
+                        castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(exp.left.type.name),
+                            exp.right);
+
+
+                if(castExp)
+                {
+                    castExp.env = exp.env;
+                    if(castExp.exp == exp.right)
+                        exp.right = castExp;
+                    else
+                        exp.left = castExp;
+
+                }
+            }
+        }
+        if (exp.op >= BinaryExp.Operator.LeftShift &&
+            exp.op <= BinaryExp.Operator.UnsignedRightShift)
+        {}  // FIXME: When we have const-system we need to check for 
+            //        right site being larger then the bitsize of the 
+            //        left
+    }
+
+    override void visitDerefExp(DerefExp exp)
+    {
+        if (!exp.exp.type.isPointer)
+        {
+            messages.report(CanOnlyDerefPointers,
+                    [exp.exp.sourceRange][], 
+                    [exp.loc])
+                .arg(exp.exp.type.toString);
+
+            exp._type = DType.Int;
+        }
+    }
+
+    override void visitCallExp(CallExp exp)
+    {
+        super.visitCallExp(exp);
+
+        if (auto iden = cast(MemberReference)exp.exp)
+        {
+            Symbol[] internalVisitMemberRef(MemberReference m)
+            {
+                Symbol[] visitRef(MemberReference m, Identifier target, Symbol st)
+                {
+                    auto child = m.child;
+                    auto res = st.findMembers(child.get);
+                    return res;
+                }
+                switch(m.target.expType)
+                {
+                    case ExpType.Identifier:
+                        return visitRef(m, cast(Identifier)m.target,
+                                (cast(Identifier)m.target).getSymbol);
+                    case ExpType.MemberReference:
+                        Symbol[] s = internalVisitMemberRef(cast(MemberReference)m.target);
+                        if(s.length)
+                            return s;
+                        return visitRef(m, cast(Identifier)m.target, s[0]);
+                }
+            }
+
+            Exp[] newArgs;
+
+            DFunction function_type;
+            if (iden.type.isFunction())
+            {
+                Symbol[] methods = internalVisitMemberRef(iden);           
+
+                if (!methods.length)
+                {
+                    messages.report(NoMethodByName, iden.loc);
+                    return;
+                }
+
+                Symbol sel = getBestMatch(exp.args, methods);
+                exp.callSym = sel;
+                if (sel)
+                    function_type = sel.type.asFunction();
+                else
+                {
+                    messages.report(NoMachingMethod, exp.loc);
+                    foreach ( i, s ; methods )
+                    {
+                        messages.report(CandidateNr, 
+                                (cast(FuncDecl)s.decl).identifier.loc)
+                            .arg(Integer.toString(i+1));
+                    }
+                }
+            }
+            else if (iden.type.isCallable)
+                function_type = iden.type.asCallable();
+            else assert(0, "Should not happen");
+
+            foreach (i, arg; exp.args)
+            {
+                auto argType = function_type.params[i];
+                auto expType = arg.type;
+                if (argType.isSame(expType))
+                {
+                    if (!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = iden.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+            exp.args = newArgs;
+        }
+        else if (auto iden = cast(Identifier)exp.exp)
+        {
+            Exp[] newArgs;
+
+            DFunction function_type;
+            if (iden.type.isFunction())
+            {
+                Symbol[] methods;
+
+                foreach (decl ; iden.env.find(iden.get))
+                    methods ~= decl.sym;
+
+                if (!methods.length)
+                {
+                    messages.report(NoMethodByName, iden.loc);
+                    return;
+                }
+
+                Symbol sel = getBestMatch(exp.args, methods);
+                exp.callSym = sel;
+                if (sel)
+                    function_type = sel.type.asFunction();
+                else
+                {
+                    messages.report(NoMachingMethod, exp.loc);
+                    foreach ( i, s ; methods )
+                    {
+                        messages.report(CandidateNr, 
+                                (cast(FuncDecl)s.decl).identifier.loc)
+                            .arg(Integer.toString(i+1));
+                    }
+                }
+            }
+            else if (iden.type.isCallable)
+            {
+                function_type = iden.type.asCallable();
+                if (exp.args.length != function_type.params.length)
+                {
+                    messages.report(CannotCallMethod, exp.loc)
+                        .arg(iden.type.toString)
+                        .arg(exp.callerType.toString);
+                }
+            }
+            else assert(0, "Should not happen");
+
+            foreach (i, arg; exp.args)
+            {
+                auto argType = function_type.params[i];
+                auto expType = arg.type;
+                if (!argType.isSame(expType))
+                {
+                    if (!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = iden.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+            exp.args = newArgs;
+        }
+        else
+        {
+            Exp[] newArgs;
+
+            foreach(i, arg; exp.args)
+            {
+                auto argType = exp.exp.type.asFunction.params[i];
+                auto expType = arg.type;
+                if(!argType.isSame(expType))
+                {
+                    if(!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = exp.exp.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+
+            exp.args = newArgs;
+        }
+    }
+
+    override void visitNewExp(NewExp exp)
+    {
+        super.visitNewExp(exp);
+
+        Exp[] newArgs;
+        
+        Symbol[] methods = exp.newType.getSymbol.findFunctionMembers("this");
+
+        if (!methods.length)
+        {
+            messages.report(NoConstructor, exp.newType.loc);
+            return;
+        }
+
+        Symbol sel = getBestMatch(exp.c_args, methods);
+
+        if (sel)
+        {
+            foreach (i, arg; exp.c_args)
+            {
+                auto argType = sel.type.asFunction.params[i];
+                auto expType = arg.type;
+                if (!argType.isSame(expType))
+                {
+                    if (!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = exp.newType.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+            exp.c_args = newArgs;
+            exp.callSym = sel;
+        }
+        else
+        {
+            messages.report(NoMachingCon, exp.newType.loc);
+            foreach ( i, s ; methods )
+            {
+                messages.report(CandidateNr, 
+                        (cast(FuncDecl)s.decl).identifier.loc)
+                    .arg(Integer.toString(i+1));
+            }
+        }
+    }
+
+    override void visitAssignExp(AssignExp exp)
+    {
+        super.visitAssignExp(exp);
+
+        auto identifierType = exp.identifier.type;
+        auto expType = exp.exp.type;
+
+        if(!identifierType.isSame(expType))
+        {
+            if(!expType.hasImplicitConversionTo(identifierType))
+                messages.report(InvalidImplicitCast, 
+                        [exp.identifier.sourceRange, exp.exp.sourceRange][], 
+                        [exp.loc])
+                    .arg(expType.toString)
+                    .arg(identifierType.toString);
+
+            auto castExp = new CastExp(
+                    SLoc.Invalid,
+                    new Identifier(identifierType.name),
+                    exp.exp);
+            castExp.env = exp.exp.env;
+            exp.exp = castExp;
+        }
+
+        if (expType.isStaticArray)
+            messages.report(CannotReassignSArray, 
+                    [exp.identifier.sourceRange, exp.exp.sourceRange][], 
+                    [exp.loc]);
+    }
+
+    override void visitReturnStmt(ReturnStmt stmt)
+    {
+        super.visitReturnStmt(stmt);
+
+        if(stmt.exp)
+        {
+            auto returnType = stmt.env.parentFunction.type.asFunction.returnType;
+            auto expType = stmt.exp.type;
+            if(!expType)
+                return;
+            if(!returnType.isSame(expType))
+            {
+                if(!expType.hasImplicitConversionTo(returnType))
+                   messages.report(InvalidImplicitCast, stmt.exp.loc)
+                        .arg(expType.toString)
+                        .arg(returnType.toString);
+
+                auto castExp = new CastExp(
+                        SLoc.Invalid,
+                        new Identifier(returnType.name),
+                        stmt.exp);
+                castExp.env = stmt.exp.env;
+                stmt.exp = castExp;
+            }
+        }
+    }
+
+    override void visitVarDecl(VarDecl decl)
+    {
+        super.visitVarDecl(decl);
+
+        if(decl.init)
+        {
+            auto varType = decl.identifier.type;
+            auto expType = decl.init.type;
+            if(!varType.isSame(expType))
+            {
+                if(!expType.hasImplicitConversionTo(varType))
+                   messages.report(InvalidImplicitCast, decl.init.loc)
+                        .arg(expType.toString)
+                        .arg(varType.toString);
+
+                auto castExp = new CastExp(
+                        SLoc.Invalid,
+                        new Identifier(varType.name),
+                        decl.init);
+                castExp.env = decl.init.env;
+                decl.init = castExp;
+            }
+        }
+    }
+
+    private Symbol getBestMatch(Exp[] arg_list , Symbol[] available)
+    in
+    {
+        foreach (a ; available)
+            assert(a.type.isFunction, "A non-function found in available-list.");
+    }
+    body
+    {
+        assert(available.length, "No available methods in symbol-list.");
+
+        Symbol[] possible;
+        Symbol perfect;
+
+        bool per, work;
+        foreach (s ; available)
+        {
+            if (s.type.asFunction.params.length < arg_list.length)
+                continue;
+
+            per = true;
+            work = true;
+
+            foreach (i, arg; arg_list)
+            {
+                auto argType = s.type.asFunction.params[i];
+                auto expType = arg.type;
+                if (argType.isSame(expType))
+                {
+                    per = false;
+                    if( !expType.hasImplicitConversionTo(argType) )
+                    {
+                        work = false;
+                        break;
+                    }
+                }
+            }
+
+            foreach (a ; (cast(FuncDecl)s.decl).funcArgs[arg_list.length..$])
+                if (a.init is null)
+                    work = false;
+
+            if (work)
+                if (per)
+                    return s;
+                else
+                    possible ~= s;
+        }
+
+        if (possible.length)
+            return possible[0];
+
+        return null;
+    }
+
+    MessageHandler messages;
+}
+
--- a/sema/ScopeBuilder.d	Fri Jul 25 15:31:16 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,533 +0,0 @@
-module sema.ScopeBuilder;
-
-import tango.io.Stdout,
-       tango.core.Array : find;
-
-public
-import sema.Scope,
-       sema.Symbol;
-
-import sema.Visitor,
-       basic.SmallArray;
-
-class SymbolFactory
-{
-    void put(Symbol symbol, DType type)
-    {
-        types[type] = symbol;
-    }
-
-    Symbol get(Symbol owner, DType type, Identifier i, Decl decl)
-    {
-        if (type in types)
-            return owner.createAlias(i.get, types[type], decl);
-        else
-            return owner.createMember(i.get, type, decl);
-    }
-
-    Symbol[DType] types;
-}
-
-class ForwardReference : Visitor!(void)
-{
-    this(SymbolFactory sf)
-    {
-        this.sf = sf;
-    }
-    override void visit(Module[] modules)
-    {
-        (new TypeBuilder(sf)).visit(modules);
-        this.modules = 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);
-
-        d.sym = current.symbol.createMember(
-                d.identifier.get, 
-                d.type, 
-                d);
-
-        auto old = current.symbol;
-        current.symbol = d.sym;
-
-        foreach (arg; d.funcArgs)
-            visitDecl(arg);
-
-        inFunctionBodyStack.push(true);
-
-        foreach (stmt; d.statements)
-            visitStmt(stmt);
-
-        inFunctionBodyStack.pop();
-
-        current.symbol = old;
-
-    }
-
-    override void visitVarDecl(VarDecl d)
-    {
-        visitExp(d.varType);
-        if(d.identifier)
-            visitExp(d.identifier);
-        
-        if (d.init)
-            visitExp(d.init);
-
-        if(d.identifier)
-        {
-            DType t = typeOf(d.varType, d.env);
-            d.sym = sf.get(current.symbol, t, d.identifier, d);
-            d.sym.type = t;
-        }
-    }
-
-    override void visitStructDecl(StructDecl s)
-    {
-        auto old = current.symbol;
-        current.symbol = s.sym;
-        inFunctionBodyStack.push(false);
-        super.visitStructDecl(s);
-        inFunctionBodyStack.pop();
-        current.symbol = old;
-    }
-
-    override void visitClassDecl(ClassDecl s)
-    {
-        auto old = current.symbol;
-        current.symbol = s.sym;
-        inFunctionBodyStack.push(false);
-        super.visitClassDecl(s);
-        inFunctionBodyStack.pop();
-        current.symbol = old;
-    }
-
-    override void visitInterfaceDecl(InterfaceDecl s)
-    {
-        auto old = current.symbol;
-        current.symbol = s.sym;
-        inFunctionBodyStack.push(false);
-        super.visitInterfaceDecl(s);
-        inFunctionBodyStack.pop();
-        current.symbol = old;
-    }
-
-    override void visitFunctionTypeExp(FunctionTypeExp f)
-    {
-    }
-
-    DType typeOf(Identifier id, Scope sc)
-    {
-        if(auto i = cast(PointerTypeExp)id)
-            return (typeOf(i.pointerOf, sc)).getPointerTo();
-        else if(auto i = cast(StaticArrayTypeExp)id)
-            return typeOf(i.arrayOf, sc).getAsStaticArray(i.size);
-        else if(auto i = cast(FunctionTypeExp)id)
-        {
-            auto d = new DFunction(id);
-            d.returnType = typeOf(i.returnType, sc);
-            foreach (decl ; i.decls)
-                d.params ~= typeOf(decl.varType, sc);
-            return d.getPointerTo;
-        }
-        return sc.findType(id.get);
-    }
-
-    Module[] modules;
-    Module current;
-    SmallArray!(bool) inFunctionBodyStack;
-    SymbolFactory sf;
-}
-
-class TypeBuilder : Visitor!(void)
-{
-    this(SymbolFactory sf)
-    {
-        this.sf = sf;
-    }
-
-    override void visit(Module[] modules)
-    {
-        foreach (mod; modules)
-        {
-            current = mod;
-            foreach (decl; mod.decls)
-                visitDecl(decl);
-        }
-    }
-
-    override void visitStructDecl(StructDecl s)
-    {
-        auto st = s.env.findType(s.identifier.get).asStruct;
-        s.sym = current.symbol.createMember(
-                s.identifier.get, 
-                st,
-                s.env.find(s.identifier.get)[0]);
-        sf.put(s.sym, st);
-
-        foreach (decl; s.decls)
-        {
-            DType type;
-            char[] name;
-            if (auto varDecl = cast(VarDecl)decl)
-            {
-                type = typeOf(varDecl.varType, varDecl.env);
-                name = varDecl.identifier.get;
-                st.addMember(type, name);
-            }
-            /*
-            else if (auto fd = cast(FuncDecl)decl)
-            {
-                type = fd.type;
-                name = fd.identifier.get;
-            }*/
-        }
-    }
-
-    override void visitClassDecl(ClassDecl s)
-    {
-        auto st = s.env.findType(s.identifier.get).asClass;
-        s.sym = current.symbol.createMember(
-                s.identifier.get, 
-                st,
-                s.env.find(s.identifier.get)[0]);
-
-        sf.put(s.sym, st);
-
-        foreach (decl; s.decls)
-        {
-            DType type;
-            char[] name;
-            if (auto varDecl = cast(VarDecl)decl)
-            {
-                type = typeOf(varDecl.varType, varDecl.env);
-                name = varDecl.identifier.get;
-                st.addMember(type, name);
-            }
-            /*
-            else if (auto fd = cast(FuncDecl)decl)
-            {
-                type = fd.type;
-                name = fd.identifier.get;
-            }*/
-        }
-    }
-
-    override void visitInterfaceDecl(InterfaceDecl s)
-    {
-        auto st = s.env.findType(s.identifier.get).asInterface;
-        s.sym = current.symbol.createMember(
-                s.identifier.get, 
-                st,
-                s.env.find(s.identifier.get)[0]);
-        sf.put(s.sym, st);
-
-        foreach (decl; s.decls)
-        {
-            DType type;
-            char[] name;
-            if (auto varDecl = cast(VarDecl)decl)
-            {
-                type = typeOf(varDecl.varType, varDecl.env);
-                name = varDecl.identifier.get;
-                st.addMember(type, name);
-            }
-            /*
-            else if (auto fd = cast(FuncDecl)decl)
-            {
-                type = fd.type;
-                name = fd.identifier.get;
-            }*/
-        }
-    }
-
-    DType typeOf(Identifier id, Scope sc)
-    {
-        if(auto i = cast(PointerTypeExp)id)
-            return (typeOf(i.pointerOf, sc)).getPointerTo();
-        else if(auto i = cast(StaticArrayTypeExp)id)
-            return typeOf(i.arrayOf, sc).getAsStaticArray(i.size);
-        else if(auto i = cast(FunctionTypeExp)id)
-        {
-            auto d = new DFunction(id);
-            d.returnType = typeOf(i.returnType, sc);
-            foreach (decl ; i.decls)
-                d.params ~= typeOf(decl.varType, sc);
-            return d.getPointerTo;
-        }
-        return sc.findType(id.get);
-    }
-
-    Module current;
-    SymbolFactory sf;
-}
-
-
-/**
-  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;
-
-    static this()
-    {
-        mHandle = new ModuleHandler;
-    }
-
-    this()
-    {
-        sf = new SymbolFactory();
-    }
-
-    override void visit(Module[] modules)
-    {
-        foreach(m ; modules)
-            visitModule(m);
-
-        auto fr = new ForwardReference(sf);
-
-        fr.visit(modules);
-    }
-
-    private void registerBasicTypeTo(char[] n, DType t, Scope sc, Module m)
-    {
-        sc.types[n] = t;
-        auto id = new Identifier(n);
-        id.env = sc;
-        auto decl = new DummyDecl();
-        auto sym = m.symbol.createMember(n, t, decl);
-        sym.decl = decl;
-        decl.sym = sym;
-        decl.env = sc;
-        sc.put(id.get, decl);
-    }
-
-    override void visitModule(Module m)
-    {
-        auto root = new Scope;
-        table ~= root;
-
-        m.symbol = new Symbol;
-
-        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;
-        mHandle.add(m);
-        m.env = current();
-        super.visitModule(m);
-    }
-
-    override void visitDecl(Decl d)
-    {
-        d.env = current();
-        super.visitDecl(d);
-    }
-
-    override void visitImportDecl(ImportDecl i)
-    {
-        i.env.imports ~= i;
-        super.visitImportDecl(i);
-    }
-
-    override void visitStmt(Stmt s)
-    {
-        s.env = current();
-        s.stmtIndex = s.env.stmtIndex;
-        super.visitStmt(s);
-    }
-
-    override void visitExp(Exp e)
-    {
-        e.env = current();
-        e.stmtIndex = e.env.stmtIndex;
-        super.visitExp(e);
-    }
-
-    override void visitFuncDecl(FuncDecl d)
-    {
-        current().put(d.identifier.get, d);
-        d.env = current();
-        auto sc = push();
-
-        visitExp(d.returnType);
-        visitExp(d.identifier);
-        sc.parentFunction = d;
-        foreach (arg; d.funcArgs)
-            visitDecl(arg);
-        foreach (stmt; d.statements)
-        {
-            sc.currentStmtIndex++;
-            visitStmt(stmt);
-        }
-        pop(sc);
-    }
-
-    override void visitVarDecl(VarDecl d)
-    {
-        if (d.init)
-            visitExp(d.init);
-
-        if (need_push > 0 && current().parentFunction !is null) {
-            push();
-            --need_push;
-        }
-
-        if(d.identifier)
-        {
-            auto sc = current();
-            sc.put(d.identifier.get, d);
-            d.env = sc;
-            visitExp(d.varType);
-            visitExp(d.identifier);
-        }
-    }
-
-    override void visitStructDecl(StructDecl s)
-    {
-        auto sc = current();
-        sc.put(s.identifier.get, s);
-        s.env = sc;
-        auto type = new DStruct(s.identifier);
-
-        sc.types[s.identifier.get] = type;
-
-        sc = push();
-        super.visitStructDecl(s);
-        pop(sc);
-    }
-
-    override void visitClassDecl(ClassDecl s)
-    {
-        auto sc = current();
-        sc.put(s.identifier.get, s);
-        s.env = sc;
-        auto type = new DClass(s.identifier);
-
-        sc.types[s.identifier.get] = type;
-
-        sc = push();
-        super.visitClassDecl(s);
-        pop(sc);
-    }
-
-    override void visitInterfaceDecl(InterfaceDecl s)
-    {
-        auto sc = current();
-        sc.put(s.identifier.get, s);
-        s.env = sc;
-        auto type = new DInterface(s.identifier);
-
-        sc.types[s.identifier.get] = type;
-
-        sc = push();
-        super.visitInterfaceDecl(s);
-        pop(sc);
-    }
-
-    override void visitDeclStmt(DeclStmt d)
-    {
-        ++need_push;
-        super.visitDeclStmt(d);
-    }
-    private uint need_push = 0;
-
-    override void visitIfStmt(IfStmt s)
-    {
-        s.env = current();
-        visitExp(s.cond);
-        auto sc = push();
-        visitStmt(s.then_body);
-        pop(sc);
-
-        if (s.else_body !is null)
-        {
-            sc = push();
-            visitStmt(s.else_body);
-            pop(sc);
-        }
-    }
-
-    override void visitWhileStmt(WhileStmt s)
-    {
-        s.env = current();
-        auto sc = push();
-        super.visitWhileStmt(s);
-        pop(sc);
-    }
-
-    override void visitForStmt(ForStmt s)
-    {
-        s.env = current();
-        auto sc = push();
-        super.visitForStmt(s);
-        pop(sc);
-    }
-
-    override void visitCompoundStmt(CompoundStatement s)
-    {
-        s.env = current();
-        auto sc = push();
-        super.visitCompoundStmt(s);
-        pop(sc);
-    }
-
-private:
-    Scope[] table;
-    SymbolFactory sf;
-
-    Scope push()
-    {
-        auto sc = new Scope(current());
-        table ~= sc;
-        return sc;
-    }
-
-    Scope pop(Scope sc = null)
-    {
-        if (sc !is null)
-        {
-            table.length = table.find(sc);
-            return sc;
-        }
-
-        auto res = table[$ - 1];
-        table.length = table.length - 1;
-        return res;
-    }
-
-    Scope current()
-    {
-        return table[$ - 1];
-    }
-}
-
--- a/sema/ScopeCheck.d	Fri Jul 25 15:31:16 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-module sema.ScopeCheck;
-
-import sema.Visitor,
-       sema.Symbol,
-       sema.Scope,
-       sema.DType;
-
-import basic.Message,
-       basic.Attribute;
-
-import tango.io.Stdout;
-
-class ScopeCheck : Visitor!(void)
-{
-
-    this(MessageHandler messages)
-    {
-        this.messages = messages;
-    }
-
-    override void visitIdentifier(Identifier i)
-    {
-        auto symbol = i.env.find(i.get);
-
-        if(symbol is null)
-            messages.report(UndefinedIdentifier, i.loc)
-                .arg(i.get);
-    }
-
-    override void visitVarDecl(VarDecl d)
-    {
-        if(d.identifier.get is null)
-            messages.report(UndefinedType, d.varType.loc)
-                .arg(d.varType.get);
-
-        auto env = d.env;
-        if (d.env.enclosing)
-            if (d.env.enclosing.find(d.identifier.get) !is null)
-                if (d.env.parentFunction !is null)
-                    while( d.env.parentFunction.env !is env)
-                    {
-                        if (d.env.enclosing.find(d.identifier.get)[0].env == env)
-                            messages.report(CannotRedeclare, d.identifier.loc)
-                                .arg(d.identifier.get);
-                        env = env.enclosing;
-                    }
-
-        visitExp(d.identifier);
-        if (d.init)
-            visitExp(d.init);
-    }
-
-    override void visitFuncDecl(FuncDecl f)
-    {
-        visitExp(f.identifier);
-
-        inFunction = true;
-        foreach (stmt; f.statements)
-            visitStmt(stmt);
-        inFunction = false;
-    }
-
-    override void visitImportDecl(ImportDecl) { }
-
-    override void visitCastExp(CastExp exp)
-    {
-        visitExp(exp.exp);
-    }
-
-    override void visitMemberReference(MemberReference m)
-    {
-        internalVisitMemberRef(m);
-    }
-
-    private Symbol internalVisitMemberRef(MemberReference m)
-    {
-        Symbol visitRef(MemberReference m, Identifier target, Symbol st)
-        {
-            auto child = m.child;
-            auto res = st.findMembers(child.get);
-
-            if(!res.length)
-                messages.report(MissingMember, m.loc)
-                    .arg(st.type.name)
-                    .arg(target.get)
-                    .arg(child.get);
-            else
-                internalCheckProtection(res[0], child);
-
-            return res.length ? res[0] : null;
-        }
-        switch(m.target.expType)
-        {
-            case ExpType.Identifier:
-                return visitRef(m, cast(Identifier)m.target,
-                        (cast(Identifier)m.target).getSymbol);
-            case ExpType.MemberReference:
-                Symbol s = internalVisitMemberRef(cast(MemberReference)m.target);
-                if(!s)
-                    return null;
-                return visitRef(m, cast(Identifier)m.target, s);
-        }
-    }
-
-    override void visitExp(Exp exp)
-    {
-        if (exp.expType == ExpType.Identifier && inFunction
-            && exp.env.find((cast(Identifier)exp).get) !is null)
-        {
-            if (exp.env.findType((cast(Identifier)exp).get) is null)
-                internalCheckProtection(
-                    exp.env.find((cast(Identifier)exp).get)[0].sym, 
-                    cast(Identifier)exp);
-        }
-
-        super.visitExp(exp);
-    }
-
-    private void internalCheckProtection(Symbol sym, Identifier iden)
-    {
-        if (isChildOf(sym.decl.env, iden.env))
-            return;
-
-        switch(sym.decl.att.getProtection)
-        {
-            case Protection.Private:
-/*                if (iden.env.inModule == sym.decl.getIdentifier.env.inModule
-                    && sym.decl.getIdentifier.env.enclosing == iden.env.inModule)
-                {}
-                else*/
-                messages.report(CannotAccessPrivate, iden.loc);
-                return;
-            default:
-                return;
-        }
-    }
-
-    private bool isChildOf(Scope parent, Scope child)
-    {
-        if (child is parent)
-            return true;
-
-        if (child.enclosing !is null)
-            return isChildOf(parent, child.enclosing);
-
-        return false;
-    }
-
-    private bool isType(char[] s)
-    {
-        return (s in types? true : false);
-    }
-
-    int[char[]] types;
-    MessageHandler messages;
-    bool inFunction;
-}
-
--- a/sema/TypeCheck.d	Fri Jul 25 15:31:16 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,475 +0,0 @@
-module sema.TypeCheck;
-
-import sema.Visitor,
-       sema.Symbol,
-       sema.DType;
-
-import tango.io.Stdout,
-       Integer = tango.text.convert.Integer;
-
-import basic.SourceLocation,
-       basic.Message;
-
-class TypeCheck : Visitor!(void)
-{
-    this(MessageHandler messages)
-    {
-        this.messages = messages;
-    }
-
-    override void visitBinaryExp(BinaryExp exp)
-    {
-        super.visitBinaryExp(exp);
-
-        if(!(exp.left.type is exp.right.type))
-        {
-            if (!exp.right.type.hasImplicitConversionTo(exp.left.type) &&
-                !exp.left.type.hasImplicitConversionTo(exp.right.type))
-                messages.report(InvalidImplicitCast, exp.loc)
-                    .arg(exp.right.type.toString)
-                    .arg(exp.left.type.toString);
-            else
-            {
-                CastExp castExp;
-                if(exp.left.type.isReal && exp.right.type.isReal)
-                    if(exp.left.type.byteSize > exp.right.type.byteSize)
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.left.type.name),
-                            exp.right);
-                    else
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.right.type.name),
-                            exp.left);
-                else if(exp.left.type.isReal || exp.right.type.isReal)
-                    if(exp.left.type.isReal)
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.left.type.name),
-                            exp.right);
-                    else
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.right.type.name),
-                            exp.left);
-                else
-                    if(exp.left.type.byteSize > exp.right.type.byteSize)
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.left.type.name),
-                            exp.right);
-                    else if(exp.left.type.byteSize > exp.right.type.byteSize)
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.right.type.name),
-                            exp.left);
-                    else
-                        castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(exp.left.type.name),
-                            exp.right);
-
-
-                if(castExp)
-                {
-                    castExp.env = exp.env;
-                    if(castExp.exp == exp.right)
-                        exp.right = castExp;
-                    else
-                        exp.left = castExp;
-
-                }
-            }
-        }
-        if (exp.op >= BinaryExp.Operator.LeftShift &&
-            exp.op <= BinaryExp.Operator.UnsignedRightShift)
-        {}  // FIXME: When we have const-system we need to check for 
-            //        right site being larger then the bitsize of the 
-            //        left
-    }
-
-    override void visitDerefExp(DerefExp exp)
-    {
-        if (!exp.exp.type.isPointer)
-        {
-            messages.report(CanOnlyDerefPointers,
-                    [exp.exp.sourceRange][], 
-                    [exp.loc])
-                .arg(exp.exp.type.toString);
-
-            exp._type = DType.Int;
-        }
-    }
-
-    override void visitCallExp(CallExp exp)
-    {
-        super.visitCallExp(exp);
-
-        if (auto iden = cast(MemberReference)exp.exp)
-        {
-            Symbol[] internalVisitMemberRef(MemberReference m)
-            {
-                Symbol[] visitRef(MemberReference m, Identifier target, Symbol st)
-                {
-                    auto child = m.child;
-                    auto res = st.findMembers(child.get);
-                    return res;
-                }
-                switch(m.target.expType)
-                {
-                    case ExpType.Identifier:
-                        return visitRef(m, cast(Identifier)m.target,
-                                (cast(Identifier)m.target).getSymbol);
-                    case ExpType.MemberReference:
-                        Symbol[] s = internalVisitMemberRef(cast(MemberReference)m.target);
-                        if(s.length)
-                            return s;
-                        return visitRef(m, cast(Identifier)m.target, s[0]);
-                }
-            }
-
-            Exp[] newArgs;
-
-            DFunction function_type;
-            if (iden.type.isFunction())
-            {
-                Symbol[] methods = internalVisitMemberRef(iden);           
-
-                if (!methods.length)
-                {
-                    messages.report(NoMethodByName, iden.loc);
-                    return;
-                }
-
-                Symbol sel = getBestMatch(exp.args, methods);
-                exp.callSym = sel;
-                if (sel)
-                    function_type = sel.type.asFunction();
-                else
-                {
-                    messages.report(NoMachingMethod, exp.loc);
-                    foreach ( i, s ; methods )
-                    {
-                        messages.report(CandidateNr, 
-                                (cast(FuncDecl)s.decl).identifier.loc)
-                            .arg(Integer.toString(i+1));
-                    }
-                }
-            }
-            else if (iden.type.isCallable)
-                function_type = iden.type.asCallable();
-            else assert(0, "Should not happen");
-
-            foreach (i, arg; exp.args)
-            {
-                auto argType = function_type.params[i];
-                auto expType = arg.type;
-                if (argType.isSame(expType))
-                {
-                    if (!expType.hasImplicitConversionTo(argType))
-                        messages.report(InvalidImplicitCast, exp.loc)
-                            .arg(expType.toString)
-                            .arg(argType.toString);
-
-                    auto castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(argType.name),
-                            arg);
-                    castExp.env = iden.env;
-                    newArgs ~= castExp;
-                }
-                else
-                    newArgs ~= arg;
-            }
-            exp.args = newArgs;
-        }
-        else if (auto iden = cast(Identifier)exp.exp)
-        {
-            Exp[] newArgs;
-
-            DFunction function_type;
-            if (iden.type.isFunction())
-            {
-                Symbol[] methods;
-
-                foreach (decl ; iden.env.find(iden.get))
-                    methods ~= decl.sym;
-
-                if (!methods.length)
-                {
-                    messages.report(NoMethodByName, iden.loc);
-                    return;
-                }
-
-                Symbol sel = getBestMatch(exp.args, methods);
-                exp.callSym = sel;
-                if (sel)
-                    function_type = sel.type.asFunction();
-                else
-                {
-                    messages.report(NoMachingMethod, exp.loc);
-                    foreach ( i, s ; methods )
-                    {
-                        messages.report(CandidateNr, 
-                                (cast(FuncDecl)s.decl).identifier.loc)
-                            .arg(Integer.toString(i+1));
-                    }
-                }
-            }
-            else if (iden.type.isCallable)
-            {
-                function_type = iden.type.asCallable();
-                if (exp.args.length != function_type.params.length)
-                {
-                    messages.report(CannotCallMethod, exp.loc)
-                        .arg(iden.type.toString)
-                        .arg(exp.callerType.toString);
-                }
-            }
-            else assert(0, "Should not happen");
-
-            foreach (i, arg; exp.args)
-            {
-                auto argType = function_type.params[i];
-                auto expType = arg.type;
-                if (!argType.isSame(expType))
-                {
-                    if (!expType.hasImplicitConversionTo(argType))
-                        messages.report(InvalidImplicitCast, exp.loc)
-                            .arg(expType.toString)
-                            .arg(argType.toString);
-
-                    auto castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(argType.name),
-                            arg);
-                    castExp.env = iden.env;
-                    newArgs ~= castExp;
-                }
-                else
-                    newArgs ~= arg;
-            }
-            exp.args = newArgs;
-        }
-        else
-        {
-            Exp[] newArgs;
-
-            foreach(i, arg; exp.args)
-            {
-                auto argType = exp.exp.type.asFunction.params[i];
-                auto expType = arg.type;
-                if(!argType.isSame(expType))
-                {
-                    if(!expType.hasImplicitConversionTo(argType))
-                        messages.report(InvalidImplicitCast, exp.loc)
-                            .arg(expType.toString)
-                            .arg(argType.toString);
-
-                    auto castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(argType.name),
-                            arg);
-                    castExp.env = exp.exp.env;
-                    newArgs ~= castExp;
-                }
-                else
-                    newArgs ~= arg;
-            }
-
-            exp.args = newArgs;
-        }
-    }
-
-    override void visitNewExp(NewExp exp)
-    {
-        super.visitNewExp(exp);
-
-        Exp[] newArgs;
-        
-        Symbol[] methods = exp.newType.getSymbol.findFunctionMembers("this");
-
-        if (!methods.length)
-        {
-            messages.report(NoConstructor, exp.newType.loc);
-            return;
-        }
-
-        Symbol sel = getBestMatch(exp.c_args, methods);
-
-        if (sel)
-        {
-            foreach (i, arg; exp.c_args)
-            {
-                auto argType = sel.type.asFunction.params[i];
-                auto expType = arg.type;
-                if (!argType.isSame(expType))
-                {
-                    if (!expType.hasImplicitConversionTo(argType))
-                        messages.report(InvalidImplicitCast, exp.loc)
-                            .arg(expType.toString)
-                            .arg(argType.toString);
-
-                    auto castExp = new CastExp(
-                            SLoc.Invalid,
-                            new Identifier(argType.name),
-                            arg);
-                    castExp.env = exp.newType.env;
-                    newArgs ~= castExp;
-                }
-                else
-                    newArgs ~= arg;
-            }
-            exp.c_args = newArgs;
-            exp.callSym = sel;
-        }
-        else
-        {
-            messages.report(NoMachingCon, exp.newType.loc);
-            foreach ( i, s ; methods )
-            {
-                messages.report(CandidateNr, 
-                        (cast(FuncDecl)s.decl).identifier.loc)
-                    .arg(Integer.toString(i+1));
-            }
-        }
-    }
-
-    override void visitAssignExp(AssignExp exp)
-    {
-        super.visitAssignExp(exp);
-
-        auto identifierType = exp.identifier.type;
-        auto expType = exp.exp.type;
-
-        if(!identifierType.isSame(expType))
-        {
-            if(!expType.hasImplicitConversionTo(identifierType))
-                messages.report(InvalidImplicitCast, 
-                        [exp.identifier.sourceRange, exp.exp.sourceRange][], 
-                        [exp.loc])
-                    .arg(expType.toString)
-                    .arg(identifierType.toString);
-
-            auto castExp = new CastExp(
-                    SLoc.Invalid,
-                    new Identifier(identifierType.name),
-                    exp.exp);
-            castExp.env = exp.exp.env;
-            exp.exp = castExp;
-        }
-
-        if (expType.isStaticArray)
-            messages.report(CannotReassignSArray, 
-                    [exp.identifier.sourceRange, exp.exp.sourceRange][], 
-                    [exp.loc]);
-    }
-
-    override void visitReturnStmt(ReturnStmt stmt)
-    {
-        super.visitReturnStmt(stmt);
-
-        if(stmt.exp)
-        {
-            auto returnType = stmt.env.parentFunction.type.asFunction.returnType;
-            auto expType = stmt.exp.type;
-            if(!returnType.isSame(expType))
-            {
-                if(!expType.hasImplicitConversionTo(returnType))
-                   messages.report(InvalidImplicitCast, stmt.exp.loc)
-                        .arg(expType.toString)
-                        .arg(returnType.toString);
-
-                auto castExp = new CastExp(
-                        SLoc.Invalid,
-                        new Identifier(returnType.name),
-                        stmt.exp);
-                castExp.env = stmt.exp.env;
-                stmt.exp = castExp;
-            }
-        }
-    }
-
-    override void visitVarDecl(VarDecl decl)
-    {
-        super.visitVarDecl(decl);
-
-        if(decl.init)
-        {
-            auto varType = decl.identifier.type;
-            auto expType = decl.init.type;
-            if(!varType.isSame(expType))
-            {
-                if(!expType.hasImplicitConversionTo(varType))
-                   messages.report(InvalidImplicitCast, decl.init.loc)
-                        .arg(expType.toString)
-                        .arg(varType.toString);
-
-                auto castExp = new CastExp(
-                        SLoc.Invalid,
-                        new Identifier(varType.name),
-                        decl.init);
-                castExp.env = decl.init.env;
-                decl.init = castExp;
-            }
-        }
-    }
-
-    private Symbol getBestMatch(Exp[] arg_list , Symbol[] available)
-    in
-    {
-        foreach (a ; available)
-            assert(a.type.isFunction, "A non-function found in available-list.");
-    }
-    body
-    {
-        assert(available.length, "No available methods in symbol-list.");
-
-        Symbol[] possible;
-        Symbol perfect;
-
-        bool per, work;
-        foreach (s ; available)
-        {
-            if (s.type.asFunction.params.length < arg_list.length)
-                continue;
-
-            per = true;
-            work = true;
-
-            foreach (i, arg; arg_list)
-            {
-                auto argType = s.type.asFunction.params[i];
-                auto expType = arg.type;
-                if (argType.isSame(expType))
-                {
-                    per = false;
-                    if( !expType.hasImplicitConversionTo(argType) )
-                    {
-                        work = false;
-                        break;
-                    }
-                }
-            }
-
-            foreach (a ; (cast(FuncDecl)s.decl).funcArgs[arg_list.length..$])
-                if (a.init is null)
-                    work = false;
-
-            if (work)
-                if (per)
-                    return s;
-                else
-                    possible ~= s;
-        }
-
-        if (possible.length)
-            return possible[0];
-
-        return null;
-    }
-
-    MessageHandler messages;
-}
-
--- a/sema/Visitor.d	Fri Jul 25 15:31:16 2008 +0200
+++ b/sema/Visitor.d	Tue Jul 29 13:54:44 2008 +0200
@@ -49,6 +49,8 @@
                 return visitClassDecl(cast(ClassDecl)decl);
             case DeclType.InterfaceDecl:
                 return visitInterfaceDecl(cast(InterfaceDecl)decl);
+            case DeclType.AliasDecl:
+                return visitAliasDecl(cast(AliasDecl)decl);
             default:
                 throw new Exception("Unknown declaration type");
         }
@@ -119,6 +121,8 @@
                 return visitNewExp(cast(NewExp)exp);
             case ExpType.ArrayLiteralExp:
                 return visitArrayLiteralExp(cast(ArrayLiteralExp)exp);
+            case ExpType.NullExp:
+                return visitNullExp(cast(NullExp)exp);
             default:
                 throw new Exception("Unknown expression type");
         }
@@ -217,6 +221,14 @@
             return DeclT.init;
     }
 
+    DeclT visitAliasDecl(AliasDecl a)
+    {
+        static if (is(DeclT == void))
+            return;
+        else
+            return DeclT.init;
+    }
+
     // Statements:
     StmtT visitReturnStmt(ReturnStmt s)
     {
@@ -485,5 +497,13 @@
         else
             return ExpT.init;
     }
+
+    ExpT visitNullExp(NullExp n)
+    {
+        static if (is(ExpT == void))
+            return;
+        else
+            return ExpT.init;
+    }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/alias_1.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,21 @@
+
+int foo(int x)
+{
+    return x + 6;
+}
+
+alias foo bar;
+alias int** i;
+alias int A;
+alias int B;
+
+int main()
+{
+    int x = bar(5);
+    i y = &x;
+
+    A a = 5;
+    B b = a;
+
+    return 11 - *y;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/parser/null_1.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,7 @@
+
+int main()
+{
+    int* i = null;
+
+    return 0;
+}