2009-12-10 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / driver.cs
index fc51eb88ea1c2d977d65a6edd37227eefe2d2c12..3674bd6ce81292db2306a2181b2610e1ec388f98 100644 (file)
@@ -16,8 +16,7 @@ namespace Mono.CSharp
        using System;
        using System.Reflection;
        using System.Reflection.Emit;
-       using System.Collections;
-       using System.Collections.Specialized;
+       using System.Collections.Generic;
        using System.IO;
        using System.Text;
        using System.Globalization;
@@ -26,6 +25,10 @@ namespace Mono.CSharp
        public enum Target {
                Library, Exe, Module, WinExe
        };
+
+       public enum Platform {
+               AnyCPU, X86, X64, IA64
+       }
        
        /// <summary>
        ///    The compiler driver.
@@ -35,27 +38,27 @@ namespace Mono.CSharp
                //
                // Assemblies references to be linked.   Initialized with
                // mscorlib.dll here.
-               static ArrayList references;
+               List<string> 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;
+               List<string> soft_references;
 
                // 
                // External aliases for assemblies.
                //
-               static Hashtable external_aliases;
+               Dictionary<string, string> external_aliases;
 
                //
                // Modules to be linked
                //
-               static ArrayList modules;
+               List<string> modules;
 
                // Lookup paths
-               static ArrayList link_paths;
+               List<string> link_paths;
 
                // Whether we want to only run the tokenizer
                bool tokenize;
@@ -65,6 +68,7 @@ namespace Mono.CSharp
                bool want_debugging_support;
                bool parse_only;
                bool timestamps;
+               bool fatal_errors;
                
                //
                // Whether to load the initial config file (what CSC.RSP has by default)
@@ -74,9 +78,9 @@ namespace Mono.CSharp
                //
                // A list of resource files
                //
-               static Resources embedded_resources;
-               static string win32ResourceFile;
-               static string win32IconFile;
+               Resources embedded_resources;
+               string win32ResourceFile;
+               string win32IconFile;
 
                //
                // Output file
@@ -93,27 +97,35 @@ namespace Mono.CSharp
                //
                Encoding encoding;
 
+               readonly CompilerContext ctx;
+
+               static readonly char[] argument_value_separator = new char [] { ';', ',' };
+
                static public void Reset ()
                {
-                       embedded_resources = null;
-                       win32ResourceFile = win32IconFile = null;
                        output_file = null;
                }
 
-               public Driver ()
+               private Driver (CompilerContext ctx)
                {
+                       this.ctx = ctx;
                        encoding = Encoding.Default;
                }
 
-               public static Driver Create (string [] args, bool require_files)
+               public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
                {
-                       Driver d = new Driver ();
+                       Driver d = new Driver (new CompilerContext (new Report (printer)));
+
                        if (!d.ParseArguments (args, require_files))
                                return null;
 
                        return d;
                }
 
+               Report Report {
+                       get { return ctx.Report; }
+               }
+
                void ShowTime (string msg)
                {
                        if (!timestamps)
@@ -142,7 +154,7 @@ namespace Mono.CSharp
                                (int) span.TotalSeconds, span.Milliseconds, msg);
                }              
               
-               void tokenize_file (CompilationUnit file)
+               void tokenize_file (CompilationUnit file, CompilerContext ctx)
                {
                        Stream input;
 
@@ -155,7 +167,7 @@ namespace Mono.CSharp
 
                        using (input){
                                SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-                               Tokenizer lexer = new Tokenizer (reader, file);
+                               Tokenizer lexer = new Tokenizer (reader, file, ctx);
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
@@ -191,19 +203,14 @@ namespace Mono.CSharp
 
                        reader.Position = 0;
                        Parse (reader, file);
+                       reader.Dispose ();
                        input.Close ();
                }       
                
                void Parse (SeekableStreamReader reader, CompilationUnit file)
                {
-                       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, ctx);
+                       parser.parse ();
                }
 
                static void OtherFlags ()
