Update
[mono.git] / mcs / mcs / driver.cs
old mode 100755 (executable)
new mode 100644 (file)
index e0263a4..68a3935
@@ -6,6 +6,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 
 namespace Mono.CSharp
@@ -17,9 +18,9 @@ namespace Mono.CSharp
        using System.IO;
        using System.Text;
        using System.Globalization;
-       using Mono.Languages;
+       using System.Diagnostics;
 
-       enum Target {
+       public enum Target {
                Library, Exe, Module, WinExe
        };
        
@@ -41,27 +42,25 @@ namespace Mono.CSharp
                //
                static ArrayList soft_references;
 
+               //
+               // Modules to be linked
+               //
+               static ArrayList modules;
+
                // Lookup paths
                static ArrayList link_paths;
 
-               // Whether we want Yacc to output its progress
-               static bool yacc_verbose = false;
-
                // Whether we want to only run the tokenizer
                static bool tokenize = false;
                
                static string first_source;
 
-               static Target target = Target.Exe;
-               static string target_ext = ".exe";
-
                static bool want_debugging_support = false;
 
                static bool parse_only = false;
                static bool timestamps = false;
                static bool pause = false;
                static bool show_counters = false;
-               public static bool parser_verbose = false;
                
                //
                // Whether to load the initial config file (what CSC.RSP has by default)
@@ -75,7 +74,9 @@ namespace Mono.CSharp
                //
                static ArrayList resources;
                static ArrayList embedded_resources;
-               
+               static string win32ResourceFile;
+               static string win32IconFile;
+
                //
                // An array of the defines from the command line
                //
@@ -100,7 +101,7 @@ namespace Mono.CSharp
                // Whether the user has specified a different encoder manually
                //
                static bool using_default_encoder = true;
-               
+
                public static void ShowTime (string msg)
                {
                        if (!timestamps)
@@ -146,7 +147,6 @@ namespace Mono.CSharp
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
-                                       Location l = lexer.Location;
                                        tokens++;
                                        if (token == Token.ERROR)
                                                errors++;
@@ -173,7 +173,6 @@ namespace Mono.CSharp
                        SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
                                
                        parser = new CSharpParser (reader, file, defines);
-                       parser.yacc_verbose = yacc_verbose;
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
@@ -182,6 +181,19 @@ namespace Mono.CSharp
                                input.Close ();
                        }
                }
