* cs-parser.jay (GetTokenName): Mark GENERATE_COMPLETION and COMPLETE_COMPLETION...
[mono.git] / mcs / mcs / driver.cs
index 542c05b524b7c83168ebef9fc85b6594ce54f323..4476e56c6b0ccdc6dc4c5b3c82c64dcebb56311b 100644 (file)
@@ -1,12 +1,14 @@
 //
 // driver.cs: The compiler command line driver.
 //
-// Author: Miguel de Icaza (miguel@gnu.org)
+// Authors:
+//   Miguel de Icaza (miguel@gnu.org)
+//   Marek Safar (marek.safar@gmail.com)
 //
-// Licensed under the terms of the GNU GPL
+// Dual licensed under the terms of the MIT X11 or GNU GPL
 //
-// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
-// (C) 2004, 2005 Novell, Inc
+// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
 //
 
 namespace Mono.CSharp
@@ -28,95 +30,91 @@ namespace Mono.CSharp
        /// <summary>
        ///    The compiler driver.
        /// </summary>
-       public class Driver
+       class Driver
        {
-               
                //
                // Assemblies references to be linked.   Initialized with
                // mscorlib.dll here.
-               static ArrayList references;
+               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;
+               ArrayList soft_references;
 
                // 
                // External aliases for assemblies.
                //
-               static Hashtable external_aliases;
+               Hashtable external_aliases;
 
                //
                // Modules to be linked
                //
-               static ArrayList modules;
+               ArrayList modules;
 
                // Lookup paths
                static ArrayList link_paths;
 
                // Whether we want to only run the tokenizer
-               static bool tokenize = false;
+               bool tokenize;
                
-               static string first_source;
-
-               static bool want_debugging_support = false;
+               string first_source;
 
-               static bool parse_only = false;
-               static bool timestamps = false;
-               static bool pause = false;
-               static bool show_counters = false;
+               bool want_debugging_support;
+               bool parse_only;
+               bool timestamps;
                
                //
                // Whether to load the initial config file (what CSC.RSP has by default)
                // 
-               static bool load_default_config = true;
+               bool load_default_config = true;
 
                //
                // A list of resource files
                //
-               static Resources embedded_resources;
-               static string win32ResourceFile;
-               static string win32IconFile;
-
-               //
-               // An array of the defines from the command line
-               //
-               static ArrayList defines;
+               Resources embedded_resources;
+               string win32ResourceFile;
+               string win32IconFile;
 
                //
                // Output file
                //
-               static string output_file = null;
+               static string output_file;
 
                //
                // Last time we took the time
                //
-               static DateTime last_time, first_time;
+               DateTime last_time, first_time;
 
                //
                // Encoding.
                //
-               static Encoding encoding;
+               Encoding encoding;
+
+               static readonly char[] argument_value_separator = new char [] { ';', ',' };
 
                static public void Reset ()
                {
-                       want_debugging_support = false;
-                       parse_only = false;
-                       timestamps = false;
-                       pause = false;
-                       show_counters = false;
-                       load_default_config = true;
-                       embedded_resources = null;
-                       win32ResourceFile = win32IconFile = null;
-                       defines = null;
                        output_file = null;
-                       encoding = null;
-                       first_source = null;
                }
 
-               public static void ShowTime (string msg)
+               public Driver ()
+               {
+                       encoding = Encoding.Default;
+               }
+
+               public static Driver Create (string [] args, bool require_files)
+               {
+                       Driver d = new Driver ();
+                       if (!d.ParseArguments (args, require_files))
+                               return null;
+
+                       return d;
+               }
+
+               void ShowTime (string msg)
                {
                        if (!timestamps)
                                return;
@@ -130,7 +128,7 @@ namespace Mono.CSharp
                                (int) span.TotalSeconds, span.Milliseconds, msg);
                }
 