@@ -225,38 +232,41 @@ namespace Mono.CSharp
                        Console.WriteLine (
                                "Mono C# compiler, Copyright 2001 - 2008 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" +
-                               "   -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" +
-                               "   -doc:FILE          Process documentation comments to XML file\n" + 
-                               "   -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 modes: ISO-1, ISO-2, or Default\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" +
-                               "   -nostdlib[+|-]     Does not reference mscorlib.dll library\n" +
-                               "   -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" +
+                               "   --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" +
+                               "   -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" +
+                               "   -doc:FILE            Process documentation comments to XML file\n" + 
+                               "   -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" + 
+                               "   -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" +
+                               "   -nostdlib[+|-]       Does not reference mscorlib.dll library\n" +
+                               "   -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" + 
+                               "   -pkg:P1[,Pn]         References packages P1..Pn\n" + 
 #endif
-                               "   -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" +                           
-                               "   -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" +
-                               "   -warn:0-4          Sets warning level, the default is 3 (short -w:)\n" +
-                               "   -help2             Shows internal compiler options\n" + 
+                               "   -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" +                         
+                               "   -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" +
+                               "   -warn:0-4            Sets warning level, the default is 4 (short -w:)\n" +
+                               "   -help2               Shows internal compiler options\n" + 
                                "\n" +
                                "Resources:\n" +
                                "   -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
@@ -267,7 +277,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'");
                }
@@ -288,46 +298,49 @@ 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);
+                       crp.Fatal = d.fatal_errors;
+
+                       if (d.Compile () && d.Report.Errors == 0) {
+                               if (d.Report.Warnings > 0) {
+                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", d.Report.Warnings);
                                }
+                               Environment.Exit (0);
                                return 0;
-                       } else {
-                               Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
-                                       Report.Errors, Report.Warnings);
-                               return 1;
                        }
+                       
+                       
+                       Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
+                               d.Report.Errors, d.Report.Warnings);
+                       Environment.Exit (1);
+                       return 1;
                }
 
-               static public void LoadAssembly (string assembly, bool soft)
+               public void LoadAssembly (string assembly, bool soft)
                {
                        LoadAssembly (assembly, null, soft);
                }
 
-               static void Error6 (string name, string log)
+               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);
                }
 
-               static void Error9 (string type, string filename, string log)
+               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)
+               void BadAssembly (string filename, string log)
                {
                        MethodInfo adder_method = AssemblyClass.AddModule_Method;
 
@@ -359,7 +372,7 @@ namespace Mono.CSharp
                        Error9 ("assembly", filename, log);
                }
 
-               static public void LoadAssembly (string assembly, string alias, bool soft)
+               public void LoadAssembly (string assembly, string alias, bool soft)
                {
                        Assembly a = null;
                        string total_log = "";
@@ -401,9 +414,9 @@ namespace Mono.CSharp
 
                                // Extern aliased refs require special handling
                                if (alias == null)
-                                       RootNamespace.Global.AddAssemblyReference (a);
+                                       GlobalRootNamespace.Instance.AddAssemblyReference (a);
                                else
-                                       RootNamespace.DefineRootNamespace (alias, a);
+                                       GlobalRootNamespace.Instance.DefineRootNamespace (alias, a, ctx);
 
                        } catch (BadImageFormatException f) {
                                // .NET 2.0 throws this if we try to load a module without an assembly manifest ...
@@ -414,7 +427,7 @@ namespace Mono.CSharp
                        }
                }
 
