X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdriver.cs;h=3674bd6ce81292db2306a2181b2610e1ec388f98;hb=5bc6a4e5ad482783f4923d3587d42768ae78a40f;hp=d73b2d47b6172f097bccb32e5452441bf1b30085;hpb=d91391074e5c2c5317891f18cee5246f495ecc8e;p=mono.git diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs index d73b2d47b61..3674bd6ce81 100644 --- a/mcs/mcs/driver.cs +++ b/mcs/mcs/driver.cs @@ -16,8 +16,7 @@ namespace Mono.CSharp using System; using System.Reflection; using System.Reflection.Emit; - using System.Collections; - using System.Collections.Specialized; + using System.Collections.Generic; using System.IO; using System.Text; using System.Globalization; @@ -26,6 +25,10 @@ namespace Mono.CSharp public enum Target { Library, Exe, Module, WinExe }; + + public enum Platform { + AnyCPU, X86, X64, IA64 + } /// /// The compiler driver. @@ -35,27 +38,27 @@ namespace Mono.CSharp // // Assemblies references to be linked. Initialized with // mscorlib.dll here. - static ArrayList references; + List references; // // If any of these fail, we ignore the problem. This is so // that we can list all the assemblies in Windows and not fail // if they are missing on Linux. // - static ArrayList soft_references; + List soft_references; // // External aliases for assemblies. // - static Hashtable external_aliases; + Dictionary external_aliases; // // Modules to be linked // - static ArrayList modules; + List modules; // Lookup paths - static ArrayList link_paths; + List link_paths; // Whether we want to only run the tokenizer bool tokenize; @@ -65,6 +68,7 @@ namespace Mono.CSharp bool want_debugging_support; bool parse_only; bool timestamps; + bool fatal_errors; // // Whether to load the initial config file (what CSC.RSP has by default) @@ -74,9 +78,9 @@ namespace Mono.CSharp // // A list of resource files // - static Resources embedded_resources; - static string win32ResourceFile; - static string win32IconFile; + Resources embedded_resources; + string win32ResourceFile; + string win32IconFile; // // Output file @@ -93,27 +97,35 @@ namespace Mono.CSharp // Encoding encoding; + readonly CompilerContext ctx; + + static readonly char[] argument_value_separator = new char [] { ';', ',' }; + static public void Reset () { - embedded_resources = null; - win32ResourceFile = win32IconFile = null; output_file = null; } - public Driver () + private Driver (CompilerContext ctx) { + this.ctx = ctx; encoding = Encoding.Default; } - public static Driver Create (string [] args) + public static Driver Create (string[] args, bool require_files, ReportPrinter printer) { - Driver d = new Driver (); - if (!d.ParseArguments (args)) + Driver d = new Driver (new CompilerContext (new Report (printer))); + + if (!d.ParseArguments (args, require_files)) return null; return d; } + Report Report { + get { return ctx.Report; } + } + void ShowTime (string msg) { if (!timestamps) @@ -142,7 +154,7 @@ namespace Mono.CSharp (int) span.TotalSeconds, span.Milliseconds, msg); } - void tokenize_file (CompilationUnit file) + void tokenize_file (CompilationUnit file, CompilerContext ctx) { Stream input; @@ -155,7 +167,7 @@ namespace Mono.CSharp using (input){ SeekableStreamReader reader = new SeekableStreamReader (input, encoding); - Tokenizer lexer = new Tokenizer (reader, file); + Tokenizer lexer = new Tokenizer (reader, file, ctx); int token, tokens = 0, errors = 0; while ((token = lexer.token ()) != Token.EOF){ @@ -191,19 +203,14 @@ namespace Mono.CSharp reader.Position = 0; Parse (reader, file); + reader.Dispose (); input.Close (); } void Parse (SeekableStreamReader reader, CompilationUnit file) { - CSharpParser parser = new CSharpParser (reader, file); - parser.ErrorOutput = Report.Stderr; - try { - parser.parse (); - } catch (Exception ex) { - Report.Error(589, parser.Lexer.Location, - "Compilation aborted in file `{0}', {1}", file.Name, ex); - } + CSharpParser parser = new CSharpParser (reader, file, ctx); + parser.parse (); } static void OtherFlags () @@ -225,38 +232,41 @@ namespace Mono.CSharp Console.WriteLine ( "Mono C# compiler, Copyright 2001 - 2008 Novell, Inc.\n" + "mcs [options] source-files\n" + - " --about About the Mono C# compiler\n" + - " -addmodule:M1[,Mn] Adds the module to the generated assembly\n" + - " -checked[+|-] Sets default aritmetic overflow context\n" + - " -codepage:ID Sets code page to the one in ID (number, utf8, reset)\n" + - " -clscheck[+|-] Disables CLS Compliance verifications\n" + - " -define:S1[;S2] Defines one or more conditional symbols (short: -d)\n" + - " -debug[+|-], -g Generate debugging information\n" + - " -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" + - " -doc:FILE Process documentation comments to XML file\n" + - " -help Lists all compiler options (short: -?)\n" + - " -keycontainer:NAME The key pair container used to sign the output assembly\n" + - " -keyfile:FILE The key file used to strongname the ouput assembly\n" + - " -langversion:TEXT Specifies language version modes: ISO-1, ISO-2, or Default\n" + - " -lib:PATH1[,PATHn] Specifies the location of referenced assemblies\n" + - " -main:CLASS Specifies the class with the Main method (short: -m)\n" + - " -noconfig Disables implicitly referenced assemblies\n" + - " -nostdlib[+|-] Does not reference mscorlib.dll library\n" + - " -nowarn:W1[,Wn] Suppress one or more compiler warnings\n" + - " -optimize[+|-] Enables advanced compiler optimizations (short: -o)\n" + - " -out:FILE Specifies output assembly name\n" + + " --about About the Mono C# compiler\n" + + " -addmodule:M1[,Mn] Adds the module to the generated assembly\n" + + " -checked[+|-] Sets default aritmetic overflow context\n" + + " -codepage:ID Sets code page to the one in ID (number, utf8, reset)\n" + + " -clscheck[+|-] Disables CLS Compliance verifications\n" + + " -define:S1[;S2] Defines one or more conditional symbols (short: -d)\n" + + " -debug[+|-], -g Generate debugging information\n" + + " -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" + + " -doc:FILE Process documentation comments to XML file\n" + + " -help Lists all compiler options (short: -?)\n" + + " -keycontainer:NAME The key pair container used to sign the output assembly\n" + + " -keyfile:FILE The key file used to strongname the ouput assembly\n" + + " -langversion:TEXT Specifies language version: ISO-1, ISO-2, Default, or Future\n" + + " -lib:PATH1[,PATHn] Specifies the location of referenced assemblies\n" + + " -main:CLASS Specifies the class with the Main method (short: -m)\n" + + " -noconfig Disables implicitly referenced assemblies\n" + + " -nostdlib[+|-] Does not reference mscorlib.dll library\n" + + " -nowarn:W1[,Wn] Suppress one or more compiler warnings\n" + + " -optimize[+|-] Enables advanced compiler optimizations (short: -o)\n" + + " -out:FILE Specifies output assembly name\n" + #if !SMCS_SOURCE - " -pkg:P1[,Pn] References packages P1..Pn\n" + + " -pkg:P1[,Pn] References packages P1..Pn\n" + #endif - " -recurse:SPEC Recursively compiles files according to SPEC pattern\n" + - " -reference:A1[,An] Imports metadata from the specified assembly (short: -r)\n" + - " -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" + - " -target:KIND Specifies the format of the output assembly (short: -t)\n" + - " KIND can be one of: exe, winexe, library, module\n" + - " -unsafe[+|-] Allows to compile code which uses unsafe keyword\n" + - " -warnaserror[+|-] Treats all warnings as errors\n" + - " -warn:0-4 Sets warning level, the default is 3 (short -w:)\n" + - " -help2 Shows internal compiler options\n" + + " -platform:ARCH Specifies the target platform of the output assembly\n" + + " ARCH can be one of: anycpu, x86, x64 or itanium\n" + + " -recurse:SPEC Recursively compiles files according to SPEC pattern\n" + + " -reference:A1[,An] Imports metadata from the specified assembly (short: -r)\n" + + " -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" + + " -target:KIND Specifies the format of the output assembly (short: -t)\n" + + " KIND can be one of: exe, winexe, library, module\n" + + " -unsafe[+|-] Allows to compile code which uses unsafe keyword\n" + + " -warnaserror[+|-] Treats all warnings as errors\n" + + " -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" + + " -warn:0-4 Sets warning level, the default is 4 (short -w:)\n" + + " -help2 Shows internal compiler options\n" + "\n" + "Resources:\n" + " -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" + @@ -267,7 +277,7 @@ namespace Mono.CSharp "Options can be of the form -option or /option"); } - static void TargetUsage () + void TargetUsage () { Report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'"); } @@ -288,46 +298,49 @@ namespace Mono.CSharp public static int Main (string[] args) { - RootContext.Version = LanguageVersion.Default; - Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t"; - - Driver d = Driver.Create (args); + var crp = new ConsoleReportPrinter (); + Driver d = Driver.Create (args, true, crp); if (d == null) return 1; - if (d.Compile () && Report.Errors == 0) { - if (Report.Warnings > 0) { - Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings); + crp.Fatal = d.fatal_errors; + + if (d.Compile () && d.Report.Errors == 0) { + if (d.Report.Warnings > 0) { + Console.WriteLine ("Compilation succeeded - {0} warning(s)", d.Report.Warnings); } + Environment.Exit (0); return 0; - } else { - Console.WriteLine("Compilation failed: {0} error(s), {1} warnings", - Report.Errors, Report.Warnings); - return 1; } + + + Console.WriteLine("Compilation failed: {0} error(s), {1} warnings", + d.Report.Errors, d.Report.Warnings); + Environment.Exit (1); + return 1; } - static public void LoadAssembly (string assembly, bool soft) + public void LoadAssembly (string assembly, bool soft) { LoadAssembly (assembly, null, soft); } - static void Error6 (string name, string log) + void Error6 (string name, string log) { if (log != null && log.Length > 0) Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous "); Report.Error (6, "cannot find metadata file `{0}'", name); } - static void Error9 (string type, string filename, string log) + void Error9 (string type, string filename, string log) { if (log != null && log.Length > 0) Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous "); Report.Error (9, "file `{0}' has invalid `{1}' metadata", filename, type); } - static void BadAssembly (string filename, string log) + void BadAssembly (string filename, string log) { MethodInfo adder_method = AssemblyClass.AddModule_Method; @@ -359,7 +372,7 @@ namespace Mono.CSharp Error9 ("assembly", filename, log); } - static public void LoadAssembly (string assembly, string alias, bool soft) + public void LoadAssembly (string assembly, string alias, bool soft) { Assembly a = null; string total_log = ""; @@ -401,9 +414,9 @@ namespace Mono.CSharp // Extern aliased refs require special handling if (alias == null) - RootNamespace.Global.AddAssemblyReference (a); + GlobalRootNamespace.Instance.AddAssemblyReference (a); else - RootNamespace.DefineRootNamespace (alias, a); + GlobalRootNamespace.Instance.DefineRootNamespace (alias, a, ctx); } catch (BadImageFormatException f) { // .NET 2.0 throws this if we try to load a module without an assembly manifest ... @@ -414,7 +427,7 @@ namespace Mono.CSharp } } - static public void LoadModule (string module) + public void LoadModule (string module) { Module m = null; string total_log = ""; @@ -443,7 +456,7 @@ namespace Mono.CSharp } } - RootNamespace.Global.AddModuleReference (m); + GlobalRootNamespace.Instance.AddModuleReference (m); } catch (BadImageFormatException f) { Error9 ("module", f.FileName, f.FusionLog); @@ -455,8 +468,11 @@ namespace Mono.CSharp /// /// Loads all assemblies referenced on the command line /// - static public void LoadReferences () + public void LoadReferences () { + link_paths.Add (GetSystemDir ()); + link_paths.Add (Directory.GetCurrentDirectory ()); + // // Load Core Library for default compilation // @@ -469,16 +485,16 @@ namespace Mono.CSharp foreach (string r in references) LoadAssembly (r, false); - foreach (DictionaryEntry entry in external_aliases) - LoadAssembly ((string) entry.Value, (string) entry.Key, false); - - return; + foreach (var entry in external_aliases) + LoadAssembly (entry.Value, entry.Key, false); + + GlobalRootNamespace.Instance.ComputeNamespaces (ctx); } static string [] LoadArgs (string file) { StreamReader f; - ArrayList args = new ArrayList (); + var args = new List (); string line; try { f = new StreamReader (file); @@ -518,10 +534,7 @@ namespace Mono.CSharp } } - string [] ret_value = new string [args.Count]; - args.CopyTo (ret_value, 0); - - return ret_value; + return args.ToArray (); } // @@ -569,18 +582,18 @@ namespace Mono.CSharp if (first_source == null) first_source = f; - Location.AddFile (f); + Location.AddFile (Report, f); } - bool ParseArguments (string[] args) + bool ParseArguments (string[] args, bool require_files) { - references = new ArrayList (); - external_aliases = new Hashtable (); - soft_references = new ArrayList (); - modules = new ArrayList (2); - link_paths = new ArrayList (); + references = new List (); + external_aliases = new Dictionary (); + soft_references = new List (); + modules = new List (2); + link_paths = new List (); - ArrayList response_file_list = null; + List response_file_list = null; bool parsing_options = true; for (int i = 0; i < args.Length; i++) { @@ -593,7 +606,7 @@ namespace Mono.CSharp string response_file = arg.Substring (1); if (response_file_list == null) - response_file_list = new ArrayList (); + response_file_list = new List (); if (response_file_list.Contains (response_file)) { Report.Error ( @@ -648,6 +661,9 @@ namespace Mono.CSharp ProcessSourceFiles (arg, false); } + if (require_files == false) + return true; + // // If we are an exe, require a source file for the entry point // @@ -674,12 +690,12 @@ namespace Mono.CSharp { Location.Initialize (); - int files_count = Location.SourceFiles.Length; - for (int i = 0; i < files_count; ++i) { + var cu = Location.SourceFiles; + for (int i = 0; i < cu.Count; ++i) { if (tokenize) { - tokenize_file (Location.SourceFiles [i]); + tokenize_file (cu [i], ctx); } else { - Parse (Location.SourceFiles [i]); + Parse (cu [i]); } } } @@ -726,8 +742,11 @@ namespace Mono.CSharp } } - 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 @@ -736,7 +755,6 @@ namespace Mono.CSharp "System", "System.Xml", #if NET_2_1 - "System.Core", "System.Net", "System.Windows", "System.Windows.Browser", @@ -767,9 +785,11 @@ namespace Mono.CSharp }; soft_references.AddRange (default_config); - + if (RootContext.Version > LanguageVersion.ISO_2) soft_references.Add ("System.Core"); + if (RootContext.Version > LanguageVersion.V_3) + soft_references.Add ("Microsoft.CSharp"); } public static string OutputFile @@ -782,7 +802,7 @@ namespace Mono.CSharp } } - static void SetWarningLevel (string s) + void SetWarningLevel (string s) { int level = -1; @@ -873,7 +893,7 @@ namespace Mono.CSharp return true; case "--stacktrace": - Report.Stacktrace = true; + Report.Printer.Stacktrace = true; return true; case "--linkresource": @@ -885,7 +905,7 @@ namespace Mono.CSharp Environment.Exit (1); } if (embedded_resources == null) - embedded_resources = new Resources (); + embedded_resources = new Resources (ctx); embedded_resources.Add (false, args [++i], args [i]); return true; @@ -899,7 +919,7 @@ namespace Mono.CSharp Environment.Exit (1); } if (embedded_resources == null) - embedded_resources = new Resources (); + embedded_resources = new Resources (ctx); embedded_resources.Add (true, args [++i], args [i]); return true; @@ -970,14 +990,9 @@ namespace Mono.CSharp return true; case "--fatal": - Report.Fatal = true; + fatal_errors = true; return true; - case "--werror": - Report.Warning (-29, 1, "Compatibility: Use -warnaserror: option instead of --werror"); - Report.WarningsAreErrors = true; - return true; - case "--nowarn": Report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn"); if ((i + 1) >= args.Length){ @@ -1053,6 +1068,45 @@ namespace Mono.CSharp return false; } +#if !SMCS_SOURCE + public static string GetPackageFlags (string packages, bool fatal, Report report) + { + 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. @@ -1135,12 +1189,13 @@ namespace Mono.CSharp Environment.Exit (1); } - foreach (string d in value.Split (';', ',')){ - if (!Tokenizer.IsValidIdentifier (d)) { - Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d); + foreach (string d in value.Split (argument_value_separator)) { + string conditional = d.Trim (); + if (!Tokenizer.IsValidIdentifier (conditional)) { + Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional); continue; } - RootContext.AddConditional (d); + RootContext.AddConditional (conditional); } return true; } @@ -1160,38 +1215,14 @@ namespace Mono.CSharp Environment.Exit (1); } packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'})); + string pkgout = GetPackageFlags (packages, true, Report); - 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 @@ -1200,29 +1231,29 @@ namespace Mono.CSharp case "/res": case "/resource": if (embedded_resources == null) - embedded_resources = new Resources (); + embedded_resources = new Resources (ctx); - bool embeded = arg.StartsWith ("/r"); - string[] s = value.Split (','); + bool embeded = arg [1] == 'r' || arg [1] == 'R'; + string[] s = value.Split (argument_value_separator); switch (s.Length) { - case 1: - if (s[0].Length == 0) - goto default; - embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0])); - break; - case 2: - embedded_resources.Add (embeded, s [0], s [1]); - break; - case 3: - if (s [2] != "public" && s [2] != "private") { - Report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s [2]); - return true; - } - embedded_resources.Add (embeded, s [0], s [1], s [2] == "private"); - break; - default: - Report.Error (-2005, "Wrong number of arguments for option `{0}'", option); - break; + case 1: + if (s[0].Length == 0) + goto default; + embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0])); + break; + case 2: + embedded_resources.Add (embeded, s [0], s [1]); + break; + case 3: + if (s [2] != "public" && s [2] != "private") { + Report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s [2]); + return true; + } + embedded_resources.Add (embeded, s [0], s [1], s [2] == "private"); + break; + default: + Report.Error (-2005, "Wrong number of arguments for option `{0}'", option); + break; } return true; @@ -1242,7 +1273,7 @@ namespace Mono.CSharp Environment.Exit (1); } - string [] refs = value.Split (new char [] { ';', ',' }); + string[] refs = value.Split (argument_value_separator); foreach (string r in refs){ string val = r; int index = val.IndexOf ('='); @@ -1264,7 +1295,7 @@ namespace Mono.CSharp Environment.Exit (1); } - string [] refs = value.Split (new char [] { ';', ',' }); + string[] refs = value.Split (argument_value_separator); foreach (string r in refs){ modules.Add (r); } @@ -1275,6 +1306,9 @@ namespace Mono.CSharp Report.Error (5, arg + " requires an argument"); Environment.Exit (1); } + + if (win32IconFile != null) + Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); win32ResourceFile = value; return true; @@ -1285,6 +1319,9 @@ namespace Mono.CSharp Environment.Exit (1); } + if (win32ResourceFile != null) + Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); + win32IconFile = value; return true; } @@ -1304,7 +1341,7 @@ namespace Mono.CSharp Environment.Exit (1); } - libdirs = value.Split (new Char [] { ',' }); + libdirs = value.Split (argument_value_separator); foreach (string dir in libdirs) link_paths.Add (dir); return true; @@ -1315,6 +1352,11 @@ namespace Mono.CSharp return true; case "/debug": + if (value == "full" || value == "") + want_debugging_support = true; + + return true; + case "/debug+": want_debugging_support = true; return true; @@ -1347,11 +1389,21 @@ namespace Mono.CSharp case "/warnaserror": case "/warnaserror+": - Report.WarningsAreErrors = true; + if (value.Length == 0) { + Report.WarningsAreErrors = true; + } else { + foreach (string wid in value.Split (argument_value_separator)) + Report.AddWarningAsError (wid); + } return true; case "/warnaserror-": - Report.WarningsAreErrors = false; + if (value.Length == 0) { + Report.WarningsAreErrors = false; + } else { + foreach (string wid in value.Split (argument_value_separator)) + Report.RemoveWarningAsError (wid); + } return true; case "/warn": @@ -1365,10 +1417,13 @@ namespace Mono.CSharp Report.Error (5, "/nowarn requires an argument"); Environment.Exit (1); } - - warns = value.Split (new Char [] {','}); + + warns = value.Split (argument_value_separator); foreach (string wc in warns){ try { + if (wc.Trim ().Length == 0) + continue; + int warn = Int32.Parse (wc); if (warn < 1) { throw new ArgumentOutOfRangeException("warn"); @@ -1385,6 +1440,32 @@ namespace Mono.CSharp load_default_config = false; return true; + case "/platform": + switch (value.ToLower (CultureInfo.InvariantCulture)) { + case "anycpu": + RootContext.Platform = Platform.AnyCPU; + break; + case "x86": + RootContext.Platform = Platform.X86; + break; + case "x64": + RootContext.Platform = Platform.X64; + break; + case "itanium": + RootContext.Platform = Platform.IA64; + break; + default: + Report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'"); + break; + } + + return true; + + // We just ignore this. + case "/errorreport": + case "/filealign": + return true; + case "/help2": OtherFlags (); Environment.Exit(0); @@ -1442,21 +1523,23 @@ namespace Mono.CSharp switch (value.ToLower (CultureInfo.InvariantCulture)) { case "iso-1": RootContext.Version = LanguageVersion.ISO_1; - return true; - + return true; case "default": RootContext.Version = LanguageVersion.Default; -#if GMCS_SOURCE RootContext.AddConditional ("__V2__"); -#endif return true; -#if GMCS_SOURCE case "iso-2": RootContext.Version = LanguageVersion.ISO_2; return true; -#endif + case "3": + RootContext.Version = LanguageVersion.V_3; + return true; + case "future": + RootContext.Version = LanguageVersion.Future; + return true; } - Report.Error (1617, "Invalid option `{0}' for /langversion. It must be either `ISO-1', `ISO-2' or `Default'", value); + + Report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value); return true; case "/codepage": @@ -1482,7 +1565,7 @@ namespace Mono.CSharp return false; } - static void Error_WrongOption (string option) + void Error_WrongOption (string option) { Report.Error (2007, "Unrecognized command-line option: `{0}'", option); } @@ -1511,7 +1594,7 @@ namespace Mono.CSharp return new_args; } - static void AddExternAlias (string identifier, string assembly) + void AddExternAlias (string identifier, string assembly) { if (assembly.Length == 0) { Report.Error (1680, "Invalid reference alias '" + identifier + "='. Missing filename"); @@ -1548,12 +1631,15 @@ namespace Mono.CSharp return true; } - + // // Main compilation method // public bool Compile () { + // TODO: Should be passed to parser as an argument + RootContext.ToplevelTypes = new ModuleCompiled (ctx, RootContext.Unsafe); + Parse (); if (Report.Errors > 0) return false; @@ -1564,28 +1650,7 @@ namespace Mono.CSharp if (RootContext.ToplevelTypes.NamespaceEntry != null) throw new InternalErrorException ("who set it?"); - 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 @@ -1604,7 +1669,7 @@ namespace Mono.CSharp output_file = first_source + RootContext.TargetExt; } - if (!CodeGen.Init (output_file, output_file, want_debugging_support)) + if (!CodeGen.Init (output_file, output_file, want_debugging_support, ctx)) return false; if (RootContext.Target == Target.Module) { @@ -1618,23 +1683,32 @@ namespace Mono.CSharp set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null); } - RootNamespace.Global.AddModuleReference (CodeGen.Module.Builder); + GlobalRootNamespace.Instance.AddModuleReference (RootContext.ToplevelTypes.Builder); + // + // Load assemblies required + // + if (timestamps) + ShowTime ("Loading references"); + + LoadReferences (); + if (modules.Count > 0) { foreach (string module in modules) LoadModule (module); } - if (!TypeManager.InitCoreTypes ()) + if (timestamps) + ShowTime ("References loaded"); + + if (!TypeManager.InitCoreTypes (ctx) || Report.Errors > 0) return false; - TypeManager.InitOptionalCoreTypes (); + TypeManager.InitOptionalCoreTypes (ctx); if (timestamps) ShowTime (" Core Types done"); - CodeGen.Module.Resolve (); - // // The second pass of the compiler // @@ -1650,12 +1724,10 @@ namespace Mono.CSharp RootContext.BootCorlib_PopulateCoreTypes (); RootContext.PopulateTypes (); - RootContext.DefineTypes (); - if (Report.Errors == 0 && RootContext.Documentation != null && !RootContext.Documentation.OutputDocComment ( - output_file)) + output_file, Report)) return false; // @@ -1671,7 +1743,7 @@ namespace Mono.CSharp if (RootContext.VerifyClsCompliance) { if (CodeGen.Assembly.IsClsCompliant) { - AttributeTester.VerifyModulesClsCompliance (); + AttributeTester.VerifyModulesClsCompliance (ctx); TypeManager.LoadAllImportedTypes (); } } @@ -1710,7 +1782,7 @@ namespace Mono.CSharp } if (RootContext.NeedsEntryPoint) { - MethodInfo ep = RootContext.EntryPoint; + Method ep = RootContext.EntryPoint; if (ep == null) { if (RootContext.MainClass != null) { @@ -1735,7 +1807,7 @@ namespace Mono.CSharp return false; } - CodeGen.Assembly.Builder.SetEntryPoint (ep, k); + CodeGen.Assembly.Builder.SetEntryPoint (ep.MethodBuilder, k); } else if (RootContext.MainClass != null) { Report.Error (2017, "Cannot specify -main if building a module or library"); } @@ -1757,47 +1829,31 @@ namespace Mono.CSharp try { CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile); } catch (ArgumentException) { - Report.RuntimeMissingSupport (Location.Null, "resource embeding"); + Report.RuntimeMissingSupport (Location.Null, "resource embedding "); } } else { CodeGen.Assembly.Builder.DefineVersionInfoResource (); } if (win32IconFile != null) { - MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic); + MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (define_icon == null) { - Report.RuntimeMissingSupport (Location.Null, "resource embeding"); + Report.RuntimeMissingSupport (Location.Null, "resource embedding"); + } else { + define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile }); } - define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile }); } if (Report.Errors > 0) return false; - CodeGen.Save (output_file, want_debugging_support); + CodeGen.Save (output_file, want_debugging_support, Report); if (timestamps) { ShowTime ("Saved output"); ShowTotalTime ("Total"); } Timer.ShowTimers (); - - if (Report.ExpectedError != 0) { - if (Report.Errors == 0) { - Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" + - "No other errors reported."); - - Environment.Exit (2); - } else { - Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" + - "However, other errors were reported."); - - Environment.Exit (1); - } - - - return false; - } #if DEBUGME Console.WriteLine ("Size of strings held: " + DeclSpace.length); @@ -1811,28 +1867,13 @@ namespace Mono.CSharp { interface IResource { - void Emit (); + void Emit (CompilerContext cc); string FileName { get; } } class EmbededResource : IResource { static MethodInfo embed_res; - - static EmbededResource () { - Type[] argst = new Type [] { - typeof (string), typeof (string), typeof (ResourceAttributes) - }; - - embed_res = typeof (AssemblyBuilder).GetMethod ( - "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, - null, CallingConventions.Any, argst, null); - - if (embed_res == null) { - Report.RuntimeMissingSupport (Location.Null, "Resource embedding"); - } - } - readonly object[] args; public EmbededResource (string name, string file, bool isPrivate) @@ -1843,8 +1884,22 @@ namespace Mono.CSharp args [2] = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public; } - public void Emit() + public void Emit (CompilerContext cc) { + if (embed_res == null) { + var argst = new [] { + typeof (string), typeof (string), typeof (ResourceAttributes) + }; + + embed_res = typeof (AssemblyBuilder).GetMethod ( + "EmbedResourceFile", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, + null, CallingConventions.Any, argst, null); + + if (embed_res == null) { + cc.Report.RuntimeMissingSupport (Location.Null, "Resource embedding"); + } + } + embed_res.Invoke (CodeGen.Assembly.Builder, args); } @@ -1868,7 +1923,7 @@ namespace Mono.CSharp this.attribute = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public; } - public void Emit () + public void Emit (CompilerContext cc) { CodeGen.Assembly.Builder.AddResourceFile (name, Path.GetFileName(file), attribute); } @@ -1881,7 +1936,13 @@ namespace Mono.CSharp } - IDictionary embedded_resources = new HybridDictionary (); + Dictionary embedded_resources = new Dictionary (); + readonly CompilerContext ctx; + + public Resources (CompilerContext ctx) + { + this.ctx = ctx; + } public void Add (bool embeded, string file, string name) { @@ -1890,8 +1951,8 @@ namespace Mono.CSharp public void Add (bool embeded, string file, string name, bool isPrivate) { - if (embedded_resources.Contains (name)) { - Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", name); + if (embedded_resources.ContainsKey (name)) { + ctx.Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", name); return; } IResource r = embeded ? @@ -1905,11 +1966,11 @@ namespace Mono.CSharp { foreach (IResource r in embedded_resources.Values) { if (!File.Exists (r.FileName)) { - Report.Error (1566, "Error reading resource file `{0}'", r.FileName); + ctx.Report.Error (1566, "Error reading resource file `{0}'", r.FileName); continue; } - r.Emit (); + r.Emit (ctx); } } } @@ -1920,16 +1981,14 @@ namespace Mono.CSharp public class CompilerCallableEntryPoint : MarshalByRefObject { public static bool InvokeCompiler (string [] args, TextWriter error) { - Report.Stderr = error; try { - Driver d = Driver.Create (args); + StreamReportPrinter srp = new StreamReportPrinter (error); + Driver d = Driver.Create (args, true, srp); if (d == null) return false; - return d.Compile () && Report.Errors == 0; - } - finally { - Report.Stderr = Console.Error; + return d.Compile () && srp.ErrorsCount == 0; + } finally { Reset (); } } @@ -1939,17 +1998,30 @@ 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 (); + CSharpParser.yacc_verbose_flag = 0; + 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 (); @@ -1959,6 +2031,10 @@ namespace Mono.CSharp AnonymousMethodStorey.Reset (); SymbolWriter.Reset (); Switch.Reset (); + Linq.QueryBlock.TransparentParameter.Reset (); + Convert.Reset (); + TypeInfo.Reset (); + DynamicExpressionStatement.Reset (); } } }