-               public static void ShowTotalTime (string msg)
+               void ShowTotalTime (string msg)
                {
                        if (!timestamps)
                                return;
@@ -144,7 +142,7 @@ namespace Mono.CSharp
                                (int) span.TotalSeconds, span.Milliseconds, msg);
                }              
               
-               static void tokenize_file (SourceFile file)
+               void tokenize_file (CompilationUnit file)
                {
                        Stream input;
 
@@ -157,7 +155,7 @@ namespace Mono.CSharp
 
                        using (input){
                                SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-                               Tokenizer lexer = new Tokenizer (reader, file, defines);
+                               Tokenizer lexer = new Tokenizer (reader, file);
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
@@ -171,16 +169,14 @@ namespace Mono.CSharp
                        return;
                }
 
-               // MonoTODO("Change error code for aborted compilation to something reasonable")]               
-               static void parse (SourceFile file)
+               void Parse (CompilationUnit file)
                {
-                       CSharpParser parser;
                        Stream input;
 
                        try {
                                input = File.OpenRead (file.Name);
                        } catch {
-                               Report.Error (2001, "Source file `" + file.Name + "' could not be found");
+                               Report.Error (2001, "Source file `{0}' could not be found", file.Name);
                                return;
                        }
 
@@ -194,16 +190,19 @@ namespace Mono.CSharp
                        }
 
                        reader.Position = 0;
-                       parser = new CSharpParser (reader, file, defines);
+                       Parse (reader, file);
+                       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(
-                                       666, String.Format ("Compilation aborted in file {0}, parser at {1}: {2}",
-                                                           file.Name, parser.Lexer.Location, ex));
-                       } finally {
-                               input.Close ();
+                               Report.Error(589, parser.Lexer.Location,
+                                       "Compilation aborted in file `{0}', {1}", file.Name, ex);
                        }
                }
 
@@ -224,38 +223,41 @@ namespace Mono.CSharp
                static void Usage ()
                {
                        Console.WriteLine (
-                               "Mono C# compiler, (C) 2001 - 2007 Novell, Inc.\n" +
+                               "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" + Environment.NewLine +
-                               "   -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 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 implicit references to 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" +
-                               "   -pkg:P1[,Pn]       References packages P1..Pn\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" +
-                               "   -warn:0-4          Sets warning level, the default is 3 (short -w:)\n" +
-                               "   -help2             Shows internal compiler options\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" + 
+#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" +
+                               "   -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" +
@@ -274,8 +276,9 @@ namespace Mono.CSharp
                static void About ()
                {
                        Console.WriteLine (
-                               "The Mono C# compiler is (C) 2001-2007, Novell, Inc.\n\n" +
-                               "The compiler source code is released under the terms of the GNU GPL\n\n" +
+                               "The Mono C# compiler is Copyright 2001-2008, Novell, Inc.\n\n" +
+                               "The compiler source code is released under the terms of the \n"+
+                               "MIT X11 or GNU GPL licenses\n\n" +
 
                                "For more information on Mono, visit the project Web site\n" +
                                "   http://www.mono-project.com\n\n" +
@@ -284,32 +287,29 @@ namespace Mono.CSharp
                        Environment.Exit (0);
                }
 
-               public static int counter1, counter2;
-               
                public static int Main (string[] args)
                {
                        RootContext.Version = LanguageVersion.Default;
 
                        Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
 
-                       bool ok = MainDriver (args);
-                       
-                       if (ok && Report.Errors == 0) {
+                       Driver d = Driver.Create (args, true);
+                       if (d == null)
+                               return 1;
+
+                       if (d.Compile () && Report.Errors == 0) {
                                if (Report.Warnings > 0) {
                                        Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
                                }
-                               if (show_counters){
-                                       Console.WriteLine ("Counter1: " + counter1);
-                                       Console.WriteLine ("Counter2: " + counter2);
-                               }
-                               if (pause)
-                                       Console.ReadLine ();
+                               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",
+                               Report.Errors, Report.Warnings);
+                       Environment.Exit (1);
+                       return 1;
                }
 
                static public void LoadAssembly (string assembly, bool soft)
@@ -348,7 +348,8 @@ namespace Mono.CSharp
                                        }
 
                                        if (m != null) {
-                                               Report.Error (1509, "referenced file `{0}' is not an assembly; try using the '-addmodule' option", filename);
+                                               Report.Error (1509, "Referenced file `{0}' is not an assembly. Consider using `-addmodule' option instead",
+                                                             Path.GetFileName (filename));
                                                return;
                                        }
                                } catch (FileNotFoundException) {
@@ -404,9 +405,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);
 
                        } catch (BadImageFormatException f) {
                                // .NET 2.0 throws this if we try to load a module without an assembly manifest ...
@@ -446,7 +447,7 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               RootNamespace.Global.AddModuleReference (m);
+                               GlobalRootNamespace.Instance.AddModuleReference (m);
 
                        } catch (BadImageFormatException f) {
                                Error9 ("module", f.FileName, f.FusionLog);
@@ -458,8 +459,11 @@ 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 ());
+
                        //
                        // Load Core Library for default compilation
                        //
@@ -474,14 +478,8 @@ namespace Mono.CSharp
 
                        foreach (DictionaryEntry entry in external_aliases)
                                LoadAssembly ((string) entry.Value, (string) entry.Key, false);
-                       
-                       return;
-               }
-
-               static void SetupDefaultDefines ()
-               {
-                       defines = new ArrayList ();
-                       defines.Add ("__MonoCS__");
+                               
+                       GlobalRootNamespace.Instance.ComputeNamespaces ();
                }
 
                static string [] LoadArgs (string file)
