[csharp] repl using statement fix + support for --fatal
[mono.git] / mcs / mcs / driver.cs
index aec29363217ed27e1bdc56e930f55eaeb6487768..92eb72e87d42e5859a46f0cadbaf29d331c9d4a7 100644 (file)
 // Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
 //
 
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics;
+
 namespace Mono.CSharp
 {
-       using System;
-       using System.Reflection;
-       using System.Reflection.Emit;
-       using System.Collections;
-       using System.Collections.Specialized;
-       using System.IO;
-       using System.Text;
-       using System.Globalization;
-       using System.Diagnostics;
-
-       public enum Target {
-               Library, Exe, Module, WinExe
-       };
-       
        /// <summary>
        ///    The compiler driver.
        /// </summary>
        class Driver
        {
-               //
-               // Assemblies references to be linked.   Initialized with
-               // mscorlib.dll here.
-               static ArrayList references;
-
-               //
-               // If any of these fail, we ignore the problem.  This is so
-               // that we can list all the assemblies in Windows and not fail
-               // if they are missing on Linux.
-               //
-               static ArrayList soft_references;
-
-               // 
-               // External aliases for assemblies.
-               //
-               static Hashtable external_aliases;
-
-               //
-               // Modules to be linked
-               //
-               static ArrayList modules;
-
-               // Lookup paths
-               static ArrayList link_paths;
-
-               // Whether we want to only run the tokenizer
-               bool tokenize;
-               
                string first_source;
 
-               bool want_debugging_support;
-               bool parse_only;
                bool timestamps;
+               internal int fatal_errors;
                
-               //
-               // Whether to load the initial config file (what CSC.RSP has by default)
-               // 
-               bool load_default_config = true;
-
-               //
-               // A list of resource files
-               //
-               static Resources embedded_resources;
-               static string win32ResourceFile;
-               static string win32IconFile;
-
-               //
-               // Output file
-               //
-               static string output_file;
-
                //
                // Last time we took the time
                //
-               DateTime last_time, first_time;
+               Stopwatch stopwatch;
+               DateTime first_time;
 
-               //
-               // Encoding.
-               //
-               Encoding encoding;
+               internal readonly CompilerContext ctx;
 
                static readonly char[] argument_value_separator = new char [] { ';', ',' };
 
-               static public void Reset ()
+               private Driver (CompilerContext ctx)
                {
-                       embedded_resources = null;
-                       win32ResourceFile = win32IconFile = null;
-                       output_file = null;
+                       this.ctx = ctx;
                }
 
-               public Driver ()
+               public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
                {
-                       encoding = Encoding.Default;
-               }
+                       Driver d = new Driver (new CompilerContext (new Report (printer)));
 
-               public static Driver Create (string [] args, bool require_files)
-               {
-                       Driver d = new Driver ();
                        if (!d.ParseArguments (args, require_files))
                                return null;
 
                        return d;
                }
 
+               Report Report {
+                       get { return ctx.Report; }
+               }
+
                void ShowTime (string msg)
                {
                        if (!timestamps)
                                return;
 
-                       DateTime now = DateTime.Now;
-                       TimeSpan span = now - last_time;
-                       last_time = now;
+                       stopwatch.Stop ();
 
-                       Console.WriteLine (
-                               "[{0:00}:{1:000}] {2}",
-                               (int) span.TotalSeconds, span.Milliseconds, msg);
+                       Console.WriteLine ("{0,5}ms {1}", stopwatch.ElapsedMilliseconds, msg);
+
+                       stopwatch = Stopwatch.StartNew ();
                }
 
                void ShowTotalTime (string msg)
@@ -137,14 +80,13 @@ namespace Mono.CSharp
 
                        DateTime now = DateTime.Now;
                        TimeSpan span = now - first_time;
-                       last_time = now;
 
                        Console.WriteLine (
                                "[{0:00}:{1:000}] {2}",
                                (int) span.TotalSeconds, span.Milliseconds, msg);
                }              
               
-               void tokenize_file (CompilationUnit file)
+               void tokenize_file (CompilationUnit file, CompilerContext ctx)
                {
                        Stream input;
 
@@ -156,8 +98,8 @@ namespace Mono.CSharp
                        }
 
                        using (input){
-                               SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-                               Tokenizer lexer = new Tokenizer (reader, file);
+                               SeekableStreamReader reader = new SeekableStreamReader (input, RootContext.Encoding);
+                               Tokenizer lexer = new Tokenizer (reader, file, ctx);
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
@@ -171,7 +113,7 @@ namespace Mono.CSharp
                        return;
                }
 
-               void Parse (CompilationUnit file)
+               void Parse (CompilationUnit file, ModuleContainer module)
                {
                        Stream input;
 
@@ -182,42 +124,37 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-
                        // Check 'MZ' header
-                       if (reader.Read () == 77 && reader.Read () == 90) {
+                       if (input.ReadByte () == 77 && input.ReadByte () == 90) {
                                Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
                                input.Close ();
                                return;
                        }
 
-                       reader.Position = 0;
-                       Parse (reader, file);
+                       input.Position = 0;
+                       SeekableStreamReader reader = new SeekableStreamReader (input, RootContext.Encoding);
+
+                       Parse (reader, file, module);
+                       reader.Dispose ();
                        input.Close ();
                }       
                
-               void Parse (SeekableStreamReader reader, CompilationUnit file)
+               void Parse (SeekableStreamReader reader, CompilationUnit file, ModuleContainer module)
                {
-                       CSharpParser parser = new CSharpParser (reader, file);
-                       parser.ErrorOutput = Report.Stderr;
-                       try {
-                               parser.parse ();
-                       } catch (Exception ex) {
-                               Report.Error(589, parser.Lexer.Location,
-                                       "Compilation aborted in file `{0}', {1}", file.Name, ex);
-                       }
+                       CSharpParser parser = new CSharpParser (reader, file, module);
+                       parser.parse ();
                }
 
                static void OtherFlags ()
                {
                        Console.WriteLine (
                                "Other flags in the compiler\n" +
-                               "   --fatal            Makes errors fatal\n" +
+                               "   --fatal[=COUNT]    Makes errors after COUNT fatal\n" +
+                               "   --lint             Enhanced warnings\n" +
                                "   --parse            Only parses the source file\n" +
-                               "   --typetest         Tests the tokenizer's built-in type parser\n" +
+                               "   --runtime:VERSION  Sets mscorlib.dll metadata version: v1, v2, v4\n" +
                                "   --stacktrace       Shows stack trace at error location\n" +
                                "   --timestamp        Displays time stamps of various compiler events\n" +
-                               "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -v                 Verbose parsing (for debugging the parser)\n" + 
                                "   --mcs-debug X      Sets MCS debugging level to X\n");
                }
@@ -225,13 +162,13 @@ namespace Mono.CSharp
                static void Usage ()
                {
                        Console.WriteLine (
-                               "Mono C# compiler, Copyright 2001 - 2008 Novell, Inc.\n" +
+                               "Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
                                "mcs [options] source-files\n" +
                                "   --about              About the Mono C# compiler\n" +
                                "   -addmodule:M1[,Mn]   Adds the module to the generated assembly\n" + 
                                "   -checked[+|-]        Sets default aritmetic overflow context\n" +
-                               "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
                                "   -clscheck[+|-]       Disables CLS Compliance verifications\n" +
+                               "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
                                "   -define:S1[;S2]      Defines one or more conditional symbols (short: -d)\n" +
                                "   -debug[+|-], -g      Generate debugging information\n" + 
                                "   -delaysign[+|-]      Only insert the public key into the assembly (no signing)\n" +
@@ -239,7 +176,7 @@ namespace Mono.CSharp
                                "   -help                Lists all compiler options (short: -?)\n" + 
                                "   -keycontainer:NAME   The key pair container used to sign the output assembly\n" +
                                "   -keyfile:FILE        The key file used to strongname the ouput assembly\n" +
-                               "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, Default, or future\n" + 
+                               "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, 3, Default, or Future\n" + 
                                "   -lib:PATH1[,PATHn]   Specifies the location of referenced assemblies\n" +
                                "   -main:CLASS          Specifies the class with the Main method (short: -m)\n" +
                                "   -noconfig            Disables implicitly referenced assemblies\n" +
@@ -247,19 +184,21 @@ namespace Mono.CSharp
                                "   -nowarn:W1[,Wn]      Suppress one or more compiler warnings\n" + 
                                "   -optimize[+|-]       Enables advanced compiler optimizations (short: -o)\n" + 
                                "   -out:FILE            Specifies output assembly name\n" +
-#if !SMCS_SOURCE
                                "   -pkg:P1[,Pn]         References packages P1..Pn\n" + 
-#endif
+                               "   -platform:ARCH       Specifies the target platform of the output assembly\n" +
+                               "                        ARCH can be one of: anycpu, x86, x64 or itanium\n" +
                                "   -recurse:SPEC        Recursively compiles files according to SPEC pattern\n" + 
                                "   -reference:A1[,An]   Imports metadata from the specified assembly (short: -r)\n" +
-                               "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +                         
+                               "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +
+                               "   -sdk:VERSION         Specifies SDK version of referenced assemlies\n" +
+                               "                        VERSION can be one of: 2 (default), 4\n" +
                                "   -target:KIND         Specifies the format of the output assembly (short: -t)\n" +
                                "                        KIND can be one of: exe, winexe, library, module\n" +
                                "   -unsafe[+|-]         Allows to compile code which uses unsafe keyword\n" +
                                "   -warnaserror[+|-]    Treats all warnings as errors\n" +
-                               "   -warnaserror:W1[,Wn] Treats one or more compiler warnings as errors\n" +
+                               "   -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
                                "   -warn:0-4            Sets warning level, the default is 4 (short -w:)\n" +
-                               "   -help2               Shows internal compiler options\n" + 
+                               "   -helpinternal        Shows internal and advanced compiler options\n" + 
                                "\n" +
                                "Resources:\n" +
                                "   -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
@@ -270,7 +209,7 @@ namespace Mono.CSharp
                                "Options can be of the form -option or /option");
                }
 
-               static void TargetUsage ()
+               void TargetUsage ()
                {
                        Report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
                }
@@ -278,7 +217,7 @@ namespace Mono.CSharp
                static void About ()
                {
                        Console.WriteLine (
-                               "The Mono C# compiler is Copyright 2001-2008, Novell, Inc.\n\n" +
+                               "The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
                                "The compiler source code is released under the terms of the \n"+
                                "MIT X11 or GNU GPL licenses\n\n" +
 
@@ -291,200 +230,33 @@ namespace Mono.CSharp
 
                public static int Main (string[] args)
                {
-                       RootContext.Version = LanguageVersion.Default;
-
                        Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
-
-                       Driver d = Driver.Create (args, true);
+                       var crp = new ConsoleReportPrinter ();
+                       Driver d = Driver.Create (args, true, crp);
                        if (d == null)
                                return 1;
 
-                       else if (d.Compile () && Report.Errors == 0) {
-                               if (Report.Warnings > 0) {
-                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
-                               }
-                               return 0;
-                       } else {
-                               Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
-                                       Report.Errors, Report.Warnings);
-                               return 1;
-                       }
-               }
-
-               static public void LoadAssembly (string assembly, bool soft)
-               {
-                       LoadAssembly (assembly, null, soft);
-               }
-
-               static void Error6 (string name, string log)
-               {
-                       if (log != null && log.Length > 0)
-                               Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
-                       Report.Error (6, "cannot find metadata file `{0}'", name);
-               }
+                       crp.Fatal = d.fatal_errors;
 
-               static void Error9 (string type, string filename, string log)
-               {
-                       if (log != null && log.Length > 0)
-                               Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
-                       Report.Error (9, "file `{0}' has invalid `{1}' metadata", filename, type);
-               }
-
-               static void BadAssembly (string filename, string log)
-               {
-                       MethodInfo adder_method = AssemblyClass.AddModule_Method;
-
-                       if (adder_method != null) {
-                               AssemblyName an = new AssemblyName ();
-                               an.Name = ".temp";
-                               AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
-                               try {
-                                       object m = null;
-                                       try {
-                                               m = adder_method.Invoke (ab, new object [] { filename });
-                                       } catch (TargetInvocationException ex) {
-                                               throw ex.InnerException;
-                                       }
-
-                                       if (m != null) {
-                                               Report.Error (1509, "Referenced file `{0}' is not an assembly. Consider using `-addmodule' option instead",
-                                                             Path.GetFileName (filename));
-                                               return;
-                                       }
-                               } catch (FileNotFoundException) {
-                                       // did the file get deleted during compilation? who cares? swallow the exception
-                               } catch (BadImageFormatException) {
-                                       // swallow exception
-                               } catch (FileLoadException) {
-                                       // swallow exception
-                               }
-                       }
-                       Error9 ("assembly", filename, log);
-               }
-
-               static public void LoadAssembly (string assembly, string alias, bool soft)
-               {
-                       Assembly a = null;
-                       string total_log = "";
-
-                       try {
-                               try {
-                                       char[] path_chars = { '/', '\\' };
-
-                                       if (assembly.IndexOfAny (path_chars) != -1) {
-                                               a = Assembly.LoadFrom (assembly);
-                                       } else {
-                                               string ass = assembly;
-                                               if (ass.EndsWith (".dll") || ass.EndsWith (".exe"))
-                                                       ass = assembly.Substring (0, assembly.Length - 4);
-                                               a = Assembly.Load (ass);
-                                       }
-                               } catch (FileNotFoundException) {
-                                       bool err = !soft;
-                                       foreach (string dir in link_paths) {
-                                               string full_path = Path.Combine (dir, assembly);
-                                               if (!assembly.EndsWith (".dll") && !assembly.EndsWith (".exe"))
-                                                       full_path += ".dll";
-
-                                               try {
-                                                       a = Assembly.LoadFrom (full_path);
-                                                       err = false;
-                                                       break;
-                                               } catch (FileNotFoundException ff) {
-                                                       if (soft)
-                                                               return;
-                                                       total_log += ff.FusionLog;
-                                               }
-                                       }
-                                       if (err) {
-                                               Error6 (assembly, total_log);
-                                               return;
-                                       }
-                               }
-
-                               // Extern aliased refs require special handling
-                               if (alias == null)
-                                       RootNamespace.Global.AddAssemblyReference (a);
-                               else
-                                       RootNamespace.DefineRootNamespace (alias, a);
-
-                       } catch (BadImageFormatException f) {
-                               // .NET 2.0 throws this if we try to load a module without an assembly manifest ...
-                               BadAssembly (f.FileName, f.FusionLog);
-                       } catch (FileLoadException f) {
-                               // ... while .NET 1.1 throws this
-                               BadAssembly (f.FileName, f.FusionLog);
-                       }
-               }
-
-               static public void LoadModule (string module)
-               {
-                       Module m = null;
-                       string total_log = "";
-
-                       try {
-                               try {
-                                       m = CodeGen.Assembly.AddModule (module);
-                               } catch (FileNotFoundException) {
-                                       bool err = true;
-                                       foreach (string dir in link_paths) {
-                                               string full_path = Path.Combine (dir, module);
-                                               if (!module.EndsWith (".netmodule"))
-                                                       full_path += ".netmodule";
-
-                                               try {
-                                                       m = CodeGen.Assembly.AddModule (full_path);
-                                                       err = false;
-                                                       break;
-                                               } catch (FileNotFoundException ff) {
-                                                       total_log += ff.FusionLog;
-                                               }
-                                       }
-                                       if (err) {
-                                               Error6 (module, total_log);
-                                               return;
-                                       }
+                       if (d.Compile () && d.Report.Errors == 0) {
+                               if (d.Report.Warnings > 0) {
+                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", d.Report.Warnings);
                                }
-
-                               RootNamespace.Global.AddModuleReference (m);
-
-                       } catch (BadImageFormatException f) {
-                               Error9 ("module", f.FileName, f.FusionLog);
-                       } catch (FileLoadException f) {
-                               Error9 ("module", f.FileName, f.FusionLog);
+                               Environment.Exit (0);
+                               return 0;
                        }
-               }
-
-               /// <summary>
-               ///   Loads all assemblies referenced on the command line
-               /// </summary>
-               static public void LoadReferences ()
-               {
-                       link_paths.Add (GetSystemDir ());
-                       link_paths.Add (Directory.GetCurrentDirectory ());
-
-                       //
-                       // Load Core Library for default compilation
-                       //
-                       if (RootContext.StdLib)
-                               LoadAssembly ("mscorlib", false);
-
-                       foreach (string r in soft_references)
-                               LoadAssembly (r, true);
-
-                       foreach (string r in references)
-                               LoadAssembly (r, false);
-
-                       foreach (DictionaryEntry entry in external_aliases)
-                               LoadAssembly ((string) entry.Value, (string) entry.Key, false);
-                               
-                       RootNamespace.ComputeNamespaces ();
+                       
+                       
+                       Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
+                               d.Report.Errors, d.Report.Warnings);
+                       Environment.Exit (1);
+                       return 1;
                }
 
                static string [] LoadArgs (string file)
                {
                        StreamReader f;
-                       ArrayList args = new ArrayList ();
+                       var args = new List<string> ();
                        string line;
                        try {
                                f = new StreamReader (file);
@@ -524,18 +296,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       string [] ret_value = new string [args.Count];
-                       args.CopyTo (ret_value, 0);
-
-                       return ret_value;
-               }
-
-               //
-               // Returns the directory where the system assemblies are installed
-               //
-               static string GetSystemDir ()
-               {
-                       return Path.GetDirectoryName (typeof (object).Assembly.Location);
+                       return args.ToArray ();
                }
 
                //
@@ -575,18 +336,12 @@ namespace Mono.CSharp
                        if (first_source == null)
                                first_source = f;
 
-                       Location.AddFile (f);
+                       Location.AddFile (Report, f);
                }
 
                bool ParseArguments (string[] args, bool require_files)
                {
-                       references = new ArrayList ();
-                       external_aliases = new Hashtable ();
-                       soft_references = new ArrayList ();
-                       modules = new ArrayList (2);
-                       link_paths = new ArrayList ();
-
-                       ArrayList response_file_list = null;
+                       List<string> response_file_list = null;
                        bool parsing_options = true;
 
                        for (int i = 0; i < args.Length; i++) {
@@ -599,7 +354,7 @@ namespace Mono.CSharp
                                        string response_file = arg.Substring (1);
 
                                        if (response_file_list == null)
-                                               response_file_list = new ArrayList ();
+                                               response_file_list = new List<string> ();
 
                                        if (response_file_list.Contains (response_file)) {
                                                Report.Error (
@@ -671,7 +426,7 @@ namespace Mono.CSharp
                        //
                        // If there is nothing to put in the assembly, and we are not a library
                        //
-                       if (first_source == null && embedded_resources == null) {
+                       if (first_source == null && RootContext.Resources == null) {
                                Report.Error (2008, "No files to compile were specified");
                                return false;
                        }
@@ -679,16 +434,16 @@ namespace Mono.CSharp
                        return true;
                }
 
-               public void Parse ()
+               public void Parse (ModuleContainer module)
                {
                        Location.Initialize ();
 
-                       ArrayList cu = Location.SourceFiles;
+                       var cu = Location.SourceFiles;
                        for (int i = 0; i < cu.Count; ++i) {
-                               if (tokenize) {
-                                       tokenize_file ((CompilationUnit) cu [i]);
+                               if (RootContext.TokenizeOnly) {
+                                       tokenize_file (cu [i], ctx);
                                } else {
-                                       Parse ((CompilationUnit) cu [i]);
+                                       Parse (cu [i], module);
                                }
                        }
                }
@@ -735,65 +490,7 @@ namespace Mono.CSharp
                        }
                }
 
-               public void ProcessDefaultConfig ()
-               {
-                       if (!load_default_config)
-                               return;
-       
-                       //
-                       // For now the "default config" is harcoded into the compiler
-                       // we can move this outside later
-                       //
-                       string [] default_config = {
-                               "System",
-                               "System.Xml",
-#if NET_2_1
-                               "System.Net",
-                               "System.Windows",
-                               "System.Windows.Browser",
-#endif
-#if false
-                               //
-                               // Is it worth pre-loading all this stuff?
-                               //
-                               "Accessibility",
-                               "System.Configuration.Install",
-                               "System.Data",
-                               "System.Design",
-                               "System.DirectoryServices",
-                               "System.Drawing.Design",
-                               "System.Drawing",
-                               "System.EnterpriseServices",
-                               "System.Management",
-                               "System.Messaging",
-                               "System.Runtime.Remoting",
-                               "System.Runtime.Serialization.Formatters.Soap",
-                               "System.Security",
-                               "System.ServiceProcess",
-                               "System.Web",
-                               "System.Web.RegularExpressions",
-                               "System.Web.Services",
-                               "System.Windows.Forms"
-#endif
-                       };
-
-                       soft_references.AddRange (default_config);
-
-                       if (RootContext.Version > LanguageVersion.ISO_2)
-                               soft_references.Add ("System.Core");
-               }
-
-               public static string OutputFile
-               {
-                       set {
-                               output_file = value;
-                       }
-                       get {
-                               return Path.GetFileName (output_file);
-                       }
-               }
-
-               static void SetWarningLevel (string s)
+               void SetWarningLevel (string s)
                {
                        int level = -1;
 
@@ -810,7 +507,7 @@ namespace Mono.CSharp
 
                static void Version ()
                {
-                       string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
+                       string version = System.Reflection.Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
                        Console.WriteLine ("Mono C# compiler version {0}", version);
                        Environment.Exit (0);
                }
@@ -832,7 +529,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--parse":
-                               parse_only = true;
+                               RootContext.ParseOnly = true;
                                return true;
                                
                        case "--main": case "-m":
@@ -865,7 +562,7 @@ namespace Mono.CSharp
                                return true;
 
                        case "--tokenize": 
-                               tokenize = true;
+                               RootContext.TokenizeOnly = true;
                                return true;
                                
                        case "-o": 
@@ -875,7 +572,7 @@ namespace Mono.CSharp
                                        Usage ();
                                        Environment.Exit (1);
                                }
-                               OutputFile = args [++i];
+                               RootContext.OutputFile = args [++i];
                                return true;
 
                        case "--checked":
@@ -884,7 +581,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--stacktrace":
-                               Report.Stacktrace = true;
+                               Report.Printer.Stacktrace = true;
                                return true;
                                
                        case "--linkresource":
@@ -895,10 +592,8 @@ namespace Mono.CSharp
                                        Report.Error (5, "Missing argument to --linkres"); 
                                        Environment.Exit (1);
                                }
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-                               
-                               embedded_resources.Add (false, args [++i], args [i]);
+
+                               AddResource (new AssemblyResource (args[++i], args[i]));
                                return true;
                                
                        case "--resource":
@@ -909,10 +604,8 @@ namespace Mono.CSharp
                                        Report.Error (5, "Missing argument to --resource"); 
                                        Environment.Exit (1);
                                }
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-                               
-                               embedded_resources.Add (true, args [++i], args [i]);
+
+                               AddResource (new AssemblyResource (args[++i], args[i], true));
                                return true;
                                
                        case "--target":
@@ -959,11 +652,11 @@ namespace Mono.CSharp
                                if (idx > -1) {
                                        string alias = val.Substring (0, idx);
                                        string assembly = val.Substring (idx + 1);
-                                       AddExternAlias (alias, assembly);
+                                       AddAssemblyReference (alias, assembly);
                                        return true;
                                }
 
-                               references.Add (val);
+                               AddAssemblyReference (val);
                                return true;
                                
                        case "-L":
@@ -972,7 +665,11 @@ namespace Mono.CSharp
                                        Usage ();       
                                        Environment.Exit (1);
                                }
-                               link_paths.Add (args [++i]);
+                               RootContext.ReferencesLookupPaths.Add (args [++i]);
+                               return true;
+
+                       case "--lint":
+                               RootContext.EnhancedWarnings = true;
                                return true;
                                
                        case "--nostdlib":
@@ -980,15 +677,6 @@ namespace Mono.CSharp
                                RootContext.StdLib = false;
                                return true;
                                
-                       case "--fatal":
-                               Report.Fatal = true;
-                               return true;
-                               
-                       case "--werror":
-                               Report.Warning (-29, 1, "Compatibility: Use -warnaserror: option instead of --werror");
-                               Report.WarningsAreErrors = true;
-                               return true;
-
                        case "--nowarn":
                                Report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
                                if ((i + 1) >= args.Length){
@@ -1005,7 +693,7 @@ namespace Mono.CSharp
                                }
                                Report.SetIgnoreWarning (warn);
                                return true;
-                               
+
                        case "--wlevel":
                                Report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
                                if ((i + 1) >= args.Length){
@@ -1047,25 +735,54 @@ namespace Mono.CSharp
                                
                        case "--timestamp":
                                timestamps = true;
-                               last_time = first_time = DateTime.Now;
                                return true;
 
                        case "--debug": case "-g":
                                Report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
-                               want_debugging_support = true;
+                               RootContext.GenerateDebugInfo = true;
                                return true;
                                
                        case "--noconfig":
                                Report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
-                               load_default_config = false;
+                               RootContext.LoadDefaultReferences = false;
                                return true;
+
+                       default:
+                               if (arg.StartsWith ("--fatal")){
+                                       if (arg.StartsWith ("--fatal=")){
+                                               if (!Int32.TryParse (arg.Substring (8), out fatal_errors))
+                                                       fatal_errors = 1;
+                                       } else
+                                               fatal_errors = 1;
+                                       return true;
+                               }
+                               if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
+                                       string version = arg.Substring (10);
+
+                                       switch (version) {
+                                       case "v1":
+                                       case "V1":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v1;
+                                               break;
+                                       case "v2":
+                                       case "V2":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v2;
+                                               return true;
+                                       case "v4":
+                                       case "V4":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v4;
+                                               return true;
+                                       }
+                                       return true;
+                               }
+
+                               break;
                        }
 
                        return false;
                }
 
-#if !SMCS_SOURCE
-               public static string GetPackageFlags (string packages, bool fatal)
+               public static string GetPackageFlags (string packages, bool fatal, Report report)
                {
                        ProcessStartInfo pi = new ProcessStartInfo ();
                        pi.FileName = "pkg-config";
@@ -1076,7 +793,7 @@ namespace Mono.CSharp
                        try {
                                p = Process.Start (pi);
                        } catch (Exception e) {
-                               Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+                               report.Error (-27, "Couldn't run pkg-config: " + e.Message);
                                if (fatal)
                                        Environment.Exit (1);
                                p.Close ();
@@ -1084,14 +801,14 @@ namespace Mono.CSharp
                        }
                        
                        if (p.StandardOutput == null){
-                               Report.Warning (-27, 1, "Specified package did not return any information");
+                               report.Warning (-27, 1, "Specified package did not return any information");
                                p.Close ();
                                return null;
                        }
                        string pkgout = p.StandardOutput.ReadToEnd ();
                        p.WaitForExit ();
                        if (p.ExitCode != 0) {
-                               Report.Error (-27, "Error running pkg-config. Check the above output.");
+                               report.Error (-27, "Error running pkg-config. Check the above output.");
                                if (fatal)
                                        Environment.Exit (1);
                                p.Close ();
@@ -1101,7 +818,6 @@ namespace Mono.CSharp
 
                        return pkgout;
                }
-#endif
 
                //
                // This parses the -arg and /arg options to the compiler, even if the strings
@@ -1121,7 +837,7 @@ namespace Mono.CSharp
                                value = option.Substring (idx + 1);
                        }
 
-                       switch (arg.ToLower (CultureInfo.InvariantCulture)){
+                       switch (arg.ToLowerInvariant ()){
                        case "/nologo":
                                return true;
 
@@ -1153,11 +869,11 @@ namespace Mono.CSharp
                                return true;
 
                        case "/out":
-                               if (value.Length == 0){
-                                       Usage ();
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
-                               OutputFile = value;
+                               RootContext.OutputFile = value;
                                return true;
 
                        case "/o":
@@ -1172,6 +888,7 @@ namespace Mono.CSharp
                                RootContext.Optimize = false;
                                return true;
 
+                       // TODO: Not supported by csc 3.5+
                        case "/incremental":
                        case "/incremental+":
                        case "/incremental-":
@@ -1186,11 +903,12 @@ namespace Mono.CSharp
                                }
 
                                foreach (string d in value.Split (argument_value_separator)) {
-                                       if (!Tokenizer.IsValidIdentifier (d)) {
-                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d);
+                                       string conditional = d.Trim ();
+                                       if (!Tokenizer.IsValidIdentifier (conditional)) {
+                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
                                                continue;
                                        }
-                                       RootContext.AddConditional (d);
+                                       RootContext.AddConditional (conditional);
                                }
                                return true;
                        }
@@ -1201,7 +919,7 @@ namespace Mono.CSharp
                                //
                                Console.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
                                return true;
-#if !SMCS_SOURCE
+
                        case "/pkg": {
                                string packages;
 
@@ -1210,7 +928,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
-                               string pkgout = GetPackageFlags (packages, true);
+                               string pkgout = GetPackageFlags (packages, true, Report);
                                
                                if (pkgout != null){
                                        string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
@@ -1220,135 +938,148 @@ namespace Mono.CSharp
                                
                                return true;
                        }
-#endif
+
                        case "/linkres":
                        case "/linkresource":
                        case "/res":
                        case "/resource":
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-
-                               bool embeded = arg [1] == 'r' || arg [1] == 'R';
-                               string[] s = value.Split (argument_value_separator);
+                               AssemblyResource res = null;                    
+                               string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
                                switch (s.Length) {
                                case 1:
                                        if (s[0].Length == 0)
                                                goto default;
-                                       embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0]));
+                                       res = new AssemblyResource (s [0], Path.GetFileName (s[0]));
                                        break;
                                case 2:
-                                       embedded_resources.Add (embeded, s [0], s [1]);
+                                       res = new AssemblyResource (s [0], s [1]);
                                        break;
                                case 3:
                                        if (s [2] != "public" && s [2] != "private") {
                                                Report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s [2]);
                                                return true;
                                        }
-                                       embedded_resources.Add (embeded, s [0], s [1], s [2] == "private");
+                                       res = new AssemblyResource (s[0], s[1], s[2] == "private");
                                        break;
                                default:
                                        Report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
                                        break;
                                }
 