+
+               static void OtherFlags ()
+               {
+                       Console.WriteLine (
+                               "Other flags in the compiler\n" +
+                               "   --fatal            Makes errors fatal\n" +
+                               "   --parse            Only parses the source file\n" +
+                               "   --stacktrace       Shows stack trace at error location\n" +
+                               "   --timestamp        Displays time stamps of various compiler events\n" +
+                               "   -2                 Enables experimental C# features\n" +
+                               "   -v                 Verbose parsing (for debugging the parser)\n" + 
+                               "   --mcs-debug X      Sets MCS debugging level to X\n");
+               }
                
                static void Usage ()
                {
@@ -189,39 +201,42 @@ namespace Mono.CSharp
                                "Mono C# compiler, (C) 2001 - 2003 Ximian, Inc.\n" +
                                "mcs [options] source-files\n" +
                                "   --about            About the Mono C# compiler\n" +
+                               "   -addmodule:MODULE  Adds the module to the generated assembly\n" + 
                                "   -checked[+|-]      Set default context to checked\n" +
                                "   -codepage:ID       Sets code page to the one in ID\n" +
                                "                      (number, `utf8' or `reset')\n" +
+                               "   -clscheck[+|-]     Disables CLS Compliance verifications" + Environment.NewLine +
                                "   -define:S1[;S2]    Defines one or more symbols (short: /d:)\n" +
-                               "   -debug[+-]         Generate debugging information\n" + 
+                               "   -debug[+|-]        Generate debugging information\n" + 
+                               "   -delaysign[+|-]    Only insert the public key into the assembly (no signing)\n" +
                                "   -doc:FILE          XML Documentation file to generate\n" + 
                                "   -g                 Generate debugging information\n" +
-                               "   --fatal            Makes errors fatal\n" +
+                               "   -keycontainer:NAME The key pair container used to strongname the assembly\n" +
+                               "   -keyfile:FILE      The strongname key file used to strongname the assembly\n" +
+                               "   -langversion:TEXT  Specifies language version modes: ISO-1 or Default" + Environment.NewLine +
                                "   -lib:PATH1,PATH2   Adds the paths to the assembly link path\n" +
                                "   -main:class        Specified the class that contains the entry point\n" +
                                "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
                                "   -out:FNAME         Specifies output file\n" +
-                               "   --parse            Only parses the source file\n" +
+                               "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
                                "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
                                "   -reference:ASS     References the specified assembly (-r:ASS)\n" +
-                               "   --stacktrace       Shows stack trace at error location\n" +
                                "   -target:KIND       Specifies the target (KIND is one of: exe, winexe,\n" +
                                "                      library, module), (short: /t:)\n" +
-                               "   --timestamp        Displays time stamps of various compiler events\n" +
                                "   -unsafe[+|-]       Allows unsafe code\n" +
                                "   -warnaserror[+|-]  Treat warnings as errors\n" +
                                "   -warn:LEVEL        Sets warning level (the highest is 4, the default is 2)\n" +
-                               "   -v                 Verbose parsing (for debugging the parser)\n" +
-                               "   -2                 Enables experimental C# features\n" +
+                               "   -help2             Show other help flags\n" + 
                                "\n" +
                                "Resources:\n" +
                                "   -linkresource:FILE[,ID] Links FILE as a resource\n" +
                                "   -resource:FILE[,ID]     Embed FILE as a resource\n" +
-                               "   --mcs-debug X      Sets MCS debugging level to X\n" +
-                                "   @file              Read response file for more options\n\n" +
+                               "   -win32res:FILE          Specifies Win32 resource file (.res)\n" +
+                               "   -win32icon:FILE         Use this icon for the output\n" +
+                                "   @file                   Read response file for more options\n\n" +
                                "Options can be of the form -option or /option");
                }
 
@@ -239,7 +254,7 @@ namespace Mono.CSharp
                                "For more information on Mono, visit the project Web site\n" +
                                "   http://www.go-mono.com\n\n" +
 
-                               "The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig");
+                               "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja R Harinath");
                        Environment.Exit (0);
                }
 