-               static public void LoadModule (string module)
+               public void LoadModule (string module)
                {
                        Module m = null;
                        string total_log = "";
@@ -443,7 +456,7 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               RootNamespace.Global.AddModuleReference (m);
+                               GlobalRootNamespace.Instance.AddModuleReference (m);
 
                        } catch (BadImageFormatException f) {
                                Error9 ("module", f.FileName, f.FusionLog);
@@ -455,7 +468,7 @@ namespace Mono.CSharp
                /// <summary>
                ///   Loads all assemblies referenced on the command line
                /// </summary>
-               static public void LoadReferences ()
+               public void LoadReferences ()
                {
                        link_paths.Add (GetSystemDir ());
                        link_paths.Add (Directory.GetCurrentDirectory ());
@@ -472,16 +485,16 @@ namespace Mono.CSharp
                        foreach (string r in references)
                                LoadAssembly (r, false);
 
-                       foreach (DictionaryEntry entry in external_aliases)
-                               LoadAssembly ((string) entry.Value, (string) entry.Key, false);
-                       
-                       return;
+                       foreach (var entry in external_aliases)
+                               LoadAssembly (entry.Value, entry.Key, false);
+                               
+                       GlobalRootNamespace.Instance.ComputeNamespaces (ctx);
                }
 
                static string [] LoadArgs (string file)
                {
                        StreamReader f;
-                       ArrayList args = new ArrayList ();
+                       var args = new List<string> ();
                        string line;
                        try {
                                f = new StreamReader (file);
@@ -521,10 +534,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       string [] ret_value = new string [args.Count];
-                       args.CopyTo (ret_value, 0);
-
-                       return ret_value;
+                       return args.ToArray ();
                }
 
                //
@@ -572,18 +582,18 @@ 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 ();
+                       references = new List<string> ();
+                       external_aliases = new Dictionary<string, string> ();
+                       soft_references = new List<string> ();
+                       modules = new List<string> (2);
+                       link_paths = new List<string> ();
 
-                       ArrayList response_file_list = null;
+                       List<string> response_file_list = null;
                        bool parsing_options = true;
 
                        for (int i = 0; i < args.Length; i++) {
@@ -596,7 +606,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 (
@@ -680,12 +690,12 @@ namespace Mono.CSharp
                {
                        Location.Initialize ();
 
-                       int files_count = Location.SourceFiles.Length;
-                       for (int i = 0; i < files_count; ++i) {
+                       var cu = Location.SourceFiles;
+                       for (int i = 0; i < cu.Count; ++i) {
                                if (tokenize) {
-                                       tokenize_file (Location.SourceFiles [i]);
+                                       tokenize_file (cu [i], ctx);
                                } else {
-                                       Parse (Location.SourceFiles [i]);
+                                       Parse (cu [i]);
                                }
                        }
                }
@@ -734,20 +744,9 @@ namespace Mono.CSharp
 
                public void ProcessDefaultConfig ()
                {
-                       bool need_system_core = RootContext.Version > LanguageVersion.ISO_2;
-                       
-                       if (!load_default_config){
-                               //
-                               // Yet another SRE related problem, we have to always load System.Core
-                               // even with -noconfig, otherwise the check for ExtensionAttribute in
-                               // loaded assemblies won't work
-                               //
-                               if (need_system_core && references.Count != 0 && Driver.OutputFile != "System.Core.dll")
-                                       soft_references.Add ("System.Core");
-                               
+                       if (!load_default_config)
                                return;
-                       }
-                       
+       
                        //
                        // For now the "default config" is harcoded into the compiler
                        // we can move this outside later
@@ -787,8 +786,10 @@ namespace Mono.CSharp
 
                        soft_references.AddRange (default_config);
 
-                       if (need_system_core)
+                       if (RootContext.Version > LanguageVersion.ISO_2)
                                soft_references.Add ("System.Core");
+                       if (RootContext.Version > LanguageVersion.V_3)
+                               soft_references.Add ("Microsoft.CSharp");
                }
 
                public static string OutputFile
@@ -801,7 +802,7 @@ namespace Mono.CSharp
                        }
                }
 
-               static void SetWarningLevel (string s)
+               void SetWarningLevel (string s)
                {
                        int level = -1;
 
@@ -892,7 +893,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--stacktrace":
-                               Report.Stacktrace = true;
+                               Report.Printer.Stacktrace = true;
                                return true;
                                
                        case "--linkresource":
@@ -904,7 +905,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
+                                       embedded_resources = new Resources (ctx);
                                
                                embedded_resources.Add (false, args [++i], args [i]);
                                return true;
@@ -918,7 +919,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
+                                       embedded_resources = new Resources (ctx);
                                
                                embedded_resources.Add (true, args [++i], args [i]);
                                return true;
@@ -989,14 +990,9 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--fatal":
-                               Report.Fatal = true;
+                               fatal_errors = 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){
@@ -1073,7 +1069,7 @@ namespace Mono.CSharp
                }
 
 #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";
@@ -1084,7 +1080,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 ();
@@ -1092,14 +1088,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 ();
@@ -1193,12 +1189,13 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               foreach (string d in value.Split (';', ',')){
-                                       if (!Tokenizer.IsValidIdentifier (d)) {
-                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d);
+                               foreach (string d in value.Split (argument_value_separator)) {
+                                       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;
                        }
@@ -1218,7 +1215,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'}).
@@ -1234,29 +1231,29 @@ namespace Mono.CSharp
                        case "/res":
                        case "/resource":
                                if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
+                                       embedded_resources = new Resources (ctx);
 
-                               bool embeded = arg.StartsWith ("/r");
-                               string[] s = value.Split (',');
+                               bool embeded = arg [1] == 'r' || arg [1] == 'R';
+                               string[] s = value.Split (argument_value_separator);
                                switch (s.Length) {
-                                       case 1:
-                                               if (s[0].Length == 0)
-                                                       goto default;
-                                               embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0]));
-                                               break;
-                                       case 2:
-                                               embedded_resources.Add (embeded, 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");
-                                               break;
-                                       default:
-                                               Report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
-                                               break;
+                               case 1:
+                                       if (s[0].Length == 0)
+                                               goto default;
+                                       embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0]));
+                                       break;
+                               case 2:
+                                       embedded_resources.Add (embeded, 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");
+                                       break;
+                               default:
+                                       Report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
+                                       break;
                                }
 
                                return true;