@@ -573,7 +571,7 @@ namespace Mono.CSharp
                        pattern = spec;
                }
 
-               static void ProcessFile (string f)
+               void AddSourceFile (string f)
                {
                        if (first_source == null)
                                first_source = f;
@@ -581,26 +579,128 @@ namespace Mono.CSharp
                        Location.AddFile (f);
                }
 
-               static void ProcessFiles ()
+               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;
+                       bool parsing_options = true;
+
+                       for (int i = 0; i < args.Length; i++) {
+                               string arg = args [i];
+                               if (arg.Length == 0)
+                                       continue;
+
+                               if (arg [0] == '@') {
+                                       string [] extra_args;
+                                       string response_file = arg.Substring (1);
+
+                                       if (response_file_list == null)
+                                               response_file_list = new ArrayList ();
+
+                                       if (response_file_list.Contains (response_file)) {
+                                               Report.Error (
+                                                       1515, "Response file `" + response_file +
+                                                       "' specified multiple times");
+                                               return false;
+                                       }
+
+                                       response_file_list.Add (response_file);
+
+                                       extra_args = LoadArgs (response_file);
+                                       if (extra_args == null) {
+                                               Report.Error (2011, "Unable to open response file: " +
+                                                                 response_file);
+                                               return false;
+                                       }
+
+                                       args = AddArgs (args, extra_args);
+                                       continue;
+                               }
+
+                               if (parsing_options) {
+                                       if (arg == "--") {
+                                               parsing_options = false;
+                                               continue;
+                                       }
+
+                                       if (arg [0] == '-') {
+                                               if (UnixParseOption (arg, ref args, ref i))
+                                                       continue;
+
+                                               // Try a -CSCOPTION
+                                               string csc_opt = "/" + arg.Substring (1);
+                                               if (CSCParseOption (csc_opt, ref args))
+                                                       continue;
+
+                                               Error_WrongOption (arg);
+                                               return false;
+                                       }
+                                       if (arg [0] == '/') {
+                                               if (CSCParseOption (arg, ref args))
+                                                       continue;
+
+                                               // Need to skip `/home/test.cs' however /test.cs is considered as error
+                                               if (arg.Length < 2 || arg.IndexOf ('/', 2) == -1) {
+                                                       Error_WrongOption (arg);
+                                                       return false;
+                                               }
+                                       }
+                               }
+
+                               ProcessSourceFiles (arg, false);
+                       }
+
+                       if (require_files == false)
+                               return true;
+                                       
+                       //
+                       // If we are an exe, require a source file for the entry point
+                       //
+                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe || RootContext.Target == Target.Module) {
+                               if (first_source == null) {
+                                       Report.Error (2008, "No files to compile were specified");
+                                       return false;
+                               }
+
+                       }
+
+                       //
+                       // If there is nothing to put in the assembly, and we are not a library
+                       //
+                       if (first_source == null && embedded_resources == null) {
+                               Report.Error (2008, "No files to compile were specified");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               public void Parse ()
                {
                        Location.Initialize ();
 
-                       foreach (SourceFile file in Location.SourceFiles) {
+                       ArrayList cu = Location.SourceFiles;
+                       for (int i = 0; i < cu.Count; ++i) {
                                if (tokenize) {
-                                       tokenize_file (file);
+                                       tokenize_file ((CompilationUnit) cu [i]);
                                } else {
-                                       parse (file);
+                                       Parse ((CompilationUnit) cu [i]);
                                }
                        }
                }
 
-               static void CompileFiles (string spec, bool recurse)
+               void ProcessSourceFiles (string spec, bool recurse)
                {
                        string path, pattern;
 
                        SplitPathAndPattern (spec, out path, out pattern);
                        if (pattern.IndexOf ('*') == -1){
-                               ProcessFile (spec);
+                               AddSourceFile (spec);
                                return;
                        }
 
@@ -615,7 +715,7 @@ namespace Mono.CSharp
                                return;
                        }
                        foreach (string f in files) {
-                               ProcessFile (f);
+                               AddSourceFile (f);
                        }
 
                        if (!recurse)
@@ -632,25 +732,26 @@ namespace Mono.CSharp
                                        
                                // Don't include path in this string, as each
                                // directory entry already does
-                               CompileFiles (d + "/" + pattern, true);
+                               ProcessSourceFiles (d + "/" + pattern, true);
                        }
                }
 