@@ -250,11 +265,9 @@ namespace Mono.CSharp
                        bool ok = MainDriver (args);
                        
                        if (ok && Report.Errors == 0) {
-                               Console.Write("Compilation succeeded");
                                if (Report.Warnings > 0) {
-                                       Console.Write(" - {0} warning(s)", Report.Warnings);
+                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
                                }
-                               Console.WriteLine();
                                if (show_counters){
                                        Console.WriteLine ("Counter1: " + counter1);
                                        Console.WriteLine ("Counter2: " + counter2);
@@ -275,19 +288,22 @@ namespace Mono.CSharp
                        string total_log = "";
 
                        try {
-                               char[] path_chars = { '/', '\\', '.' };
+                               char[] path_chars = { '/', '\\' };
 
                                if (assembly.IndexOfAny (path_chars) != -1) {
                                        a = Assembly.LoadFrom (assembly);
                                } else {
-                                       a = Assembly.Load (assembly);
+                                       string ass = assembly;
+                                       if (ass.EndsWith (".dll") || ass.EndsWith (".exe"))
+                                               ass = assembly.Substring (0, assembly.Length - 4);
+                                       a = Assembly.Load (ass);
                                }
                                TypeManager.AddAssembly (a);
 
                        } catch (FileNotFoundException){
                                foreach (string dir in link_paths){
                                        string full_path = Path.Combine (dir, assembly);
-                                       if (!assembly.EndsWith (".dll"))
+                                       if (!assembly.EndsWith (".dll") && !assembly.EndsWith (".exe"))
                                                full_path += ".dll";
 
                                        try {
@@ -312,6 +328,52 @@ namespace Mono.CSharp
                        }
                }
 
+               static public void LoadModule (MethodInfo adder_method, string module)
+               {
+                       Module m;
+                       string total_log = "";
+
+                       try {
+                               try {
+                                       m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
+                               }
+                               catch (TargetInvocationException ex) {
+                                       throw ex.InnerException;
+                               }
+                               TypeManager.AddModule (m);
+
+                       } 
+                       catch (FileNotFoundException){
+                               foreach (string dir in link_paths){
+                                       string full_path = Path.Combine (dir, module);
+                                       if (!module.EndsWith (".netmodule"))
+                                               full_path += ".netmodule";
+
+                                       try {
+                                               try {
+                                                       m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
+                                               }
+                                               catch (TargetInvocationException ex) {
+                                                       throw ex.InnerException;
+                                               }
+                                               TypeManager.AddModule (m);
+                                               return;
+                                       } catch (FileNotFoundException ff) {
+                                               total_log += ff.FusionLog;
+                                               continue;
+                                       }
+                               }
+                               Report.Error (6, "Cannot find module `" + module + "'" );
+                               Console.WriteLine ("Log: \n" + total_log);
+                       } catch (BadImageFormatException f) {
+                               Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
+                       } catch (FileLoadException f){
+                               Report.Error(6, "Cannot load module " + f.FusionLog);
+                       } catch (ArgumentNullException){
+                               Report.Error(6, "Cannot load module (null argument)");
+                       }
+               }
+
                /// <summary>
                ///   Loads all assemblies referenced on the command line
                /// </summary>
@@ -405,7 +467,7 @@ namespace Mono.CSharp
                //
                static void SplitPathAndPattern (string spec, out string path, out string pattern)
                {
-                       int p = spec.LastIndexOf ("/");
+                       int p = spec.LastIndexOf ('/');
                        if (p != -1){
                                //
                                // Windows does not like /file.cs, switch that to:
@@ -421,7 +483,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       p = spec.LastIndexOf ("\\");
+                       p = spec.LastIndexOf ('\\');
                        if (p != -1){
                                path = spec.Substring (0, p);
                                pattern = spec.Substring (p + 1);
@@ -458,7 +520,7 @@ namespace Mono.CSharp
                        string path, pattern;
 
                        SplitPathAndPattern (spec, out path, out pattern);
-                       if (pattern.IndexOf ("*") == -1){
+                       if (pattern.IndexOf ('*') == -1){
                                ProcessFile (spec);
                                return;
                        }
@@ -561,7 +623,7 @@ namespace Mono.CSharp
 
                static void TestWarningConflict ()
                {
-                       if (Report.Warnings == 0 && Report.WarningsAreErrors) {
+                       if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
                                Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
                                Environment.Exit (1);
                        }
@@ -569,7 +631,7 @@ namespace Mono.CSharp
 
                static void SetupV2 ()
                {
-                       RootContext.V2 = true;
+                       RootContext.Version = LanguageVersion.Default;
                        defines.Add ("__V2__");
                }
                
@@ -588,12 +650,8 @@ namespace Mono.CSharp
                static bool UnixParseOption (string arg, ref string [] args, ref int i)
                {
                        switch (arg){
-                       case "-vv":
-                               parser_verbose = true;
-                               return true;
-                               
                        case "-v":
-                               yacc_verbose = true;
+                               CSharpParser.yacc_verbose_flag++;
                                return true;
 
                        case "--version":
@@ -621,7 +679,7 @@ namespace Mono.CSharp
                                Usage ();
                                Environment.Exit (0);
                                return true;
-                               
+
                        case "--define":
                                if ((i + 1) >= args.Length){
                                        Usage ();
@@ -703,21 +761,21 @@ namespace Mono.CSharp
                                string type = args [++i];
                                switch (type){
                                case "library":
-                                       target = Target.Library;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
                                        break;
                                        
                                case "exe":
-                                       target = Target.Exe;
+                                       RootContext.Target = Target.Exe;
                                        break;
                                        
                                case "winexe":
-                                       target = Target.WinExe;
+                                       RootContext.Target = Target.WinExe;
                                        break;
                                        
                                case "module":
-                                       target = Target.Module;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".dll";
                                        break;
                                default:
                                        TargetUsage ();
@@ -836,7 +894,7 @@ namespace Mono.CSharp
                //
                static bool CSCParseOption (string option, ref string [] args, ref int i)
                {
-                       int idx = option.IndexOf (":");
+                       int idx = option.IndexOf (':');
                        string arg, value;
 
                        if (idx == -1){
@@ -856,21 +914,21 @@ namespace Mono.CSharp
                        case "/target":
                                switch (value){
                                case "exe":
-                                       target = Target.Exe;
+                                       RootContext.Target = Target.Exe;
                                        break;
 
                                case "winexe":
-                                       target = Target.WinExe;
+                                       RootContext.Target = Target.WinExe;
                                        break;
 
                                case "library":
-                                       target = Target.Library;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
                                        break;
 
                                case "module":
-                                       target = Target.Module;
-                                       target_ext = ".netmodule";
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".netmodule";
                                        break;
 
                                default:
@@ -924,22 +982,73 @@ namespace Mono.CSharp
                                
                                resources.Add (value);
                                return true;
+
+                       case "/pkg": {
+                               string packages;
+
+                               if (value == ""){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
+                               
+                               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, "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;
+                       }
                                
                        case "/res":
                        case "/resource":
                                if (value == ""){
-                                       Report.Error (5, arg + " requires an argument");
+                                       Report.Error (5, "-resource requires an argument");
                                        Environment.Exit (1);
                                }
                                if (embedded_resources == null)
                                        embedded_resources = new ArrayList ();
                                
-                               embedded_resources.Add (value);
+                               if (embedded_resources.Contains (value)) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else if (value.IndexOf (',') != -1 && embedded_resources.Contains (value.Split (',')[1])) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else {
+                                       embedded_resources.Add (value);
+                               }
                                return true;
                                
                        case "/recurse":
                                if (value == ""){
-                                       Report.Error (5, "/recurse requires an argument");
+                                       Report.Error (5, "-recurse requires an argument");
                                        Environment.Exit (1);
                                }
                                CompileFiles (value, true); 
@@ -948,7 +1057,7 @@ namespace Mono.CSharp
                        case "/r":
                        case "/reference": {
                                if (value == ""){
-                                       Report.Error (5, arg + " requires an argument");
+                                       Report.Error (5, "-reference requires an argument");
                                        Environment.Exit (1);
                                }
 
@@ -958,12 +1067,42 @@ namespace Mono.CSharp
                                }
                                return true;
                        }
-                       case "/doc": {
+                       case "/addmodule": {
                                if (value == ""){
                                        Report.Error (5, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
-                               // TODO handle the /doc argument to generate xml doc
+
+                               string [] refs = value.Split (new char [] { ';', ',' });
+                               foreach (string r in refs){
+                                       modules.Add (r);
+                               }
+                               return true;
+                       }
+                       case "/win32res": {
+                               if (value == "") {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               win32ResourceFile = value;
+                               return true;
+                       }
+                       case "/win32icon": {
+                               if (value == "") {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               win32IconFile = value;
+                               return true;
+                       }
+                       case "/doc": {
+                               if (value == ""){
+                                       Report.Error (2006, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.Documentation = new Documentation (value);
                                return true;
                        }
                        case "/lib": {
@@ -979,6 +1118,10 @@ namespace Mono.CSharp
                                        link_paths.Add (dir);
                                return true;
                        }
+
+                       case "/debug-":
+                               want_debugging_support = false;
+                               return true;
                                
                        case "/debug":
                        case "/debug+":
@@ -994,6 +1137,14 @@ namespace Mono.CSharp
                                RootContext.Checked = false;
                                return true;
 
+                       case "/clscheck":
+                       case "/clscheck+":
+                               return true;
+
+                       case "/clscheck-":
+                               RootContext.VerifyClsCompliance = false;
+                               return true;
+
                        case "/unsafe":
                        case "/unsafe+":
                                RootContext.Unsafe = true;
@@ -1050,6 +1201,11 @@ namespace Mono.CSharp
                                load_default_config = false;
                                return true;
 
+                       case "/help2":
+                               OtherFlags ();
+                               Environment.Exit(0);
+                               return true;
+                               
                        case "/help":
                        case "/?":
                                Usage ();
@@ -1077,15 +1233,47 @@ namespace Mono.CSharp
                        case "/fullpaths":
                                return true;
 
-                       case "/win32icon":
-                               Report.Error (5, "/win32icon is currently not supported");
+                       case "/keyfile":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyFile = value;
                                return true;
-                               
+                       case "/keycontainer":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyContainer = value;
+                               return true;
+                       case "/delaysign+":
+                               RootContext.StrongNameDelaySign = true;
+                               return true;
+                       case "/delaysign-":
+                               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":
+                                               RootContext.Version = LanguageVersion.ISO_1;
+                                               return true;
+
+                                       case "default":
+                                               SetupV2 ();
+                                               return true;
+                               }
+                               Report.Error (1617, "Invalid option '{0}' for /langversion; must be ISO-1 or Default", value);
+                               Environment.Exit (1);
+                               return false;
+
                        case "/codepage":
                                int cp = -1;
 
@@ -1112,10 +1300,35 @@ namespace Mono.CSharp
                                }
                                return true;
                        }
-                       Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
-                       Environment.Exit (1);
+
+                       //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
+                       //Environment.Exit (1);
                        return false;
                }
+
+               static string [] AddArgs (string [] args, string [] extra_args)
+               {
+                       string [] new_args;
+                       new_args = new string [extra_args.Length + args.Length];
+
+                       // if args contains '--' we have to take that into account
+                       // split args into first half and second half based on '--'
+                       // and add the extra_args before --
+                       int split_position = Array.IndexOf (args, "--");
+                       if (split_position != -1)
+                       {
+                               Array.Copy (args, new_args, split_position);
+                               extra_args.CopyTo (new_args, split_position);
+                               Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
+                       }
+                       else
+                       {
+                               args.CopyTo (new_args, 0);
+                               extra_args.CopyTo (new_args, args.Length);
+                       }
+
+                       return new_args;
+               }
                
                /// <summary>
                ///    Parses the arguments, and drives the compilation
@@ -1141,6 +1354,7 @@ namespace Mono.CSharp
                        
                        references = new ArrayList ();
                        soft_references = new ArrayList ();
+                       modules = new ArrayList ();
                        link_paths = new ArrayList ();
 
                        SetupDefaultDefines ();
@@ -1152,12 +1366,13 @@ namespace Mono.CSharp
                        // path.
                        //
 
-                       int argc = args.Length;
-                       for (i = 0; i < argc; i++){
+                       for (i = 0; i < args.Length; i++){
                                string arg = args [i];
-
+                               if (arg == "")
+                                       continue;
+                               
                                if (arg.StartsWith ("@")){
-                                       string [] new_args, extra_args;
+                                       string [] extra_args;
                                        string response_file = arg.Substring (1);
 
                                        if (response_file_list == null)
@@ -1179,11 +1394,7 @@ namespace Mono.CSharp
                                                return false;
                                        }
 
-                                       new_args = new string [extra_args.Length + argc];
-                                       args.CopyTo (new_args, 0);
-                                       extra_args.CopyTo (new_args, argc);
-                                       args = new_args;
-                                       argc = new_args.Length;
+                                       args = AddArgs (args, extra_args);
                                        continue;
                                }
 
@@ -1216,8 +1427,29 @@ namespace Mono.CSharp
 
                        if (tokenize)
                                return true;
-                       
-                       if (first_source == null){
+
+                       //
+                       // This will point to the NamespaceEntry of the last file that was parsed, and may
+                       // not be meaningful when resolving classes from other files.  So, reset it to prevent
+                       // silent bugs.
+                       //
+                       RootContext.Tree.Types.NamespaceEntry = null;
+
+                       //
+                       // If we are an exe, require a source file for the entry point
+                       //
+                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
+                               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 && resources == null){
                                Report.Error (2008, "No files to compile were specified");
                                return false;
                        }
@@ -1227,6 +1459,8 @@ namespace Mono.CSharp
                        
                        if (parse_only)
                                return true;
+
+                       Tokenizer.Cleanup ();
                        
                        //
                        // Load Core Library for default compilation
@@ -1247,6 +1481,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Loading references");
                        link_paths.Add (GetSystemDir ());
+                       link_paths.Add (Directory.GetCurrentDirectory ());
                        LoadReferences ();
                        
                        if (timestamps)
@@ -1260,21 +1495,41 @@ namespace Mono.CSharp
                        // Quick hack
                        //
                        if (output_file == null){
-                               int pos = first_source.LastIndexOf (".");
+                               int pos = first_source.LastIndexOf ('.');
 
                                if (pos > 0)
-                                       output_file = first_source.Substring (0, pos) + target_ext;
+                                       output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
                                else
-                                       output_file = first_source + target_ext;
+                                       output_file = first_source + RootContext.TargetExt;
                        }
 
                        CodeGen.Init (output_file, output_file, want_debugging_support);
 
-                       TypeManager.AddModule (CodeGen.ModuleBuilder);
+                       if (RootContext.Target == Target.Module) {
+                               PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               if (module_only == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               MethodInfo set_method = module_only.GetSetMethod (true);
+                               set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
+                       }
+
+                       TypeManager.AddModule (CodeGen.Module.Builder);
+
+                       if (modules.Count > 0) {
+                               MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+                               if (adder_method == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               foreach (string module in modules)
+                                       LoadModule (adder_method, module);
+                       }
 
-                       DateTime start = DateTime.Now;
                        TypeManager.ComputeNamespaces ();
-                       DateTime end = DateTime.Now;
                        
                        //
                        // Before emitting, we need to get the core
@@ -1299,15 +1554,22 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Resolving tree");
                        RootContext.ResolveTree ();
+
                        if (Report.Errors > 0)
                                return false;
                        if (timestamps)
                                ShowTime ("Populate tree");
                        if (!RootContext.StdLib)
                                RootContext.BootCorlib_PopulateCoreTypes ();
+
                        RootContext.PopulateTypes ();
                        RootContext.DefineTypes ();
                        
+                       if (RootContext.Documentation != null &&
+                               !RootContext.Documentation.OutputDocComment (
+                                       output_file))
+                               return false;
+
                        TypeManager.InitCodeHelpers ();
 
                        //
@@ -1319,6 +1581,15 @@ namespace Mono.CSharp
                                return false;
                        }
                        
+                       if (RootContext.VerifyClsCompliance) { 
+                               CodeGen.Assembly.ResolveClsCompliance ();
+                               if (CodeGen.Assembly.IsClsCompliant) {
+                                       AttributeTester.VerifyModulesClsCompliance ();
+                                       TypeManager.LoadAllImportedTypes ();
+                                       AttributeTester.VerifyTopLevelNameClsCompliance ();
+                               }
+                       }
+                       
                        //
                        // The code generator
                        //
@@ -1339,28 +1610,46 @@ namespace Mono.CSharp
                        RootContext.CloseTypes ();
 
                        PEFileKinds k = PEFileKinds.ConsoleApplication;
-                               
-                       if (target == Target.Library || target == Target.Module){
-                               k = PEFileKinds.Dll;
-
-                               if (RootContext.MainClass != null)
-                                       Report.Error (2017, "Can not specify -main: when building module or library");
-                       } else if (target == Target.Exe)
-                               k = PEFileKinds.ConsoleApplication;
-                       else if (target == Target.WinExe)
-                               k = PEFileKinds.WindowApplication;
+                       
+                       switch (RootContext.Target) {
+                       case Target.Library:
+                       case Target.Module:
+                               k = PEFileKinds.Dll; break;
+                       case Target.Exe:
+                               k = PEFileKinds.ConsoleApplication; break;
+                       case Target.WinExe:
+                               k = PEFileKinds.WindowApplication; break;
+                       }
 
-                       if (target == Target.Exe || target == Target.WinExe){
+                       if (RootContext.NeedsEntryPoint) {
                                MethodInfo ep = RootContext.EntryPoint;
 
-                               if (ep == null){
+                               if (ep == null) {
+                                       if (RootContext.MainClass != null) {
+                                               DeclSpace main_cont = RootContext.Tree.Decls [RootContext.MainClass] as DeclSpace;
+                                               if (main_cont == null) {
+                                                       Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass); 
+                                                       return false;
+                                               }
+
+                                               if (!(main_cont is ClassOrStruct)) {
+                                                       Report.Error (1556, output_file, "'{0}' specified for Main method must be a valid class or struct", RootContext.MainClass);
+                                                       return false;
+                                               }
+
+                                               Report.Error (1558, main_cont.Location, "'{0}' does not have a suitable static Main method", main_cont.GetSignatureForError ());
+                                               return false;
+                                       }
+
                                        if (Report.Errors == 0)
                                                Report.Error (5001, "Program " + output_file +
                                                              " does not have an entry point defined");
                                        return false;
                                }
-                               
-                               CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+
+                               CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
+                       } else if (RootContext.MainClass != null) {
+                               Report.Error (2017, "Can not specify -main: when building module or library");
                        }
 
                        //
@@ -1378,7 +1667,7 @@ namespace Mono.CSharp
                                        } else
                                                file = res = spec;
 
-                                       CodeGen.AssemblyBuilder.AddResourceFile (res, file);
+                                       CodeGen.Assembly.Builder.AddResourceFile (res, file);
                                }
                        }
                        
@@ -1386,9 +1675,14 @@ namespace Mono.CSharp
                                object[] margs = new object [2];
                                Type[] argst = new Type [2];
                                argst [0] = argst [1] = typeof (string);
-                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", argst);
+
+                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod (
+                                       "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
+                                       null, CallingConventions.Any, argst, null);
+                               
                                if (embed_res == null) {
-                                       Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
+                                       Report.Warning (0, new Location (-1),
+                                                       "Cannot embed resources on this runtime: try the Mono runtime instead.");
                                } else {
                                        foreach (string spec in embedded_resources) {
                                                int cp;
@@ -1397,11 +1691,13 @@ namespace Mono.CSharp
                                                if (cp != -1){
                                                        margs [0] = spec.Substring (cp + 1);
                                                        margs [1] = spec.Substring (0, cp);
-                                               } else
-                                                       margs [0] = margs [1] = spec;
+                                               } else {
+                                                       margs [1] = spec;
+                                                       margs [0] = Path.GetFileName (spec);
+                                               }
 
                                                if (File.Exists ((string) margs [1]))
-                                                       embed_res.Invoke (CodeGen.AssemblyBuilder, margs);
+                                                       embed_res.Invoke (CodeGen.Assembly.Builder, margs);
                                                else {
                                                        Report.Error (1566, "Can not find the resource " + margs [1]);
                                                }
@@ -1409,6 +1705,29 @@ namespace Mono.CSharp
                                }
                        }
 
+                       //
+                       // Add Win32 resources
+                       //
+
+                       CodeGen.Assembly.Builder.DefineVersionInfoResource ();
+
+                       if (win32ResourceFile != null) {
+                               try {
+                                       CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
+                               }
+                               catch (ArgumentException) {
+                                       Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
+                               }
+                       }
+
+                       if (win32IconFile != null) {
+                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               if (define_icon == null) {
+                                       Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
+                               }
+                               define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
+                       }
+
                        if (Report.Errors > 0)
                                return false;
                        
@@ -1420,9 +1739,20 @@ namespace Mono.CSharp
 
                        Timer.ShowTimers ();
                        
-                       if (Report.ExpectedError != 0){
-                               Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
-                               Environment.Exit (1);
+                       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;
                        }
 
@@ -1432,7 +1762,6 @@ namespace Mono.CSharp
 #endif
                        return (Report.Errors == 0);
                }
-
        }
 
        //