+                               if (res != null) {
+                                       res.IsEmbeded = arg [1] == 'r' || arg [1] == 'R';
+                                       AddResource (res);
+                               }
+
                                return true;
                                
                        case "/recurse":
-                               if (value.Length == 0){
-                                       Report.Error (5, "-recurse requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
                                ProcessSourceFiles (value, true); 
                                return true;
 
                        case "/r":
                        case "/reference": {
-                               if (value.Length == 0){
-                                       Report.Error (5, "-reference requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
 
                                string[] refs = value.Split (argument_value_separator);
                                foreach (string r in refs){
+                                       if (r.Length == 0)
+                                               continue;
+
                                        string val = r;
                                        int index = val.IndexOf ('=');
                                        if (index > -1) {
                                                string alias = r.Substring (0, index);
                                                string assembly = r.Substring (index + 1);
-                                               AddExternAlias (alias, assembly);
-                                               return true;
+                                               AddAssemblyReference (alias, assembly);
+                                               if (refs.Length != 1) {
+                                                       Report.Error (2034, "Cannot specify multiple aliases using single /reference option");
+                                                       break;
+                                               }
+                                       } else {
+                                               AddAssemblyReference (val);
                                        }
-
-                                       if (val.Length != 0)
-                                               references.Add (val);
                                }
                                return true;
                        }
                        case "/addmodule": {
-                               if (value.Length == 0){
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
 
                                string[] refs = value.Split (argument_value_separator);
                                foreach (string r in refs){
-                                       modules.Add (r);
+                                       RootContext.Modules.Add (r);
                                }
                                return true;
                        }
                        case "/win32res": {
                                if (value.Length == 0) {
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
                                
-                               if (win32IconFile != null)
+                               if (RootContext.Win32IconFile != null)
                                        Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
-                               win32ResourceFile = value;
+                               RootContext.Win32ResourceFile = value;
                                return true;
                        }
                        case "/win32icon": {
                                if (value.Length == 0) {
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
 
-                               if (win32ResourceFile != null)
+                               if (RootContext.Win32ResourceFile != null)
                                        Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
-                               win32IconFile = value;
+                               RootContext.Win32IconFile = value;
                                return true;
                        }
                        case "/doc": {
-                               if (value.Length == 0){
-                                       Report.Error (2006, arg + " requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
+
                                RootContext.Documentation = new Documentation (value);
                                return true;
                        }
                        case "/lib": {
                                string [] libdirs;
                                
-                               if (value.Length == 0){
-                                       Report.Error (5, "/lib requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
 
                                libdirs = value.Split (argument_value_separator);
                                foreach (string dir in libdirs)
-                                       link_paths.Add (dir);
+                                       RootContext.ReferencesLookupPaths.Add (dir);
                                return true;
                        }
 
                        case "/debug-":
-                               want_debugging_support = false;
+                               RootContext.GenerateDebugInfo = false;
                                return true;
                                
                        case "/debug":
+                               if (value == "full" || value == "")
+                                       RootContext.GenerateDebugInfo = true;
+
+                               return true;
+                               
                        case "/debug+":
-                               want_debugging_support = true;
+                               RootContext.GenerateDebugInfo = true;
                                return true;
 
                        case "/checked":
@@ -1362,6 +1093,7 @@ namespace Mono.CSharp
 
                        case "/clscheck":
                        case "/clscheck+":
+                               RootContext.VerifyClsCompliance = true;
                                return true;
 
                        case "/clscheck-":
@@ -1378,6 +1110,7 @@ namespace Mono.CSharp
                                return true;
 
                        case "/warnaserror":
+                       case "/warnaserror+":
                                if (value.Length == 0) {
                                        Report.WarningsAreErrors = true;
                                } else {
@@ -1386,27 +1119,31 @@ namespace Mono.CSharp
                                }
                                return true;
 
-                       case "/warnaserror+":
-                               Report.WarningsAreErrors = true;
-                               return true;
-
                        case "/warnaserror-":
-                               Report.WarningsAreErrors = false;
+                               if (value.Length == 0) {
+                                       Report.WarningsAreErrors = false;
+                               } else {
+                                       foreach (string wid in value.Split (argument_value_separator))
+                                               Report.RemoveWarningAsError (wid);
+                               }
                                return true;
 
                        case "/warn":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                SetWarningLevel (value);
                                return true;
 
                        case "/nowarn": {
-                               string [] warns;
-
                                if (value.Length == 0){
-                                       Report.Error (5, "/nowarn requires an argument");
-                                       Environment.Exit (1);
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
 
-                               warns = value.Split (argument_value_separator);
+                               var warns = value.Split (argument_value_separator);
                                foreach (string wc in warns){
                                        try {
                                                if (wc.Trim ().Length == 0)
@@ -1418,17 +1155,73 @@ namespace Mono.CSharp
                                                }
                                                Report.SetIgnoreWarning (warn);
                                        } catch {
-                                               Report.Error (1904, String.Format("`{0}' is not a valid warning number", wc));
+                                               Report.Error (1904, "`{0}' is not a valid warning number", wc);
                                        }
                                }
                                return true;
                        }
 
                        case "/noconfig":
-                               load_default_config = false;
+                               RootContext.LoadDefaultReferences = false;
+                               return true;
+
+                       case "/platform":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
+                               switch (value.ToLower (CultureInfo.InvariantCulture)) {
+                               case "anycpu":
+                                       RootContext.Platform = Platform.AnyCPU;
+                                       break;
+                               case "x86":
+                                       RootContext.Platform = Platform.X86;
+                                       break;
+                               case "x64":
+                                       RootContext.Platform = Platform.X64;
+                                       break;
+                               case "itanium":
+                                       RootContext.Platform = Platform.IA64;
+                                       break;
+                               default:
+                                       Report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
+                                       break;
+                               }
+
+                               return true;
+
+                       case "/sdk":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
+                               switch (value.ToLowerInvariant ()) {
+                                       case "2":
+                                               RootContext.SdkVersion = SdkVersion.v2;
+                                               break;
+                                       case "4":
+                                               RootContext.SdkVersion = SdkVersion.v4;
+                                               break;
+                                       default:
+                                               Report.Error (-26, "Invalid sdk version name");
+                                               break;
+                               }
+
                                return true;
 
-                       case "/help2":
+                               // We just ignore this.
+                       case "/errorreport":
+                       case "/filealign":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
+                               return true;
+                               
+                       case "/helpinternal":
                                OtherFlags ();
                                Environment.Exit(0);
                                return true;
@@ -1442,8 +1235,8 @@ namespace Mono.CSharp
                        case "/main":
                        case "/m":
                                if (value.Length == 0){
-                                       Report.Error (5, arg + " requires an argument");                                        
-                                       Environment.Exit (1);
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
                                RootContext.MainClass = value;
                                return true;
@@ -1461,20 +1254,24 @@ namespace Mono.CSharp
                                return true;
 
                        case "/keyfile":
-                               if (value == String.Empty) {
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresFileName (option);
+                                       break;
                                }
+
                                RootContext.StrongNameKeyFile = value;
                                return true;
+
                        case "/keycontainer":
-                               if (value == String.Empty) {
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
+
                                RootContext.StrongNameKeyContainer = value;
                                return true;
                        case "/delaysign+":
+                       case "/delaysign":
                                RootContext.StrongNameDelaySign = true;
                                return true;
                        case "/delaysign-":
@@ -1482,57 +1279,78 @@ namespace Mono.CSharp
                                return true;
 
                        case "/langversion":
-                               switch (value.ToLower (CultureInfo.InvariantCulture)) {
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
+                               switch (value.ToLowerInvariant ()) {
                                case "iso-1":
                                        RootContext.Version = LanguageVersion.ISO_1;
-                                       return true;
-                                       
+                                       return true;    
                                case "default":
                                        RootContext.Version = LanguageVersion.Default;
-#if GMCS_SOURCE                                        
                                        RootContext.AddConditional ("__V2__");
-#endif
                                        return true;
-#if GMCS_SOURCE
                                case "iso-2":
                                        RootContext.Version = LanguageVersion.ISO_2;
                                        return true;
+                               case "3":
+                                       RootContext.Version = LanguageVersion.V_3;
+                                       return true;
                                case "future":
                                        RootContext.Version = LanguageVersion.Future;
                                        return true;
-#endif
                                }
-                               Report.Error (1617, "Invalid option `{0}' for /langversion. It must be either `ISO-1', `ISO-2' or `Default'", value);
+
+                               Report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value);
                                return true;
 
                        case "/codepage":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                switch (value) {
                                case "utf8":
-                                       encoding = new UTF8Encoding();
+                                       RootContext.Encoding = new UTF8Encoding();
                                        break;
                                case "reset":
-                                       encoding = Encoding.Default;
+                                       RootContext.Encoding = Encoding.Default;
                                        break;
                                default:
                                        try {
-                                               encoding = Encoding.GetEncoding (
-                                               Int32.Parse (value));
+                                               RootContext.Encoding = Encoding.GetEncoding (Int32.Parse (value));
                                        } catch {
                                                Report.Error (2016, "Code page `{0}' is invalid or not installed", value);
                                        }
                                        break;
                                }
                                return true;
+
+                       default:
+                               return false;
                        }
 
-                       return false;
+                       return true;
                }
 
-               static void Error_WrongOption (string option)
+               void Error_WrongOption (string option)
                {
                        Report.Error (2007, "Unrecognized command-line option: `{0}'", option);
                }
 
+               void Error_RequiresFileName (string option)
+               {
+                       Report.Error (2005, "Missing file specification for `{0}' option", option);
+               }
+
+               void Error_RequiresArgument (string option)
+               {
+                       Report.Error (2006, "Missing argument for `{0}' option", option);
+               }
+
                static string [] AddArgs (string [] args, string [] extra_args)
                {
                        string [] new_args;
@@ -1557,20 +1375,40 @@ namespace Mono.CSharp
                        return new_args;
                }
 
-               static void AddExternAlias (string identifier, string assembly)
+               void AddAssemblyReference (string assembly)
+               {
+                       RootContext.AssemblyReferences.Add (assembly);
+               }
+
+               void AddAssemblyReference (string alias, string assembly)
                {
                        if (assembly.Length == 0) {
-                               Report.Error (1680, "Invalid reference alias '" + identifier + "='. Missing filename");
+                               Report.Error (1680, "Invalid reference alias `{0}='. Missing filename", alias);
                                return;
                        }
 
-                       if (!IsExternAliasValid (identifier)) {
-                               Report.Error (1679, "Invalid extern alias for /reference. Alias '" + identifier + "' is not a valid identifier");
+                       if (!IsExternAliasValid (alias)) {
+                               Report.Error (1679, "Invalid extern alias for -reference. Alias `{0}' is not a valid identifier", alias);
                                return;
                        }
-                       
-                       // Could here hashtable throw an exception?
-                       external_aliases [identifier] = assembly;
+
+                       RootContext.AssemblyReferencesAliases.Add (Tuple.Create (alias, assembly));
+               }
+
+               void AddResource (AssemblyResource res)
+               {
+                       if (RootContext.Resources == null) {
+                               RootContext.Resources = new List<AssemblyResource> ();
+                               RootContext.Resources.Add (res);
+                               return;
+                       }
+
+                       if (RootContext.Resources.Contains (res)) {
+                               ctx.Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", res.Name);
+                               return;
+                       }
+
+                       RootContext.Resources.Add (res);
                }
                
                static bool IsExternAliasValid (string identifier)
@@ -1600,96 +1438,112 @@ namespace Mono.CSharp
                //
                public bool Compile ()
                {
-                       Parse ();
+                       var module = new ModuleContainer (ctx);
+                       RootContext.ToplevelTypes = module;
+
+                       if (timestamps) {
+                               stopwatch = Stopwatch.StartNew ();
+                               first_time = DateTime.Now;
+                       }
+
+                       Parse (module);
+                       ShowTime ("Parsing source files");
+
                        if (Report.Errors > 0)
                                return false;
 
-                       if (tokenize || parse_only)
+                       if (RootContext.TokenizeOnly || RootContext.ParseOnly)
                                return true;
 
                        if (RootContext.ToplevelTypes.NamespaceEntry != null)
                                throw new InternalErrorException ("who set it?");
 
-                       ProcessDefaultConfig ();
-
                        //
                        // Quick hack
                        //
-                       if (output_file == null){
-                               if (first_source == null){
+                       var output_file = RootContext.OutputFile;
+                       string output_file_name;
+                       if (output_file == null) {
+                               if (first_source == null) {
                                        Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
                                        return false;
                                }
-                                       
+
                                int pos = first_source.LastIndexOf ('.');
 
                                if (pos > 0)
                                        output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
                                else
                                        output_file = first_source + RootContext.TargetExt;
-                       }
-
-                       if (!CodeGen.Init (output_file, output_file, want_debugging_support))
-                               return false;
-
-                       if (RootContext.Target == Target.Module) {
-                               PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                               if (module_only == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "/target:module");
-                                       Environment.Exit (1);
-                               }
 
-                               MethodInfo set_method = module_only.GetSetMethod (true);
-                               set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
+                               output_file_name = output_file;
+                       } else {
+                               output_file_name = Path.GetFileName (output_file);
                        }
 
-                       RootNamespace.Global.AddModuleReference (CodeGen.Module.Builder);
-
                        //
                        // Load assemblies required
                        //
                        if (timestamps)
-                               ShowTime ("Loading references");
+                               stopwatch = Stopwatch.StartNew ();
 
-                       LoadReferences ();
-                       
-                       if (modules.Count > 0) {
-                               foreach (string module in modules)
-                                       LoadModule (module);
-                       }
-                       
-                       if (timestamps)
-                               ShowTime ("References loaded");
-                       
-                       if (!TypeManager.InitCoreTypes () || Report.Errors > 0)
+#if STATIC
+                       var importer = new StaticImporter ();
+                       var references_loader = new StaticLoader (importer, ctx);
+
+                       var assembly = new AssemblyDefinitionStatic (module, references_loader, output_file_name, output_file);
+                       assembly.Create (references_loader.Domain);
+
+                       // Create compiler types first even before any referenced
+                       // assembly is loaded to allow forward referenced types from
+                       // loaded assembly into compiled builder to be resolved
+                       // correctly
+                       module.CreateType ();
+                       ShowTime ("Creating compiled types");
+
+                       importer.AddCompiledAssembly (assembly);
+                       references_loader.LoadReferences (module);
+                       ShowTime ("Imporing referenced assemblies");
+
+                       if (!ctx.BuildinTypes.CheckDefinitions (module))
                                return false;
 
-                       TypeManager.InitOptionalCoreTypes ();
+                       ShowTime ("Initializing predefined types");
 
-                       if (timestamps)
-                               ShowTime ("   Core Types done");
+                       references_loader.LoadModules (assembly, module.GlobalRootNamespace);
+#else
+                       var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
+                       module.SetDeclaringAssembly (assembly);
 
-                       CodeGen.Module.Resolve ();
+                       var importer = new ReflectionImporter (ctx.BuildinTypes);
+                       assembly.Importer = importer;
 
-                       //
-                       // The second pass of the compiler
-                       //
-                       if (timestamps)
-                               ShowTime ("Resolving tree");
-                       RootContext.ResolveTree ();
+                       var loader = new DynamicLoader (importer, ctx);
+                       loader.LoadReferences (module);
+
+                       ShowTime ("Imporing referenced assemblies");
+
+                       if (!ctx.BuildinTypes.CheckDefinitions (module))
+                               return false;
+
+                       ShowTime ("Initializing predefined types");
+
+                       if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
+                               return false;
+
+                       loader.LoadModules (assembly, module.GlobalRootNamespace);
+#endif
+                       module.Define ();
+
+                       ShowTime ("Types definition");
 
                        if (Report.Errors > 0)
                                return false;
-                       if (timestamps)
-                               ShowTime ("Populate tree");
-                       if (!RootContext.StdLib)
-                               RootContext.BootCorlib_PopulateCoreTypes ();
-                       RootContext.PopulateTypes ();
 
                        if (Report.Errors == 0 &&
                                RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
-                                       output_file))
+                                       output_file, Report))
                                return false;
 
                        //
@@ -1701,14 +1555,8 @@ namespace Mono.CSharp
                                return false;
                        }
 
-                       CodeGen.Assembly.Resolve ();
+                       assembly.Resolve ();
                        
-                       if (RootContext.VerifyClsCompliance) {
-                               if (CodeGen.Assembly.IsClsCompliant) {
-                                       AttributeTester.VerifyModulesClsCompliance ();
-                                       TypeManager.LoadAllImportedTypes ();
-                               }
-                       }
                        if (Report.Errors > 0)
                                return false;
                        
@@ -1716,236 +1564,45 @@ namespace Mono.CSharp
                        // The code generator
                        //
                        if (timestamps)
-                               ShowTime ("Emitting code");
-                       ShowTotalTime ("Total so far");
-                       RootContext.EmitCode ();
-                       if (timestamps)
-                               ShowTime ("   done");
-
-                       if (Report.Errors > 0){
-                               return false;
-                       }
-
-                       if (timestamps)
-                               ShowTime ("Closing types");
-
-                       RootContext.CloseTypes ();
-
-                       PEFileKinds k = PEFileKinds.ConsoleApplication;
-
-                       switch (RootContext.Target) {
-                       case Target.Library:
-                       case Target.Module:
-                               k = PEFileKinds.Dll; break;
-                       case Target.Exe:
-                               k = PEFileKinds.ConsoleApplication; break;
-                       case Target.WinExe:
-                               k = PEFileKinds.WindowApplication; break;
-                       }
-
-                       if (RootContext.NeedsEntryPoint) {
-                               Method ep = RootContext.EntryPoint;
-
-                               if (ep == null) {
-                                       if (RootContext.MainClass != null) {
-                                               DeclSpace main_cont = RootContext.ToplevelTypes.GetDefinition (RootContext.MainClass) as DeclSpace;
-                                               if (main_cont == null) {
-                                                       Report.Error (1555, "Could not find `{0}' specified for Main method", RootContext.MainClass); 
-                                                       return false;
-                                               }
+                               stopwatch = Stopwatch.StartNew ();
 
-                                               if (!(main_cont is ClassOrStruct)) {
-                                                       Report.Error (1556, "`{0}' specified for Main method must be a valid class or struct", RootContext.MainClass);
-                                                       return false;
-                                               }
+                       assembly.Emit ();
 
-                                               Report.Error (1558, main_cont.Location, "`{0}' does not have a suitable static Main method", main_cont.GetSignatureForError ());
-                                               return false;
-                                       }
-
-                                       if (Report.Errors == 0)
-                                               Report.Error (5001, "Program `{0}' does not contain a static `Main' method suitable for an entry point",
-                                                       output_file);
-                                       return false;
-                               }
+                       ShowTime ("Resolving and emitting members blocks");
 
-                               CodeGen.Assembly.Builder.SetEntryPoint (ep.MethodBuilder, k);
-                       } else if (RootContext.MainClass != null) {
-                               Report.Error (2017, "Cannot specify -main if building a module or library");
+                       if (Report.Errors > 0){
+                               return false;
                        }
 
-                       if (embedded_resources != null){
-                               if (RootContext.Target == Target.Module) {
-                                       Report.Error (1507, "Cannot link resource file when building a module");
-                                       return false;
-                               }
-
-                               embedded_resources.Emit ();
-                       }
+                       module.CloseType ();
 
-                       //
-                       // Add Win32 resources
-                       //
+                       ShowTime ("Closing types");
 
-                       if (win32ResourceFile != null) {
-                               try {
-                                       CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
-                               } catch (ArgumentException) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
-                               }
-                       } else {
-                               CodeGen.Assembly.Builder.DefineVersionInfoResource ();
-                       }
+                       if (timestamps)
+                               stopwatch = Stopwatch.StartNew ();
 
-                       if (win32IconFile != null) {
-                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-                               if (define_icon == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
-                               } else {
-                                       define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
-                               }
-                       }
+                       assembly.EmbedResources ();
+                       ShowTime ("Embedding resources");
 
                        if (Report.Errors > 0)
                                return false;
-                       
-                       CodeGen.Save (output_file, want_debugging_support);
-                       if (timestamps) {
-                               ShowTime ("Saved output");
-                               ShowTotalTime ("Total");
-                       }
 
-                       Timer.ShowTimers ();
+                       if (timestamps)
+                               stopwatch = Stopwatch.StartNew ();
                        
-                       if (Report.ExpectedError != 0) {
-                               if (Report.Errors == 0) {
-                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
-                                               "No other errors reported.");
-                                       
-                                       Environment.Exit (2);
-                               } else {
-                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
-                                               "However, other errors were reported.");
-                                       
-                                       Environment.Exit (1);
-                               }
-                               
-                               
-                               return false;
-                       }
+                       assembly.Save ();
 
-#if DEBUGME
-                       Console.WriteLine ("Size of strings held: " + DeclSpace.length);
-                       Console.WriteLine ("Size of strings short: " + DeclSpace.small);
+#if STATIC
+                       references_loader.Dispose ();
 #endif
-                       return (Report.Errors == 0);
-               }
-       }
-
-       class Resources
-       {
-               interface IResource
-               {
-                       void Emit ();
-                       string FileName { get; }
-               }
-
-               class EmbededResource : IResource
-               {
-                       static MethodInfo embed_res;
-
-                       static EmbededResource () {
-                               Type[] argst = new Type [] { 
-                                                                                          typeof (string), typeof (string), typeof (ResourceAttributes)
-                                                                                  };
-
-                               embed_res = typeof (AssemblyBuilder).GetMethod (
-                                       "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
-                                       null, CallingConventions.Any, argst, null);
-                               
-                               if (embed_res == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "Resource embedding");
-                               }
-                       }
-
-                       readonly object[] args;
-
-                       public EmbededResource (string name, string file, bool isPrivate)
-                       {
-                               args = new object [3];
-                               args [0] = name;
-                               args [1] = file;
-                               args [2] = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
-                       }
-
-                       public void Emit()
-                       {
-                               embed_res.Invoke (CodeGen.Assembly.Builder, args);
-                       }
-
-                       public string FileName {
-                               get {
-                                       return (string)args [1];
-                               }
-                       }
-               }
-
-               class LinkedResource : IResource
-               {
-                       readonly string file;
-                       readonly string name;
-                       readonly ResourceAttributes attribute;
-
-                       public LinkedResource (string name, string file, bool isPrivate)
-                       {
-                               this.name = name;
-                               this.file = file;
-                               this.attribute = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
-                       }
-
-                       public void Emit ()
-                       {
-                               CodeGen.Assembly.Builder.AddResourceFile (name, Path.GetFileName(file), attribute);
-                       }
-
-                       public string FileName {
-                               get {
-                                       return file;
-                               }
-                       }
-               }
-
-
-               IDictionary embedded_resources = new HybridDictionary ();
 
-               public void Add (bool embeded, string file, string name)
-               {
-                       Add (embeded, file, name, false);
-               }
+                       ShowTime ("Saving output assembly");
 
-               public void Add (bool embeded, string file, string name, bool isPrivate)
-               {
-                       if (embedded_resources.Contains (name)) {
-                               Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", name);
-                               return;
-                       }
-                       IResource r = embeded ? 
-                               (IResource) new EmbededResource (name, file, isPrivate) : 
-                               new LinkedResource (name, file, isPrivate);
+                       ShowTotalTime ("Total");
 
-                       embedded_resources.Add (name, r);
-               }
+                       Timer.ShowTimers ();
 
-               public void Emit ()
-               {
-                       foreach (IResource r in embedded_resources.Values) {
-                               if (!File.Exists (r.FileName)) {
-                                       Report.Error (1566, "Error reading resource file `{0}'", r.FileName);
-                                       continue;
-                               }
-                               
-                               r.Emit ();
-                       }
+                       return (Report.Errors == 0);
                }
        }
 
@@ -1955,16 +1612,14 @@ namespace Mono.CSharp
        public class CompilerCallableEntryPoint : MarshalByRefObject {
                public static bool InvokeCompiler (string [] args, TextWriter error)
                {
-                       Report.Stderr = error;
                        try {
-                               Driver d = Driver.Create (args, true);
+                               StreamReportPrinter srp = new StreamReportPrinter (error);
+                               Driver d = Driver.Create (args, true, srp);
                                if (d == null)
                                        return false;
 
-                               return d.Compile () && Report.Errors == 0;
-                       }
-                       finally {
-                               Report.Stderr = Console.Error;
+                               return d.Compile () && srp.ErrorsCount == 0;
+                       } finally {
                                Reset ();
                        }
                }
@@ -1987,21 +1642,28 @@ namespace Mono.CSharp
                
                public static void Reset (bool full_flag)
                {
-                       Driver.Reset ();
-                       RootContext.Reset (full_flag);
-                       Tokenizer.Reset ();
+                       CSharpParser.yacc_verbose_flag = 0;
                        Location.Reset ();
-                       Report.Reset ();
-                       TypeManager.Reset ();
-                       TypeHandle.Reset ();
 
-                       if (full_flag)
-                               RootNamespace.Reset ();
+                       if (!full_flag)
+                               return;
+
+                       RootContext.Reset (full_flag);
+                       TypeManager.Reset ();
+                       ArrayContainer.Reset ();
+                       ReferenceContainer.Reset ();
+                       PointerContainer.Reset ();
+                       Parameter.Reset ();
+
+                       Unary.Reset ();
+                       UnaryMutator.Reset ();
+                       Binary.Reset ();
+                       ConstantFold.Reset ();
+                       CastFromDecimal.Reset ();
+                       StringConcat.Reset ();
                        
                        NamespaceEntry.Reset ();
-                       CodeGen.Reset ();
                        Attribute.Reset ();
-                       AttributeTester.Reset ();
                        AnonymousTypeClass.Reset ();
                        AnonymousMethodBody.Reset ();
                        AnonymousMethodStorey.Reset ();
@@ -2011,6 +1673,5 @@ namespace Mono.CSharp
                        Convert.Reset ();
                        TypeInfo.Reset ();
                }
-
        }
 }