-               static void DefineDefaultConfig ()
+               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
-                               "agclr",
-                               "System.Core",
-                               "System.Silverlight",
-                               "System.Xml.Core",
-#else
-                               "System.Xml"
+                               "System.Net",
+                               "System.Windows",
+                               "System.Windows.Browser",
 #endif
 #if false
                                //
@@ -676,11 +777,11 @@ namespace Mono.CSharp
                                "System.Windows.Forms"
 #endif
                        };
-                       
-                       if (RootContext.Version == LanguageVersion.LINQ)
-                               soft_references.Add ("System.Core");
 
                        soft_references.AddRange (default_config);
+
+                       if (RootContext.Version > LanguageVersion.ISO_2)
+                               soft_references.Add ("System.Core");
                }
 
                public static string OutputFile
@@ -708,12 +809,6 @@ namespace Mono.CSharp
                        Report.WarningLevel = level;
                }
 
-               static void SetupV2 ()
-               {
-                       RootContext.Version = LanguageVersion.Default;
-                       defines.Add ("__V2__");
-               }
-               
                static void Version ()
                {
                        string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
@@ -726,7 +821,7 @@ namespace Mono.CSharp
                // deprecated in favor of the CSCParseOption, which will also handle the
                // options that start with a dash in the future.
                //
-               static bool UnixParseOption (string arg, ref string [] args, ref int i)
+               bool UnixParseOption (string arg, ref string [] args, ref int i)
                {
                        switch (arg){
                        case "-v":
@@ -767,26 +862,9 @@ namespace Mono.CSharp
                                        Usage ();
                                        Environment.Exit (1);
                                }
-                               defines.Add (args [++i]);
+                               RootContext.AddConditional (args [++i]);
                                return true;
 
-                       case "--show-counters":
-                               show_counters = true;
-                               return true;
-                               
-                       case "--expect-error": {
-                               int code = 0;
-                               
-                               try {
-                                       code = Int32.Parse (
-                                               args [++i], NumberStyles.AllowLeadingSign);
-                                       Report.ExpectedError = code;
-                               } catch {
-                                       Report.Error (-14, "Invalid number specified");
-                               } 
-                               return true;
-                       }
-                               
                        case "--tokenize": 
                                tokenize = true;
                                return true;
@@ -907,11 +985,6 @@ namespace Mono.CSharp
                                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){
@@ -965,7 +1038,7 @@ namespace Mono.CSharp
                                        Report.Error (5, "--recurse requires an argument");
                                        Environment.Exit (1);
                                }
-                               CompileFiles (args [++i], true); 
+                               ProcessSourceFiles (args [++i], true); 
                                return true;
                                
                        case "--timestamp":
@@ -973,10 +1046,6 @@ namespace Mono.CSharp
                                last_time = first_time = DateTime.Now;
                                return true;
 
-                       case "--pause":
-                               pause = true;
-                               return true;
-                               
                        case "--debug": case "-g":
                                Report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
                                want_debugging_support = true;
@@ -991,11 +1060,50 @@ namespace Mono.CSharp
                        return false;
                }
 