@@ -1276,7 +1273,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               string [] refs = value.Split (new char [] { ';', ',' });
+                               string[] refs = value.Split (argument_value_separator);
                                foreach (string r in refs){
                                        string val = r;
                                        int index = val.IndexOf ('=');
@@ -1298,7 +1295,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               string [] refs = value.Split (new char [] { ';', ',' });
+                               string[] refs = value.Split (argument_value_separator);
                                foreach (string r in refs){
                                        modules.Add (r);
                                }
@@ -1309,6 +1306,9 @@ namespace Mono.CSharp
                                        Report.Error (5, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
+                               
+                               if (win32IconFile != null)
+                                       Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
                                win32ResourceFile = value;
                                return true;
@@ -1319,6 +1319,9 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
+                               if (win32ResourceFile != null)
+                                       Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
+
                                win32IconFile = value;
                                return true;
                        }
@@ -1338,7 +1341,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               libdirs = value.Split (new Char [] { ',' });
+                               libdirs = value.Split (argument_value_separator);
                                foreach (string dir in libdirs)
                                        link_paths.Add (dir);
                                return true;
@@ -1349,6 +1352,11 @@ namespace Mono.CSharp
                                return true;
                                
                        case "/debug":
+                               if (value == "full" || value == "")
+                                       want_debugging_support = true;
+
+                               return true;
+                               
                        case "/debug+":
                                want_debugging_support = true;
                                return true;
@@ -1381,11 +1389,21 @@ namespace Mono.CSharp
 
                        case "/warnaserror":
                        case "/warnaserror+":
-                               Report.WarningsAreErrors = true;
+                               if (value.Length == 0) {
+                                       Report.WarningsAreErrors = true;
+                               } else {
+                                       foreach (string wid in value.Split (argument_value_separator))
+                                               Report.AddWarningAsError (wid);
+                               }
                                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":
@@ -1399,10 +1417,13 @@ namespace Mono.CSharp
                                        Report.Error (5, "/nowarn requires an argument");
                                        Environment.Exit (1);
                                }
-                               
-                               warns = value.Split (new Char [] {','});
+
+                               warns = value.Split (argument_value_separator);
                                foreach (string wc in warns){
                                        try {
+                                               if (wc.Trim ().Length == 0)
+                                                       continue;
+
                                                int warn = Int32.Parse (wc);
                                                if (warn < 1) {
                                                        throw new ArgumentOutOfRangeException("warn");
@@ -1419,6 +1440,32 @@ namespace Mono.CSharp
                                load_default_config = false;
                                return true;
 
+                       case "/platform":
+                               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;
+
+                               // We just ignore this.
+                       case "/errorreport":
+                       case "/filealign":
+                               return true;
+                               
                        case "/help2":
                                OtherFlags ();
                                Environment.Exit(0);
@@ -1476,21 +1523,23 @@ namespace Mono.CSharp
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
                                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;
-#endif
+                               case "3":
+                                       RootContext.Version = LanguageVersion.V_3;
+                                       return true;
+                               case "future":
+                                       RootContext.Version = LanguageVersion.Future;
+                                       return true;
                                }
-                               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":
@@ -1516,7 +1565,7 @@ namespace Mono.CSharp
                        return false;
                }
 
-               static void Error_WrongOption (string option)
+               void Error_WrongOption (string option)
                {
                        Report.Error (2007, "Unrecognized command-line option: `{0}'", option);
                }
@@ -1545,7 +1594,7 @@ namespace Mono.CSharp
                        return new_args;
                }
 
