{
string first_source;
- bool timestamps;
internal int fatal_errors;
- //
- // Last time we took the time
- //
- Stopwatch stopwatch;
- DateTime first_time;
-
internal readonly CompilerContext ctx;
static readonly char[] argument_value_separator = new char [] { ';', ',' };
this.ctx = ctx;
}
- public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
+ public static Driver Create (string[] args, bool require_files, Func<string [], int, int> unknown_option_parser, ReportPrinter printer)
{
Driver d = new Driver (new CompilerContext (new Report (printer)));
- if (!d.ParseArguments (args, require_files))
+ if (!d.ParseArguments (args, require_files, unknown_option_parser))
return null;
return d;
Report Report {
get { return ctx.Report; }
}
-
- void ShowTime (string msg)
- {
- if (!timestamps)
- return;
-
- stopwatch.Stop ();
-
- Console.WriteLine ("{0,5}ms {1}", stopwatch.ElapsedMilliseconds, msg);
-
- stopwatch = Stopwatch.StartNew ();
- }
-
- void ShowTotalTime (string msg)
- {
- if (!timestamps)
- return;
-
- DateTime now = DateTime.Now;
- TimeSpan span = now - first_time;
-
- Console.WriteLine (
- "[{0:00}:{1:000}] {2}",
- (int) span.TotalSeconds, span.Milliseconds, msg);
- }
-
+
void tokenize_file (CompilationUnit file, CompilerContext ctx)
{
Stream input;
" --fatal[=COUNT] Makes errors after COUNT fatal\n" +
" --lint Enhanced warnings\n" +
" --parse Only parses the source file\n" +
+ " --runtime:VERSION Sets mscorlib.dll metadata version: v1, v2, v4\n" +
" --stacktrace Shows stack trace at error location\n" +
" --timestamp Displays time stamps of various compiler events\n" +
" -v Verbose parsing (for debugging the parser)\n" +
static void Usage ()
{
Console.WriteLine (
- "Mono C# compiler, Copyright 2001 - 2008 Novell, Inc.\n" +
+ "Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
"mcs [options] source-files\n" +
" --about About the Mono C# compiler\n" +
" -addmodule:M1[,Mn] Adds the module to the generated assembly\n" +
" -checked[+|-] Sets default aritmetic overflow context\n" +
- " -codepage:ID Sets code page to the one in ID (number, utf8, reset)\n" +
" -clscheck[+|-] Disables CLS Compliance verifications\n" +
+ " -codepage:ID Sets code page to the one in ID (number, utf8, reset)\n" +
" -define:S1[;S2] Defines one or more conditional symbols (short: -d)\n" +
" -debug[+|-], -g Generate debugging information\n" +
" -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" +
" -doc:FILE Process documentation comments to XML file\n" +
+ " -fullpaths Any issued error or warning uses absolute file path\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" +
" -nowarn:W1[,Wn] Suppress one or more compiler warnings\n" +
" -optimize[+|-] Enables advanced compiler optimizations (short: -o)\n" +
" -out:FILE Specifies output assembly name\n" +
-#if !SMCS_SOURCE
" -pkg:P1[,Pn] References packages P1..Pn\n" +
-#endif
" -platform:ARCH Specifies the target platform of the output assembly\n" +
" ARCH can be one of: anycpu, x86, x64 or itanium\n" +
" -recurse:SPEC Recursively compiles files according to SPEC pattern\n" +
" -reference:A1[,An] Imports metadata from the specified assembly (short: -r)\n" +
- " -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" +
+ " -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" +
+ " -sdk:VERSION Specifies SDK version of referenced assemlies\n" +
+ " VERSION can be one of: 2 (default), 4\n" +
" -target:KIND Specifies the format of the output assembly (short: -t)\n" +
" KIND can be one of: exe, winexe, library, module\n" +
" -unsafe[+|-] Allows to compile code which uses unsafe keyword\n" +
" -warnaserror[+|-] Treats all warnings as errors\n" +
" -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
" -warn:0-4 Sets warning level, the default is 4 (short -w:)\n" +
- " -help2 Shows internal compiler options\n" +
+ " -helpinternal Shows internal and advanced compiler options\n" +
"\n" +
"Resources:\n" +
" -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
static void About ()
{
Console.WriteLine (
- "The Mono C# compiler is Copyright 2001-2008, Novell, Inc.\n\n" +
+ "The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
"The compiler source code is released under the terms of the \n"+
"MIT X11 or GNU GPL licenses\n\n" +
{
Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
var crp = new ConsoleReportPrinter ();
- Driver d = Driver.Create (args, true, crp);
+ Driver d = Driver.Create (args, true, null, crp);
if (d == null)
return 1;
Location.AddFile (Report, f);
}
- bool ParseArguments (string[] args, bool require_files)
+ bool ParseArguments (string[] args, bool require_files, Func<string [], int, int> unknown_option_parser)
{
List<string> response_file_list = null;
bool parsing_options = true;
if (CSCParseOption (csc_opt, ref args))
continue;
+ if (unknown_option_parser != null){
+ var ret = unknown_option_parser (args, i);
+ if (ret != -1){
+ i = ret;
+ return true;
+ }
+ }
+
Error_WrongOption (arg);
return false;
}
static void Version ()
{
- string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
+ string version = System.Reflection.Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
Console.WriteLine ("Mono C# compiler version {0}", version);
Environment.Exit (0);
}
}
Report.SetIgnoreWarning (warn);
return true;
-
+
case "--wlevel":
Report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
if ((i + 1) >= args.Length){
return true;
case "--timestamp":
- timestamps = true;
+ RootContext.Timestamps = true;
return true;
case "--debug": case "-g":
fatal_errors = 1;
return true;
}
+ if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
+ string version = arg.Substring (10);
+
+ switch (version) {
+ case "v1":
+ case "V1":
+ RootContext.StdLibRuntimeVersion = RuntimeVersion.v1;
+ break;
+ case "v2":
+ case "V2":
+ RootContext.StdLibRuntimeVersion = RuntimeVersion.v2;
+ return true;
+ case "v4":
+ case "V4":
+ RootContext.StdLibRuntimeVersion = RuntimeVersion.v4;
+ return true;
+ }
+ return true;
+ }
+
break;
}
return false;
}
-#if !SMCS_SOURCE
public static string GetPackageFlags (string packages, bool fatal, Report report)
{
ProcessStartInfo pi = new ProcessStartInfo ();
return pkgout;
}
-#endif
//
// This parses the -arg and /arg options to the compiler, even if the strings
//
Console.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
return true;
-#if !SMCS_SOURCE
+
case "/pkg": {
string packages;
return true;
}
-#endif
+
case "/linkres":
case "/linkresource":
case "/res":
case "/resource":
AssemblyResource res = null;
- string[] s = value.Split (argument_value_separator);
+ string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
switch (s.Length) {
case 1:
if (s[0].Length == 0)
return true;
case "/warn":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
SetWarningLevel (value);
return true;
case "/nowarn": {
- string [] warns;
-
if (value.Length == 0){
- Report.Error (5, "/nowarn requires an argument");
- Environment.Exit (1);
+ Error_RequiresArgument (option);
+ break;
}
- warns = value.Split (argument_value_separator);
+ var warns = value.Split (argument_value_separator);
foreach (string wc in warns){
try {
if (wc.Trim ().Length == 0)
return true;
case "/platform":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
switch (value.ToLower (CultureInfo.InvariantCulture)) {
case "anycpu":
RootContext.Platform = Platform.AnyCPU;
return true;
+ case "/sdk":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
+ switch (value.ToLowerInvariant ()) {
+ case "2":
+ RootContext.SdkVersion = SdkVersion.v2;
+ break;
+ case "4":
+ RootContext.SdkVersion = SdkVersion.v4;
+ break;
+ default:
+ Report.Error (-26, "Invalid sdk version name");
+ break;
+ }
+
+ return true;
+
// We just ignore this.
case "/errorreport":
case "/filealign":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
return true;
- case "/help2":
+ case "/helpinternal":
OtherFlags ();
Environment.Exit(0);
return true;
case "/main":
case "/m":
if (value.Length == 0){
- Report.Error (5, arg + " requires an argument");
- Environment.Exit (1);
+ Error_RequiresArgument (option);
+ break;
}
RootContext.MainClass = value;
return true;
return true;
case "/fullpaths":
+ RootContext.ShowFullPaths = true;
return true;
case "/keyfile":
RootContext.StrongNameKeyFile = value;
return true;
+
case "/keycontainer":
- if (value == String.Empty) {
- Report.Error (5, arg + " requires an argument");
- Environment.Exit (1);
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
}
+
RootContext.StrongNameKeyContainer = value;
return true;
case "/delaysign+":
return true;
case "/langversion":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
switch (value.ToLowerInvariant ()) {
case "iso-1":
RootContext.Version = LanguageVersion.ISO_1;
return true;
case "/codepage":
+ if (value.Length == 0) {
+ Error_RequiresArgument (option);
+ break;
+ }
+
switch (value) {
case "utf8":
RootContext.Encoding = new UTF8Encoding();
break;
}
return true;
+
+ default:
+ return false;
}
- return false;
+ return true;
}
void Error_WrongOption (string option)
Report.Error (2005, "Missing file specification for `{0}' option", option);
}
+ void Error_RequiresArgument (string option)
+ {
+ Report.Error (2006, "Missing argument for `{0}' option", option);
+ }
+
static string [] AddArgs (string [] args, string [] extra_args)
{
string [] new_args;
//
public bool Compile ()
{
+ TimeReporter tr = new TimeReporter (RootContext.Timestamps);
+ ctx.TimeReporter = tr;
+ tr.StartTotal ();
+
var module = new ModuleContainer (ctx);
RootContext.ToplevelTypes = module;
- if (timestamps) {
- stopwatch = Stopwatch.StartNew ();
- first_time = DateTime.Now;
- }
-
+ tr.Start (TimeReporter.TimerType.ParseTotal);
Parse (module);
- ShowTime ("Parsing source files");
+ tr.Stop (TimeReporter.TimerType.ParseTotal);
if (Report.Errors > 0)
return false;
output_file_name = Path.GetFileName (output_file);
}
- //
- // Load assemblies required
- //
- if (timestamps)
- stopwatch = Stopwatch.StartNew ();
+#if STATIC
+ var importer = new StaticImporter ();
+ var references_loader = new StaticLoader (importer, ctx);
+
+ tr.Start (TimeReporter.TimerType.AssemblyBuilderSetup);
+ var assembly = new AssemblyDefinitionStatic (module, references_loader, output_file_name, output_file);
+ assembly.Create (references_loader.Domain);
+ tr.Stop (TimeReporter.TimerType.AssemblyBuilderSetup);
+
+ // Create compiler types first even before any referenced
+ // assembly is loaded to allow forward referenced types from
+ // loaded assembly into compiled builder to be resolved
+ // correctly
+ tr.Start (TimeReporter.TimerType.CreateTypeTotal);
+ module.CreateType ();
+ importer.AddCompiledAssembly (assembly);
+ tr.Stop (TimeReporter.TimerType.CreateTypeTotal);
+
+ references_loader.LoadReferences (module);
+
+ tr.Start (TimeReporter.TimerType.PredefinedTypesInit);
+ if (!ctx.BuildinTypes.CheckDefinitions (module))
+ return false;
- var assembly = module.MakeExecutable (output_file_name, output_file);
+ tr.Stop (TimeReporter.TimerType.PredefinedTypesInit);
+
+ references_loader.LoadModules (assembly, module.GlobalRootNamespace);
+#else
+ var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
+ module.SetDeclaringAssembly (assembly);
var importer = new ReflectionImporter (ctx.BuildinTypes);
assembly.Importer = importer;
var loader = new DynamicLoader (importer, ctx);
loader.LoadReferences (module);
- ShowTime ("Imporing referenced assemblies");
-
if (!ctx.BuildinTypes.CheckDefinitions (module))
return false;
- ShowTime ("Initializing predefined types");
-
if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
return false;
- loader.LoadModules (assembly);
+ module.CreateType ();
+ loader.LoadModules (assembly, module.GlobalRootNamespace);
+#endif
+ tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
module.Define ();
-
- ShowTime ("Types definition");
+ tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);
if (Report.Errors > 0)
return false;
- if (Report.Errors == 0 &&
- RootContext.Documentation != null &&
+ if (RootContext.Documentation != null &&
!RootContext.Documentation.OutputDocComment (
output_file, Report))
return false;
//
// Verify using aliases now
//
+ tr.Start (TimeReporter.TimerType.UsingVerification);
NamespaceEntry.VerifyAllUsing ();
+ tr.Stop (TimeReporter.TimerType.UsingVerification);
if (Report.Errors > 0){
return false;
if (Report.Errors > 0)
return false;
-
- //
- // The code generator
- //
- if (timestamps)
- stopwatch = Stopwatch.StartNew ();
- assembly.Emit ();
- ShowTime ("Resolving and emitting members blocks");
+ tr.Start (TimeReporter.TimerType.EmitTotal);
+ assembly.Emit ();
+ tr.Stop (TimeReporter.TimerType.EmitTotal);
if (Report.Errors > 0){
return false;
}
+ tr.Start (TimeReporter.TimerType.CloseTypes);
module.CloseType ();
+ tr.Stop (TimeReporter.TimerType.CloseTypes);
- ShowTime ("Closing types");
-
- if (timestamps)
- stopwatch = Stopwatch.StartNew ();
-
+ tr.Start (TimeReporter.TimerType.Resouces);
assembly.EmbedResources ();
- ShowTime ("Embedding resources");
+ tr.Stop (TimeReporter.TimerType.Resouces);
if (Report.Errors > 0)
return false;
- if (timestamps)
- stopwatch = Stopwatch.StartNew ();
-
assembly.Save ();
- ShowTime ("Saving output assembly");
-
- ShowTotalTime ("Total");
-
- Timer.ShowTimers ();
+#if STATIC
+ references_loader.Dispose ();
+#endif
+ tr.StopTotal ();
+ tr.ShowStats ();
return (Report.Errors == 0);
}
{
try {
StreamReportPrinter srp = new StreamReportPrinter (error);
- Driver d = Driver.Create (args, true, srp);
+ Driver d = Driver.Create (args, true, null, srp);
if (d == null)
return false;
{
CSharpParser.yacc_verbose_flag = 0;
Location.Reset ();
-
+
if (!full_flag)
return;