+#if !SMCS_SOURCE
+               public static string GetPackageFlags (string packages, bool fatal)
+               {
+                       ProcessStartInfo pi = new ProcessStartInfo ();
+                       pi.FileName = "pkg-config";
+                       pi.RedirectStandardOutput = true;
+                       pi.UseShellExecute = false;
+                       pi.Arguments = "--libs " + packages;
+                       Process p = null;
+                       try {
+                               p = Process.Start (pi);
+                       } catch (Exception e) {
+                               Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+                               if (fatal)
+                                       Environment.Exit (1);
+                               p.Close ();
+                               return null;
+                       }
+                       
+                       if (p.StandardOutput == null){
+                               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.");
+                               if (fatal)
+                                       Environment.Exit (1);
+                               p.Close ();
+                               return null;
+                       }
+                       p.Close ();
+
+                       return pkgout;
+               }
+#endif
+
                //
                // This parses the -arg and /arg options to the compiler, even if the strings
                // in the following text use "/arg" on the strings.
                //
-               static bool CSCParseOption (string option, ref string [] args, ref int i)
+               bool CSCParseOption (string option, ref string [] args)
                {
                        int idx = option.IndexOf (':');
                        string arg, value;
@@ -1009,7 +1117,7 @@ namespace Mono.CSharp
                                value = option.Substring (idx + 1);
                        }
 
-                       switch (arg){
+                       switch (arg.ToLower (CultureInfo.InvariantCulture)){
                        case "/nologo":
                                return true;
 
@@ -1073,12 +1181,12 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               foreach (string d in value.Split (';', ',')){
+                               foreach (string d in value.Split (argument_value_separator)) {
                                        if (!Tokenizer.IsValidIdentifier (d)) {
                                                Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d);
                                                continue;
                                        }
-                                       defines.Add (d);
+                                       RootContext.AddConditional (d);
                                }
                                return true;
                        }
@@ -1089,7 +1197,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;
 
@@ -1098,41 +1206,17 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
+                               string pkgout = GetPackageFlags (packages, true);
                                
-                               ProcessStartInfo pi = new ProcessStartInfo ();
-                               pi.FileName = "pkg-config";
-                               pi.RedirectStandardOutput = true;
-                               pi.UseShellExecute = false;
-                               pi.Arguments = "--libs " + packages;
-                               Process p = null;
-                               try {
-                                       p = Process.Start (pi);
-                               } catch (Exception e) {
-                                       Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
-                                       Environment.Exit (1);
-                               }
-
-                               if (p.StandardOutput == null){
-                                       Report.Warning (-27, 1, "Specified package did not return any information");
-                                       return true;
-                               }
-                               string pkgout = p.StandardOutput.ReadToEnd ();
-                               p.WaitForExit ();
-                               if (p.ExitCode != 0) {
-                                       Report.Error (-27, "Error running pkg-config. Check the above output.");
-                                       Environment.Exit (1);
-                               }
-
                                if (pkgout != null){
                                        string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
                                                Split (new Char [] { ' ', '\t'});
                                        args = AddArgs (args, xargs);
                                }
                                
-                               p.Close ();
                                return true;
                        }