-               static void AddExternAlias (string identifier, string assembly)
+               void AddExternAlias (string identifier, string assembly)
                {
                        if (assembly.Length == 0) {
                                Report.Error (1680, "Invalid reference alias '" + identifier + "='. Missing filename");
@@ -1588,6 +1637,9 @@ namespace Mono.CSharp
                //
                public bool Compile ()
                {
+                       // TODO: Should be passed to parser as an argument
+                       RootContext.ToplevelTypes = new ModuleCompiled (ctx, RootContext.Unsafe);
+
                        Parse ();
                        if (Report.Errors > 0)
                                return false;
@@ -1600,20 +1652,6 @@ namespace Mono.CSharp
 
                        ProcessDefaultConfig ();
 
-                       //
-                       // Load assemblies required
-                       //
-                       if (timestamps)
-                               ShowTime ("Loading references");
-                       LoadReferences ();
-                       
-                       if (timestamps)
-                               ShowTime ("   References loaded");
-                       
-                       if (Report.Errors > 0){
-                               return false;
-                       }
-
                        //
                        // Quick hack
                        //
@@ -1631,7 +1669,7 @@ namespace Mono.CSharp
                                        output_file = first_source + RootContext.TargetExt;
                        }
 
-                       if (!CodeGen.Init (output_file, output_file, want_debugging_support))
+                       if (!CodeGen.Init (output_file, output_file, want_debugging_support, ctx))
                                return false;
 
                        if (RootContext.Target == Target.Module) {
@@ -1645,23 +1683,32 @@ namespace Mono.CSharp
                                set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
                        }
 
-                       RootNamespace.Global.AddModuleReference (CodeGen.Module.Builder);
+                       GlobalRootNamespace.Instance.AddModuleReference (RootContext.ToplevelTypes.Builder);
+
+                       //
+                       // Load assemblies required
+                       //
+                       if (timestamps)
+                               ShowTime ("Loading references");
 
+                       LoadReferences ();
+                       
                        if (modules.Count > 0) {
                                foreach (string module in modules)
                                        LoadModule (module);
                        }
                        
-                       if (!TypeManager.InitCoreTypes ())
+                       if (timestamps)
+                               ShowTime ("References loaded");
+                       
+                       if (!TypeManager.InitCoreTypes (ctx) || Report.Errors > 0)
                                return false;
 
-                       TypeManager.InitOptionalCoreTypes ();
+                       TypeManager.InitOptionalCoreTypes (ctx);
 
                        if (timestamps)
                                ShowTime ("   Core Types done");
 
-                       CodeGen.Module.Resolve ();
-
                        //
                        // The second pass of the compiler
                        //
@@ -1677,12 +1724,10 @@ namespace Mono.CSharp
                                RootContext.BootCorlib_PopulateCoreTypes ();
                        RootContext.PopulateTypes ();
 
-                       RootContext.DefineTypes ();
-                       
                        if (Report.Errors == 0 &&
                                RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
-                                       output_file))
+                                       output_file, Report))
                                return false;
 
                        //
@@ -1698,7 +1743,7 @@ namespace Mono.CSharp
                        
                        if (RootContext.VerifyClsCompliance) {
                                if (CodeGen.Assembly.IsClsCompliant) {
-                                       AttributeTester.VerifyModulesClsCompliance ();
+                                       AttributeTester.VerifyModulesClsCompliance (ctx);
                                        TypeManager.LoadAllImportedTypes ();
                                }
                        }
@@ -1737,7 +1782,7 @@ namespace Mono.CSharp
                        }
 
                        if (RootContext.NeedsEntryPoint) {
-                               MethodInfo ep = RootContext.EntryPoint;
+                               Method ep = RootContext.EntryPoint;
 
                                if (ep == null) {
                                        if (RootContext.MainClass != null) {
@@ -1762,7 +1807,7 @@ namespace Mono.CSharp
                                        return false;
                                }
 
-                               CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
+                               CodeGen.Assembly.Builder.SetEntryPoint (ep.MethodBuilder, k);
                        } else if (RootContext.MainClass != null) {
                                Report.Error (2017, "Cannot specify -main if building a module or library");
                        }
@@ -1784,47 +1829,31 @@ namespace Mono.CSharp
                                try {
                                        CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
                                } catch (ArgumentException) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
+                                       Report.RuntimeMissingSupport (Location.Null, "resource embedding ");
                                }
                        } else {
                                CodeGen.Assembly.Builder.DefineVersionInfoResource ();
                        }
 
                        if (win32IconFile != null) {
-                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                                if (define_icon == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
+                                       Report.RuntimeMissingSupport (Location.Null, "resource embedding");
+                               } else {
+                                       define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
                                }
-                               define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
                        }
 
                        if (Report.Errors > 0)
                                return false;
                        