-                               
+#endif
                        case "/linkres":
                        case "/linkresource":
                        case "/res":
@@ -1140,27 +1224,27 @@ namespace Mono.CSharp
                                if (embedded_resources == null)
                                        embedded_resources = new Resources ();
 
-                               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;
@@ -1170,7 +1254,7 @@ namespace Mono.CSharp
                                        Report.Error (5, "-recurse requires an argument");
                                        Environment.Exit (1);
                                }
-                               CompileFiles (value, true); 
+                               ProcessSourceFiles (value, true); 
                                return true;
 
                        case "/r":
@@ -1180,7 +1264,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 ('=');
@@ -1190,8 +1274,9 @@ namespace Mono.CSharp
                                                AddExternAlias (alias, assembly);
                                                return true;
                                        }
-                                       
-                                       references.Add (val);
+
+                                       if (val.Length != 0)
+                                               references.Add (val);
                                }
                                return true;
                        }
@@ -1201,7 +1286,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);
                                }
@@ -1212,6 +1297,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;
@@ -1222,6 +1310,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;
                        }
@@ -1241,7 +1332,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;
@@ -1284,11 +1375,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":
@@ -1302,10 +1403,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");
@@ -1318,12 +1422,7 @@ namespace Mono.CSharp
                                return true;
                        }
 
-                       case "/noconfig-":
-                               load_default_config = true;
-                               return true;
-                               
                        case "/noconfig":
-                       case "/noconfig+":
                                load_default_config = false;
                                return true;
 
@@ -1380,12 +1479,6 @@ namespace Mono.CSharp
                                RootContext.StrongNameDelaySign = false;
                                return true;
 
-                       case "/v2":
-                       case "/2":
-                               Console.WriteLine ("The compiler option -2 is obsolete. Please use /langversion instead");
-                               SetupV2 ();
-                               return true;
-                               
                        case "/langversion":
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
                                case "iso-1":
@@ -1393,15 +1486,17 @@ namespace Mono.CSharp
                                        return true;
                                        
                                case "default":
-                                       SetupV2 ();
+                                       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 "linq":
-                                       RootContext.Version = LanguageVersion.LINQ;
+                               case "future":
+                                       RootContext.Version = LanguageVersion.Future;
                                        return true;
 #endif
                                }
@@ -1460,7 +1555,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");
@@ -1497,162 +1592,26 @@ namespace Mono.CSharp
                        
                        return true;
                }
-               
-               /// <summary>
-               ///    Parses the arguments, and drives the compilation
-               ///    process.
-               /// </summary>
-               ///
-               /// <remarks>
-               ///    TODO: Mostly structured to debug the compiler
-               ///    now, needs to be turned into a real driver soon.
-               /// </remarks>
-               // [MonoTODO("Change error code for unknown argument to something reasonable")]
-               internal static bool MainDriver (string [] args)
-               {
-                       int i;
-                       bool parsing_options = true;
-
-                       encoding = Encoding.Default;
-
-                       references = new ArrayList ();
-                       external_aliases = new Hashtable ();
-                       soft_references = new ArrayList ();
-                       modules = new ArrayList ();
-                       link_paths = new ArrayList ();
-
-                       SetupDefaultDefines ();
-                       
-                       //
-                       // Setup defaults
-                       //
-                       // This is not required because Assembly.Load knows about this
-                       // path.
-                       //
-
-                       Hashtable response_file_list = null;
-
-                       for (i = 0; i < args.Length; i++){
-                               string arg = args [i];
-                               if (arg.Length == 0)
-                                       continue;
-
-                               if (arg.StartsWith ("@")){
-                                       string [] extra_args;
-                                       string response_file = arg.Substring (1);
-
-                                       if (response_file_list == null)
-                                               response_file_list = new Hashtable ();
-                                       
-                                       if (response_file_list.Contains (response_file)){
-                                               Report.Error (
-                                                       1515, "Response file `" + response_file +
-                                                       "' specified multiple times");
-                                               Environment.Exit (1);
-                                       }
-                                       
-                                       response_file_list.Add (response_file, response_file);
-                                                   
-                                       extra_args = LoadArgs (response_file);
-                                       if (extra_args == null){
-                                               Report.Error (2011, "Unable to open response file: " +
-                                                             response_file);
-                                               return false;
-                                       }
-
-                                       args = AddArgs (args, extra_args);
-                                       continue;
-                               }
-
-                               if (parsing_options){
-                                       if (arg == "--"){
-                                               parsing_options = false;
-                                               continue;
-                                       }
-                                       
-                                       if (arg.StartsWith ("-")){
-                                               if (UnixParseOption (arg, ref args, ref i))
-                                                       continue;
-
-                                               // Try a -CSCOPTION
-                                               string csc_opt = "/" + arg.Substring (1);
-                                               if (CSCParseOption (csc_opt, ref args, ref i))
-                                                       continue;
-
-                                               Error_WrongOption (arg);
-                                               return false;
-                                       } else {
-                                               if (arg [0] == '/'){
-                                                       if (CSCParseOption (arg, ref args, ref i))
-                                                               continue;
-
-                                                       // Need to skip `/home/test.cs' however /test.cs is considered as error
-                                                       if (arg.Length < 2 || arg.IndexOf ('/', 2) == -1) {
-                                                               Error_WrongOption (arg);
-                                                               return false;
-                                                       }
-                                               }
-                                       }
-                               }
 
-                               CompileFiles (arg, false); 
-                       }
+               //
+               // Main compilation method
+               //
+               public bool Compile ()
+               {
+                       // TODO: Should be passed to parser as an argument
+                       RootContext.ToplevelTypes = new ModuleContainer (RootContext.Unsafe);
 
-                       ProcessFiles ();
+                       Parse ();
+                       if (Report.Errors > 0)
+                               return false;
 
-                       if (tokenize)
+                       if (tokenize || parse_only)
                                return true;
 
                        if (RootContext.ToplevelTypes.NamespaceEntry != null)
                                throw new InternalErrorException ("who set it?");
 
-                       //
-                       // If we are an exe, require a source file for the entry point
-                       //
-                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe || RootContext.Target == Target.Module){
-                               if (first_source == null){
-                                       Report.Error (2008, "No files to compile were specified");
-                                       return false;
-                               }
-
-                       }
-
-                       //
-                       // If there is nothing to put in the assembly, and we are not a library
-                       //
-                       if (first_source == null && embedded_resources == null){
-                               Report.Error (2008, "No files to compile were specified");
-                               return false;
-                       }
-
-                       if (Report.Errors > 0)
-                               return false;
-                       
-                       if (parse_only)
-                               return true;
-
-                       if (load_default_config)
-                               DefineDefaultConfig ();
-
-                       if (Report.Errors > 0){
-                               return false;
-                       }
-
-                       //
-                       // Load assemblies required
-                       //
-                       if (timestamps)
-                               ShowTime ("Loading references");
-                       link_paths.Add (GetSystemDir ());
-                       link_paths.Add (Directory.GetCurrentDirectory ());
-                       LoadReferences ();
-                       
-                       if (timestamps)
-                               ShowTime ("   References loaded");
-                       
-                       if (Report.Errors > 0){
-                               return false;
-                       }
+                       ProcessDefaultConfig ();
 
                        //
                        // Quick hack
@@ -1685,32 +1644,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);
                        }
                        
-                       //
-                       // Before emitting, we need to get the core
-                       // types emitted from the user defined types
-                       // or from the system ones.
-                       //
                        if (timestamps)