-                       CodeGen.Save (output_file, want_debugging_support);
+                       CodeGen.Save (output_file, want_debugging_support, Report);
                        if (timestamps) {
                                ShowTime ("Saved output");
                                ShowTotalTime ("Total");
                        }
 
                        Timer.ShowTimers ();
-                       
-                       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;
-                       }
 
 #if DEBUGME
                        Console.WriteLine ("Size of strings held: " + DeclSpace.length);
@@ -1838,28 +1867,13 @@ namespace Mono.CSharp
        {
                interface IResource
                {
-                       void Emit ();
+                       void Emit (CompilerContext cc);
                        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)
@@ -1870,8 +1884,22 @@ namespace Mono.CSharp
                                args [2] = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
                        }
 
-                       public void Emit()
+                       public void Emit (CompilerContext cc)
                        {
+                               if (embed_res == null) {
+                                       var argst = new [] {
+                                               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) {
+                                               cc.Report.RuntimeMissingSupport (Location.Null, "Resource embedding");
+                                       }
+                               }
+
                                embed_res.Invoke (CodeGen.Assembly.Builder, args);
                        }
 
@@ -1895,7 +1923,7 @@ namespace Mono.CSharp
                                this.attribute = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
                        }
 
-                       public void Emit ()
+                       public void Emit (CompilerContext cc)
                        {
                                CodeGen.Assembly.Builder.AddResourceFile (name, Path.GetFileName(file), attribute);
                        }
@@ -1908,7 +1936,13 @@ namespace Mono.CSharp
                }
 
 
-               IDictionary embedded_resources = new HybridDictionary ();
+               Dictionary<string, IResource> embedded_resources = new Dictionary<string, IResource> ();
+               readonly CompilerContext ctx;
+
+               public Resources (CompilerContext ctx)
+               {
+                       this.ctx = ctx;
+               }
 
                public void Add (bool embeded, string file, string name)
                {
@@ -1917,8 +1951,8 @@ namespace Mono.CSharp
 
                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);
+                       if (embedded_resources.ContainsKey (name)) {
+                               ctx.Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", name);
                                return;
                        }
                        IResource r = embeded ? 
@@ -1932,11 +1966,11 @@ namespace Mono.CSharp
                {
                        foreach (IResource r in embedded_resources.Values) {
                                if (!File.Exists (r.FileName)) {
-                                       Report.Error (1566, "Error reading resource file `{0}'", r.FileName);
+                                       ctx.Report.Error (1566, "Error reading resource file `{0}'", r.FileName);
                                        continue;
                                }
                                
-                               r.Emit ();
+                               r.Emit (ctx);
                        }
                }
        }
@@ -1947,16 +1981,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 ();
                        }
                }
@@ -1980,15 +2012,15 @@ namespace Mono.CSharp
                public static void Reset (bool full_flag)
                {
                        Driver.Reset ();
+                       CSharpParser.yacc_verbose_flag = 0;
                        RootContext.Reset (full_flag);
-                       Tokenizer.Reset ();
                        Location.Reset ();
-                       Report.Reset ();
                        TypeManager.Reset ();
+                       PredefinedAttributes.Reset ();
                        TypeHandle.Reset ();
 
                        if (full_flag)
-                               RootNamespace.Reset ();
+                               GlobalRootNamespace.Reset ();
                        
                        NamespaceEntry.Reset ();
                        CodeGen.Reset ();
@@ -1999,7 +2031,10 @@ namespace Mono.CSharp
                        AnonymousMethodStorey.Reset ();
                        SymbolWriter.Reset ();
                        Switch.Reset ();
+                       Linq.QueryBlock.TransparentParameter.Reset ();
+                       Convert.Reset ();
+                       TypeInfo.Reset ();
+                       DynamicExpressionStatement.Reset ();
                }
-
        }
 }