-                               ShowTime ("Initializing Core Types");
-                       if (!RootContext.StdLib){
-                               RootContext.ResolveCore ();
-                               if (Report.Errors > 0)
-                                       return false;
-                       }
+                               ShowTime ("References loaded");
                        
-                       TypeManager.InitCoreTypes ();
+                       if (!TypeManager.InitCoreTypes () || Report.Errors > 0)
+                               return false;
+
+                       TypeManager.InitOptionalCoreTypes ();
+
                        if (timestamps)
                                ShowTime ("   Core Types done");
 
-                       CodeGen.Module.Resolve ();
-
                        //
                        // The second pass of the compiler
                        //
@@ -1726,10 +1685,6 @@ namespace Mono.CSharp
                                RootContext.BootCorlib_PopulateCoreTypes ();
                        RootContext.PopulateTypes ();
 
-                       TypeManager.InitCodeHelpers ();
-
-                       RootContext.DefineTypes ();
-                       
                        if (Report.Errors == 0 &&
                                RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
@@ -1788,7 +1743,7 @@ namespace Mono.CSharp
                        }
 
                        if (RootContext.NeedsEntryPoint) {
-                               MethodInfo ep = RootContext.EntryPoint;
+                               Method ep = RootContext.EntryPoint;
 
                                if (ep == null) {
                                        if (RootContext.MainClass != null) {
@@ -1813,7 +1768,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");
                        }
@@ -1831,29 +1786,29 @@ namespace Mono.CSharp
                        // Add Win32 resources
                        //
 
-                       CodeGen.Assembly.Builder.DefineVersionInfoResource ();
-
                        if (win32ResourceFile != null) {
                                try {
                                        CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
-                               }
-                               catch (ArgumentException) {
+                               } catch (ArgumentException) {
                                        Report.RuntimeMissingSupport (Location.Null, "resource embeding");
                                }
+                       } 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");
+                               } 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);
+                       CodeGen.Save (output_file, want_debugging_support);
                        if (timestamps) {
                                ShowTime ("Saved output");
                                ShowTotalTime ("Total");
@@ -2001,7 +1956,11 @@ namespace Mono.CSharp
                {
                        Report.Stderr = error;
                        try {
-                               return Driver.MainDriver (args) && Report.Errors == 0;
+                               Driver d = Driver.Create (args, true);
+                               if (d == null)
+                                       return false;
+
+                               return d.Compile () && Report.Errors == 0;
                        }
                        finally {
                                Report.Stderr = Console.Error;
@@ -2014,21 +1973,43 @@ namespace Mono.CSharp
                                return Report.AllWarnings;
                        }
                }
+
+               public static void Reset ()
+               {
+                       Reset (true);
+               }
+
+               public static void PartialReset ()
+               {
+                       Reset (false);
+               }
                
-               static void Reset ()
+               public static void Reset (bool full_flag)
                {
                        Driver.Reset ();
-                       RootContext.Reset ();
-                       Tokenizer.Reset ();
+                       RootContext.Reset (full_flag);
                        Location.Reset ();
                        Report.Reset ();
                        TypeManager.Reset ();
+                       PredefinedAttributes.Reset ();
                        TypeHandle.Reset ();
-                       RootNamespace.Reset ();
+
+                       if (full_flag)
+                               GlobalRootNamespace.Reset ();
+                       
                        NamespaceEntry.Reset ();
                        CodeGen.Reset ();
                        Attribute.Reset ();
                        AttributeTester.Reset ();
+                       AnonymousTypeClass.Reset ();
+                       AnonymousMethodBody.Reset ();
+                       AnonymousMethodStorey.Reset ();
+                       SymbolWriter.Reset ();
+                       Switch.Reset ();
+                       Linq.QueryBlock.TransparentParameter.Reset ();
+                       Convert.Reset ();
+                       TypeInfo.Reset ();
                }
+
        }
 }