Merge pull request #950 from ermshiperete/bug-xamarin-2787
[mono.git] / mcs / mcs / settings.cs
1 //
2 // settings.cs: All compiler settings
3 //
4 // Author: Miguel de Icaza (miguel@ximian.com)
5 //            Ravi Pratap  (ravi@ximian.com)
6 //            Marek Safar  (marek.safar@gmail.com)
7 //
8 //
9 // Dual licensed under the terms of the MIT X11 or GNU GPL
10 //
11 // Copyright 2001 Ximian, Inc (http://www.ximian.com)
12 // Copyright 2004-2008 Novell, Inc
13 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
14 //
15
16 using System.Collections.Generic;
17 using System.IO;
18 using System.Text;
19 using System.Globalization;
20 using System;
21
22 namespace Mono.CSharp {
23
24         public enum LanguageVersion
25         {
26                 ISO_1 = 1,
27                 ISO_2 = 2,
28                 V_3 = 3,
29                 V_4 = 4,
30                 V_5 = 5,
31                 Future = 100,
32
33                 Default = LanguageVersion.Future,
34         }
35
36         public enum RuntimeVersion
37         {
38                 v1,
39                 v2,
40                 v4
41         }
42
43         public enum Target
44         {
45                 Library, Exe, Module, WinExe
46         }
47
48         public enum Platform
49         {
50                 AnyCPU,
51                 AnyCPU32Preferred,
52                 Arm,
53                 X86,
54                 X64,
55                 IA64
56         }
57
58         public class CompilerSettings
59         {
60                 public Target Target;
61                 public Platform Platform;
62                 public string TargetExt;
63                 public bool VerifyClsCompliance;
64                 public bool Optimize;
65                 public LanguageVersion Version;
66                 public bool EnhancedWarnings;
67                 public bool LoadDefaultReferences;
68                 public string SdkVersion;
69
70                 public string StrongNameKeyFile;
71                 public string StrongNameKeyContainer;
72                 public bool StrongNameDelaySign;
73
74                 public int TabSize;
75
76                 public bool WarningsAreErrors;
77                 public int WarningLevel;
78
79                 //
80                 // Assemblies references to be loaded
81                 //
82                 public List<string> AssemblyReferences;
83
84                 // 
85                 // External aliases for assemblies
86                 //
87                 public List<Tuple<string, string>> AssemblyReferencesAliases;
88
89                 //
90                 // Modules to be embedded
91                 //
92                 public List<string> Modules;
93
94                 //
95                 // Lookup paths for referenced assemblies
96                 //
97                 public List<string> ReferencesLookupPaths;
98
99                 //
100                 // Encoding.
101                 //
102                 public Encoding Encoding;
103
104                 //
105                 // If set, enable XML documentation generation
106                 //
107                 public string DocumentationFile;
108
109                 public string MainClass;
110
111                 //
112                 // Output file
113                 //
114                 public string OutputFile;
115
116                 // 
117                 // The default compiler checked state
118                 //
119                 public bool Checked;
120
121                 //
122                 // If true, the compiler is operating in statement mode,
123                 // this currently turns local variable declaration into
124                 // static variables of a class
125                 //
126                 public bool StatementMode;      // TODO: SUPER UGLY
127                 
128                 //
129                 // Whether to allow Unsafe code
130                 //
131                 public bool Unsafe;
132
133                 public string Win32ResourceFile;
134                 public string Win32IconFile;
135
136                 //
137                 // A list of resource files for embedding
138                 //
139                 public List<AssemblyResource> Resources;
140
141                 public bool GenerateDebugInfo;
142
143                 #region Compiler debug flags only
144                 public bool ParseOnly, TokenizeOnly, Timestamps;
145                 public int DebugFlags;
146                 public int VerboseParserFlag;
147                 public int FatalCounter;
148                 public bool Stacktrace;
149                 public bool BreakOnInternalError;
150                 #endregion
151
152                 public bool ShowFullPaths;
153
154                 //
155                 // Whether we are being linked against the standard libraries.
156                 // This is only used to tell whether `System.Object' should
157                 // have a base class or not.
158                 //
159                 public bool StdLib;
160
161                 public RuntimeVersion StdLibRuntimeVersion;
162
163                 public string RuntimeMetadataVersion;
164
165                 public bool WriteMetadataOnly;
166
167                 readonly List<string> conditional_symbols;
168
169                 readonly List<SourceFile> source_files;
170
171                 List<int> warnings_as_error;
172                 List<int> warnings_only;
173                 HashSet<int> warning_ignore_table;
174
175                 public CompilerSettings ()
176                 {
177                         StdLib = true;
178                         Target = Target.Exe;
179                         TargetExt = ".exe";
180                         Platform = Platform.AnyCPU;
181                         Version = LanguageVersion.Default;
182                         VerifyClsCompliance = true;
183                         Encoding = Encoding.UTF8;
184                         LoadDefaultReferences = true;
185                         StdLibRuntimeVersion = RuntimeVersion.v4;
186                         WarningLevel = 4;
187
188                         // Default to 1 or mdb files would be platform speficic
189                         TabSize = 1;
190
191                         AssemblyReferences = new List<string> ();
192                         AssemblyReferencesAliases = new List<Tuple<string, string>> ();
193                         Modules = new List<string> ();
194                         ReferencesLookupPaths = new List<string> ();
195
196                         conditional_symbols = new List<string> ();
197                         //
198                         // Add default mcs define
199                         //
200                         conditional_symbols.Add ("__MonoCS__");
201
202                         source_files = new List<SourceFile> ();
203                 }
204
205                 #region Properties
206
207                 public SourceFile FirstSourceFile {
208                         get {
209                                 return source_files.Count > 0 ? source_files [0] : null;
210                         }
211                 }
212
213                 public bool HasKeyFileOrContainer {
214                         get {
215                                 return StrongNameKeyFile != null || StrongNameKeyContainer != null;
216                         }
217                 }
218
219                 public bool NeedsEntryPoint {
220                         get {
221                                 return Target == Target.Exe || Target == Target.WinExe;
222                         }
223                 }
224
225                 public List<SourceFile> SourceFiles {
226                         get {
227                                 return source_files;
228                         }
229                 }
230
231                 #endregion
232
233                 public void AddConditionalSymbol (string symbol)
234                 {
235                         if (!conditional_symbols.Contains (symbol))
236                                 conditional_symbols.Add (symbol);
237                 }
238
239                 public void AddWarningAsError (int id)
240                 {
241                         if (warnings_as_error == null)
242                                 warnings_as_error = new List<int> ();
243
244                         warnings_as_error.Add (id);
245                 }
246
247                 public void AddWarningOnly (int id)
248                 {
249                         if (warnings_only == null)
250                                 warnings_only = new List<int> ();
251
252                         warnings_only.Add (id);
253                 }
254
255                 public bool IsConditionalSymbolDefined (string symbol)
256                 {
257                         return conditional_symbols.Contains (symbol);
258                 }
259
260                 public bool IsWarningAsError (int code)
261                 {
262                         bool is_error = WarningsAreErrors;
263
264                         // Check specific list
265                         if (warnings_as_error != null)
266                                 is_error |= warnings_as_error.Contains (code);
267
268                         // Ignore excluded warnings
269                         if (warnings_only != null && warnings_only.Contains (code))
270                                 is_error = false;
271
272                         return is_error;
273                 }
274
275                 public bool IsWarningEnabled (int code, int level)
276                 {
277                         if (WarningLevel < level)
278                                 return false;
279
280                         return !IsWarningDisabledGlobally (code);
281                 }
282
283                 public bool IsWarningDisabledGlobally (int code)
284                 {
285                         return warning_ignore_table != null && warning_ignore_table.Contains (code);
286                 }
287
288                 public void SetIgnoreWarning (int code)
289                 {
290                         if (warning_ignore_table == null)
291                                 warning_ignore_table = new HashSet<int> ();
292
293                         warning_ignore_table.Add (code);
294                 }
295         }
296
297         public class CommandLineParser
298         {
299                 enum ParseResult
300                 {
301                         Success,
302                         Error,
303                         Stop,
304                         UnknownOption
305                 }
306
307                 static readonly char[] argument_value_separator = { ';', ',' };
308                 static readonly char[] numeric_value_separator = { ';', ',', ' ' };
309
310                 readonly TextWriter output;
311                 readonly Report report;
312                 bool stop_argument;
313
314                 Dictionary<string, int> source_file_index;
315
316                 public event Func<string[], int, int> UnknownOptionHandler;
317
318                 CompilerSettings parser_settings;
319
320                 public CommandLineParser (TextWriter errorOutput)
321                         : this (errorOutput, Console.Out)
322                 {
323                 }
324
325                 public CommandLineParser (TextWriter errorOutput, TextWriter messagesOutput)
326                 {
327                         var rp = new StreamReportPrinter (errorOutput);
328
329                         parser_settings = new CompilerSettings ();
330                         report = new Report (new CompilerContext (parser_settings, rp), rp);
331                         this.output = messagesOutput;
332                 }
333
334                 public bool HasBeenStopped {
335                         get {
336                                 return stop_argument;
337                         }
338                 }
339
340                 void About ()
341                 {
342                         output.WriteLine (
343                                 "The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
344                                 "The compiler source code is released under the terms of the \n" +
345                                 "MIT X11 or GNU GPL licenses\n\n" +
346
347                                 "For more information on Mono, visit the project Web site\n" +
348                                 "   http://www.mono-project.com\n\n" +
349
350                                 "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja R Harinath, Atushi Enomoto");
351                 }
352
353                 public CompilerSettings ParseArguments (string[] args)
354                 {
355                         CompilerSettings settings = new CompilerSettings ();
356                         if (!ParseArguments (settings, args))
357                                 return null;
358
359                         return settings;
360                 }
361
362                 public bool ParseArguments (CompilerSettings settings, string[] args)
363                 {
364                         if (settings == null)
365                                 throw new ArgumentNullException ("settings");
366
367                         List<string> response_file_list = null;
368                         bool parsing_options = true;
369                         stop_argument = false;
370                         source_file_index = new Dictionary<string, int> ();
371
372                         for (int i = 0; i < args.Length; i++) {
373                                 string arg = args[i];
374                                 if (arg.Length == 0)
375                                         continue;
376
377                                 if (arg[0] == '@') {
378                                         string[] extra_args;
379                                         string response_file = arg.Substring (1);
380
381                                         if (response_file_list == null)
382                                                 response_file_list = new List<string> ();
383
384                                         if (response_file_list.Contains (response_file)) {
385                                                 report.Error (1515, "Response file `{0}' specified multiple times", response_file);
386                                                 return false;
387                                         }
388
389                                         response_file_list.Add (response_file);
390
391                                         extra_args = LoadArgs (response_file);
392                                         if (extra_args == null) {
393                                                 report.Error (2011, "Unable to open response file: " + response_file);
394                                                 return false;
395                                         }
396
397                                         args = AddArgs (args, extra_args);
398                                         continue;
399                                 }
400
401                                 if (parsing_options) {
402                                         if (arg == "--") {
403                                                 parsing_options = false;
404                                                 continue;
405                                         }
406
407                                         bool dash_opt = arg[0] == '-';
408                                         bool slash_opt = arg[0] == '/';
409                                         if (dash_opt) {
410                                                 switch (ParseOptionUnix (arg, ref args, ref i, settings)) {
411                                                 case ParseResult.Error:
412                                                 case ParseResult.Success:
413                                                         continue;
414                                                 case ParseResult.Stop:
415                                                         stop_argument = true;
416                                                         return true;
417                                                 case ParseResult.UnknownOption:
418                                                         if (UnknownOptionHandler != null) {
419                                                                 var ret = UnknownOptionHandler (args, i);
420                                                                 if (ret != -1) {
421                                                                         i = ret;
422                                                                         continue;
423                                                                 }
424                                                         }
425                                                         break;
426                                                 }
427                                         }
428
429                                         if (dash_opt || slash_opt) {
430                                                 // Try a -CSCOPTION
431                                                 string csc_opt = dash_opt ? "/" + arg.Substring (1) : arg;
432                                                 switch (ParseOption (csc_opt, ref args, settings)) {
433                                                 case ParseResult.Error:
434                                                 case ParseResult.Success:
435                                                         continue;
436                                                 case ParseResult.UnknownOption:
437                                                         // Need to skip `/home/test.cs' however /test.cs is considered as error
438                                                         if ((slash_opt && arg.Length > 3 && arg.IndexOf ('/', 2) > 0))
439                                                                 break;
440
441                                                         if (UnknownOptionHandler != null) {
442                                                                 var ret = UnknownOptionHandler (args, i);
443                                                                 if (ret != -1) {
444                                                                         i = ret;
445                                                                         continue;
446                                                                 }
447                                                         }
448
449                                                         Error_WrongOption (arg);
450                                                         return false;
451
452                                                 case ParseResult.Stop:
453                                                         stop_argument = true;
454                                                         return true;
455                                                 }
456                                         }
457                                 }
458
459                                 ProcessSourceFiles (arg, false, settings.SourceFiles);
460                         }
461
462                         return report.Errors == 0;
463                 }
464
465                 void ProcessSourceFiles (string spec, bool recurse, List<SourceFile> sourceFiles)
466                 {
467                         string path, pattern;
468
469                         SplitPathAndPattern (spec, out path, out pattern);
470                         if (pattern.IndexOf ('*') == -1) {
471                                 AddSourceFile (spec, sourceFiles);
472                                 return;
473                         }
474
475                         string[] files;
476                         try {
477                                 files = Directory.GetFiles (path, pattern);
478                         } catch (System.IO.DirectoryNotFoundException) {
479                                 report.Error (2001, "Source file `" + spec + "' could not be found");
480                                 return;
481                         } catch (System.IO.IOException) {
482                                 report.Error (2001, "Source file `" + spec + "' could not be found");
483                                 return;
484                         }
485                         foreach (string f in files) {
486                                 AddSourceFile (f, sourceFiles);
487                         }
488
489                         if (!recurse)
490                                 return;
491
492                         string[] dirs = null;
493
494                         try {
495                                 dirs = Directory.GetDirectories (path);
496                         } catch {
497                         }
498
499                         foreach (string d in dirs) {
500
501                                 // Don't include path in this string, as each
502                                 // directory entry already does
503                                 ProcessSourceFiles (d + "/" + pattern, true, sourceFiles);
504                         }
505                 }
506
507                 static string[] AddArgs (string[] args, string[] extra_args)
508                 {
509                         string[] new_args;
510                         new_args = new string[extra_args.Length + args.Length];
511
512                         // if args contains '--' we have to take that into account
513                         // split args into first half and second half based on '--'
514                         // and add the extra_args before --
515                         int split_position = Array.IndexOf (args, "--");
516                         if (split_position != -1) {
517                                 Array.Copy (args, new_args, split_position);
518                                 extra_args.CopyTo (new_args, split_position);
519                                 Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
520                         } else {
521                                 args.CopyTo (new_args, 0);
522                                 extra_args.CopyTo (new_args, args.Length);
523                         }
524
525                         return new_args;
526                 }
527
528                 void AddAssemblyReference (string alias, string assembly, CompilerSettings settings)
529                 {
530                         if (assembly.Length == 0) {
531                                 report.Error (1680, "Invalid reference alias `{0}='. Missing filename", alias);
532                                 return;
533                         }
534
535                         if (!IsExternAliasValid (alias)) {
536                                 report.Error (1679, "Invalid extern alias for -reference. Alias `{0}' is not a valid identifier", alias);
537                                 return;
538                         }
539
540                         settings.AssemblyReferencesAliases.Add (Tuple.Create (alias, assembly));
541                 }
542
543                 void AddResource (AssemblyResource res, CompilerSettings settings)
544                 {
545                         if (settings.Resources == null) {
546                                 settings.Resources = new List<AssemblyResource> ();
547                                 settings.Resources.Add (res);
548                                 return;
549                         }
550
551                         if (settings.Resources.Contains (res)) {
552                                 report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", res.Name);
553                                 return;
554                         }
555
556                         settings.Resources.Add (res);
557                 }
558
559                 void AddSourceFile (string fileName, List<SourceFile> sourceFiles)
560                 {
561                         string path = Path.GetFullPath (fileName);
562
563                         int index;
564                         if (source_file_index.TryGetValue (path, out index)) {
565                                 string other_name = sourceFiles[index - 1].Name;
566                                 if (fileName.Equals (other_name))
567                                         report.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name);
568                                 else
569                                         report.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", fileName, other_name, path);
570
571                                 return;
572                         }
573
574                         var unit = new SourceFile (fileName, path, sourceFiles.Count + 1);
575                         sourceFiles.Add (unit);
576                         source_file_index.Add (path, unit.Index);
577                 }
578
579                 public bool ProcessWarningsList (string text, Action<int> action)
580                 {
581                         bool valid = true;
582                         foreach (string wid in text.Split (numeric_value_separator, StringSplitOptions.RemoveEmptyEntries)) {
583                                 int id;
584                                 if (!int.TryParse (wid, NumberStyles.AllowLeadingWhite, CultureInfo.InvariantCulture, out id)) {
585                                         report.Error (1904, "`{0}' is not a valid warning number", wid);
586                                         valid = false;
587                                         continue;
588                                 }
589
590                                 if (report.CheckWarningCode (id, Location.Null))
591                                         action (id);
592                         }
593
594                         return valid;
595                 }
596
597                 void Error_RequiresArgument (string option)
598                 {
599                         report.Error (2006, "Missing argument for `{0}' option", option);
600                 }
601
602                 void Error_RequiresFileName (string option)
603                 {
604                         report.Error (2005, "Missing file specification for `{0}' option", option);
605                 }
606
607                 void Error_WrongOption (string option)
608                 {
609                         report.Error (2007, "Unrecognized command-line option: `{0}'", option);
610                 }
611
612                 static bool IsExternAliasValid (string identifier)
613                 {
614                         return Tokenizer.IsValidIdentifier (identifier);
615                 }
616
617                 static string[] LoadArgs (string file)
618                 {
619                         StreamReader f;
620                         var args = new List<string> ();
621                         string line;
622                         try {
623                                 f = new StreamReader (file);
624                         } catch {
625                                 return null;
626                         }
627
628                         StringBuilder sb = new StringBuilder ();
629
630                         while ((line = f.ReadLine ()) != null) {
631                                 int t = line.Length;
632
633                                 for (int i = 0; i < t; i++) {
634                                         char c = line[i];
635
636                                         if (c == '"' || c == '\'') {
637                                                 char end = c;
638
639                                                 for (i++; i < t; i++) {
640                                                         c = line[i];
641
642                                                         if (c == end)
643                                                                 break;
644                                                         sb.Append (c);
645                                                 }
646                                         } else if (c == ' ') {
647                                                 if (sb.Length > 0) {
648                                                         args.Add (sb.ToString ());
649                                                         sb.Length = 0;
650                                                 }
651                                         } else
652                                                 sb.Append (c);
653                                 }
654                                 if (sb.Length > 0) {
655                                         args.Add (sb.ToString ());
656                                         sb.Length = 0;
657                                 }
658                         }
659
660                         return args.ToArray ();
661                 }
662
663                 void OtherFlags ()
664                 {
665                         output.WriteLine (
666                                 "Other flags in the compiler\n" +
667                                 "   --fatal[=COUNT]    Makes error after COUNT fatal\n" +
668                                 "   --lint             Enhanced warnings\n" +
669                                 "   --metadata-only    Produced assembly will contain metadata only\n" +
670                                 "   --parse            Only parses the source file\n" +
671                                 "   --runtime:VERSION  Sets mscorlib.dll metadata version: v1, v2, v4\n" +
672                                 "   --stacktrace       Shows stack trace at error location\n" +
673                                 "   --timestamp        Displays time stamps of various compiler events\n" +
674                                 "   -v                 Verbose parsing (for debugging the parser)\n" +
675                                 "   --mcs-debug X      Sets MCS debugging level to X\n" +
676                                 "   --break-on-ice     Breaks compilation on internal compiler error");
677                 }
678
679                 //
680                 // This parses the -arg and /arg options to the compiler, even if the strings
681                 // in the following text use "/arg" on the strings.
682                 //
683                 ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings)
684                 {
685                         int idx = option.IndexOf (':');
686                         string arg, value;
687
688                         if (idx == -1) {
689                                 arg = option;
690                                 value = "";
691                         } else {
692                                 arg = option.Substring (0, idx);
693
694                                 value = option.Substring (idx + 1);
695                         }
696
697                         switch (arg.ToLowerInvariant ()) {
698                         case "/nologo":
699                                 return ParseResult.Success;
700
701                         case "/t":
702                         case "/target":
703                                 switch (value) {
704                                 case "exe":
705                                         settings.Target = Target.Exe;
706                                         break;
707
708                                 case "winexe":
709                                         settings.Target = Target.WinExe;
710                                         break;
711
712                                 case "library":
713                                         settings.Target = Target.Library;
714                                         settings.TargetExt = ".dll";
715                                         break;
716
717                                 case "module":
718                                         settings.Target = Target.Module;
719                                         settings.TargetExt = ".netmodule";
720                                         break;
721
722                                 default:
723                                         report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
724                                         return ParseResult.Error;
725                                 }
726                                 return ParseResult.Success;
727
728                         case "/out":
729                                 if (value.Length == 0) {
730                                         Error_RequiresFileName (option);
731                                         return ParseResult.Error;
732                                 }
733                                 settings.OutputFile = value;
734                                 return ParseResult.Success;
735
736                         case "/o":
737                         case "/o+":
738                         case "/optimize":
739                         case "/optimize+":
740                                 settings.Optimize = true;
741                                 return ParseResult.Success;
742
743                         case "/o-":
744                         case "/optimize-":
745                                 settings.Optimize = false;
746                                 return ParseResult.Success;
747
748                         // TODO: Not supported by csc 3.5+
749                         case "/incremental":
750                         case "/incremental+":
751                         case "/incremental-":
752                                 // nothing.
753                                 return ParseResult.Success;
754
755                         case "/d":
756                         case "/define": {
757                                         if (value.Length == 0) {
758                                                 Error_RequiresArgument (option);
759                                                 return ParseResult.Error;
760                                         }
761
762                                         foreach (string d in value.Split (argument_value_separator)) {
763                                                 string conditional = d.Trim ();
764                                                 if (!Tokenizer.IsValidIdentifier (conditional)) {
765                                                         report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
766                                                         continue;
767                                                 }
768
769                                                 settings.AddConditionalSymbol (conditional);
770                                         }
771                                         return ParseResult.Success;
772                                 }
773
774                         case "/bugreport":
775                                 //
776                                 // We should collect data, runtime, etc and store in the file specified
777                                 //
778                                 output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
779                                 return ParseResult.Success;
780
781                         case "/pkg": {
782                                         string packages;
783
784                                         if (value.Length == 0) {
785                                                 Error_RequiresArgument (option);
786                                                 return ParseResult.Error;
787                                         }
788                                         packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' }));
789                                         string pkgout = Driver.GetPackageFlags (packages, report);
790
791                                         if (pkgout == null)
792                                                 return ParseResult.Error;
793
794                                         string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' });
795                                         args = AddArgs (args, xargs);
796                                         return ParseResult.Success;
797                                 }
798
799                         case "/linkres":
800                         case "/linkresource":
801                         case "/res":
802                         case "/resource":
803                                 AssemblyResource res = null;
804                                 string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
805                                 switch (s.Length) {
806                                 case 1:
807                                         if (s[0].Length == 0)
808                                                 goto default;
809                                         res = new AssemblyResource (s[0], Path.GetFileName (s[0]));
810                                         break;
811                                 case 2:
812                                         res = new AssemblyResource (s[0], s[1]);
813                                         break;
814                                 case 3:
815                                         if (s[2] != "public" && s[2] != "private") {
816                                                 report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]);
817                                                 return ParseResult.Error;
818                                         }
819                                         res = new AssemblyResource (s[0], s[1], s[2] == "private");
820                                         break;
821                                 default:
822                                         report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
823                                         return ParseResult.Error;
824                                 }
825
826                                 if (res != null) {
827                                         res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R';
828                                         AddResource (res, settings);
829                                 }
830
831                                 return ParseResult.Success;
832
833                         case "/recurse":
834                                 if (value.Length == 0) {
835                                         Error_RequiresFileName (option);
836                                         return ParseResult.Error;
837                                 }
838                                 ProcessSourceFiles (value, true, settings.SourceFiles);
839                                 return ParseResult.Success;
840
841                         case "/r":
842                         case "/reference": {
843                                         if (value.Length == 0) {
844                                                 Error_RequiresFileName (option);
845                                                 return ParseResult.Error;
846                                         }
847
848                                         string[] refs = value.Split (argument_value_separator);
849                                         foreach (string r in refs) {
850                                                 if (r.Length == 0)
851                                                         continue;
852
853                                                 string val = r;
854                                                 int index = val.IndexOf ('=');
855                                                 if (index > -1) {
856                                                         string alias = r.Substring (0, index);
857                                                         string assembly = r.Substring (index + 1);
858                                                         AddAssemblyReference (alias, assembly, settings);
859                                                         if (refs.Length != 1) {
860                                                                 report.Error (2034, "Cannot specify multiple aliases using single /reference option");
861                                                                 return ParseResult.Error;
862                                                         }
863                                                 } else {
864                                                         settings.AssemblyReferences.Add (val);
865                                                 }
866                                         }
867                                         return ParseResult.Success;
868                                 }
869                         case "/addmodule": {
870                                         if (value.Length == 0) {
871                                                 Error_RequiresFileName (option);
872                                                 return ParseResult.Error;
873                                         }
874
875                                         string[] refs = value.Split (argument_value_separator);
876                                         foreach (string r in refs) {
877                                                 settings.Modules.Add (r);
878                                         }
879                                         return ParseResult.Success;
880                                 }
881                         case "/win32res": {
882                                         if (value.Length == 0) {
883                                                 Error_RequiresFileName (option);
884                                                 return ParseResult.Error;
885                                         }
886
887                                         if (settings.Win32IconFile != null)
888                                                 report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
889
890                                         settings.Win32ResourceFile = value;
891                                         return ParseResult.Success;
892                                 }
893                         case "/win32icon": {
894                                         if (value.Length == 0) {
895                                                 Error_RequiresFileName (option);
896                                                 return ParseResult.Error;
897                                         }
898
899                                         if (settings.Win32ResourceFile != null)
900                                                 report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
901
902                                         settings.Win32IconFile = value;
903                                         return ParseResult.Success;
904                                 }
905                         case "/doc": {
906                                         if (value.Length == 0) {
907                                                 Error_RequiresFileName (option);
908                                                 return ParseResult.Error;
909                                         }
910
911                                         settings.DocumentationFile = value;
912                                         return ParseResult.Success;
913                                 }
914                         case "/lib": {
915                                         string[] libdirs;
916
917                                         if (value.Length == 0) {
918                                                 return ParseResult.Error;
919                                         }
920
921                                         libdirs = value.Split (argument_value_separator);
922                                         foreach (string dir in libdirs)
923                                                 settings.ReferencesLookupPaths.Add (dir);
924                                         return ParseResult.Success;
925                                 }
926
927                         case "/debug-":
928                                 settings.GenerateDebugInfo = false;
929                                 return ParseResult.Success;
930
931                         case "/debug":
932                                 if (value.Equals ("full", StringComparison.OrdinalIgnoreCase) || value.Equals ("pdbonly", StringComparison.OrdinalIgnoreCase) || idx < 0) {
933                                         settings.GenerateDebugInfo = true;
934                                         return ParseResult.Success;
935                                 }
936
937                                 if (value.Length > 0) {
938                                         report.Error (1902, "Invalid debug option `{0}'. Valid options are `full' or `pdbonly'", value);
939                                 } else {
940                                         Error_RequiresArgument (option);
941                                 }
942
943                                 return ParseResult.Error;
944
945                         case "/debug+":
946                                 settings.GenerateDebugInfo = true;
947                                 return ParseResult.Success;
948
949                         case "/checked":
950                         case "/checked+":
951                                 settings.Checked = true;
952                                 return ParseResult.Success;
953
954                         case "/checked-":
955                                 settings.Checked = false;
956                                 return ParseResult.Success;
957
958                         case "/clscheck":
959                         case "/clscheck+":
960                                 settings.VerifyClsCompliance = true;
961                                 return ParseResult.Success;
962
963                         case "/clscheck-":
964                                 settings.VerifyClsCompliance = false;
965                                 return ParseResult.Success;
966
967                         case "/unsafe":
968                         case "/unsafe+":
969                                 settings.Unsafe = true;
970                                 return ParseResult.Success;
971
972                         case "/unsafe-":
973                                 settings.Unsafe = false;
974                                 return ParseResult.Success;
975
976                         case "/warnaserror":
977                         case "/warnaserror+":
978                                 if (value.Length == 0) {
979                                         settings.WarningsAreErrors = true;
980                                         parser_settings.WarningsAreErrors = true;
981                                 } else {
982                                         if (!ProcessWarningsList (value, settings.AddWarningAsError))
983                                                 return ParseResult.Error;
984                                 }
985                                 return ParseResult.Success;
986
987                         case "/warnaserror-":
988                                 if (value.Length == 0) {
989                                         settings.WarningsAreErrors = false;
990                                 } else {
991                                         if (!ProcessWarningsList (value, settings.AddWarningOnly))
992                                                 return ParseResult.Error;
993                                 }
994                                 return ParseResult.Success;
995
996                         case "/warn":
997                         case "/w":
998                                 if (value.Length == 0) {
999                                         Error_RequiresArgument (option);
1000                                         return ParseResult.Error;
1001                                 }
1002
1003                                 SetWarningLevel (value, settings);
1004                                 return ParseResult.Success;
1005
1006                         case "/nowarn":
1007                                 if (value.Length == 0) {
1008                                         Error_RequiresArgument (option);
1009                                         return ParseResult.Error;
1010                                 }
1011
1012                                 if (!ProcessWarningsList (value, settings.SetIgnoreWarning))
1013                                         return ParseResult.Error;
1014
1015                                 return ParseResult.Success;
1016
1017                         case "/noconfig":
1018                                 settings.LoadDefaultReferences = false;
1019                                 return ParseResult.Success;
1020
1021                         case "/platform":
1022                                 if (value.Length == 0) {
1023                                         Error_RequiresArgument (option);
1024                                         return ParseResult.Error;
1025                                 }
1026
1027                                 switch (value.ToLowerInvariant ()) {
1028                                 case "arm":
1029                                         settings.Platform = Platform.Arm;
1030                                         break;
1031                                 case "anycpu":
1032                                         settings.Platform = Platform.AnyCPU;
1033                                         break;
1034                                 case "x86":
1035                                         settings.Platform = Platform.X86;
1036                                         break;
1037                                 case "x64":
1038                                         settings.Platform = Platform.X64;
1039                                         break;
1040                                 case "itanium":
1041                                         settings.Platform = Platform.IA64;
1042                                         break;
1043                                 case "anycpu32bitpreferred":
1044                                         settings.Platform = Platform.AnyCPU32Preferred;
1045                                         break;
1046                                 default:
1047                                         report.Error (1672, "Invalid -platform option `{0}'. Valid options are `anycpu', `anycpu32bitpreferred', `arm', `x86', `x64' or `itanium'",
1048                                                 value);
1049                                         return ParseResult.Error;
1050                                 }
1051
1052                                 return ParseResult.Success;
1053
1054                         case "/sdk":
1055                                 if (value.Length == 0) {
1056                                         Error_RequiresArgument (option);
1057                                         return ParseResult.Error;
1058                                 }
1059
1060                                 settings.SdkVersion = value;
1061                                 return ParseResult.Success;
1062
1063                         // We just ignore this.
1064                         case "/errorreport":
1065                         case "/filealign":
1066                                 if (value.Length == 0) {
1067                                         Error_RequiresArgument (option);
1068                                         return ParseResult.Error;
1069                                 }
1070
1071                                 return ParseResult.Success;
1072
1073                         case "/helpinternal":
1074                                 OtherFlags ();
1075                                 return ParseResult.Stop;
1076
1077                         case "/help":
1078                         case "/?":
1079                                 Usage ();
1080                                 return ParseResult.Stop;
1081
1082                         case "/main":
1083                         case "/m":
1084                                 if (value.Length == 0) {
1085                                         Error_RequiresArgument (option);
1086                                         return ParseResult.Error;
1087                                 }
1088                                 settings.MainClass = value;
1089                                 return ParseResult.Success;
1090
1091                         case "/nostdlib":
1092                         case "/nostdlib+":
1093                                 settings.StdLib = false;
1094                                 return ParseResult.Success;
1095
1096                         case "/nostdlib-":
1097                                 settings.StdLib = true;
1098                                 return ParseResult.Success;
1099
1100                         case "/fullpaths":
1101                                 settings.ShowFullPaths = true;
1102                                 return ParseResult.Success;
1103
1104                         case "/keyfile":
1105                                 if (value.Length == 0) {
1106                                         Error_RequiresFileName (option);
1107                                         return ParseResult.Error;
1108                                 }
1109
1110                                 settings.StrongNameKeyFile = value;
1111                                 return ParseResult.Success;
1112
1113                         case "/keycontainer":
1114                                 if (value.Length == 0) {
1115                                         Error_RequiresArgument (option);
1116                                         return ParseResult.Error;
1117                                 }
1118
1119                                 settings.StrongNameKeyContainer = value;
1120                                 return ParseResult.Success;
1121
1122                         case "/delaysign+":
1123                         case "/delaysign":
1124                                 settings.StrongNameDelaySign = true;
1125                                 return ParseResult.Success;
1126
1127                         case "/delaysign-":
1128                                 settings.StrongNameDelaySign = false;
1129                                 return ParseResult.Success;
1130
1131                         case "/langversion":
1132                                 if (value.Length == 0) {
1133                                         Error_RequiresArgument (option);
1134                                         return ParseResult.Error;
1135                                 }
1136
1137                                 switch (value.ToLowerInvariant ()) {
1138                                 case "iso-1":
1139                                         settings.Version = LanguageVersion.ISO_1;
1140                                         return ParseResult.Success;
1141                                 case "default":
1142                                         settings.Version = LanguageVersion.Default;
1143                                         return ParseResult.Success;
1144                                 case "iso-2":
1145                                         settings.Version = LanguageVersion.ISO_2;
1146                                         return ParseResult.Success;
1147                                 case "3":
1148                                         settings.Version = LanguageVersion.V_3;
1149                                         return ParseResult.Success;
1150                                 case "4":
1151                                         settings.Version = LanguageVersion.V_4;
1152                                         return ParseResult.Success;
1153                                 case "5":
1154                                         settings.Version = LanguageVersion.V_5;
1155                                         return ParseResult.Success;
1156                                 case "future":
1157                                         settings.Version = LanguageVersion.Future;
1158                                         return ParseResult.Success;
1159                                 }
1160
1161                                 report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3', `4', `5', `Default' or `Future'", value);
1162                                 return ParseResult.Error;
1163
1164                         case "/codepage":
1165                                 if (value.Length == 0) {
1166                                         Error_RequiresArgument (option);
1167                                         return ParseResult.Error;
1168                                 }
1169
1170                                 switch (value) {
1171                                 case "utf8":
1172                                         settings.Encoding = Encoding.UTF8;
1173                                         break;
1174                                 case "reset":
1175                                         settings.Encoding = Encoding.Default;
1176                                         break;
1177                                 default:
1178                                         try {
1179                                                 settings.Encoding = Encoding.GetEncoding (int.Parse (value));
1180                                         } catch {
1181                                                 report.Error (2016, "Code page `{0}' is invalid or not installed", value);
1182                                         }
1183                                         return ParseResult.Error;
1184                                 }
1185                                 return ParseResult.Success;
1186
1187                         case "runtimemetadataversion":
1188                                 if (value.Length == 0) {
1189                                         Error_RequiresArgument (option);
1190                                         return ParseResult.Error;
1191                                 }
1192
1193                                 settings.RuntimeMetadataVersion = value;
1194                                 return ParseResult.Success;
1195
1196                         default:
1197                                 return ParseResult.UnknownOption;
1198                         }
1199                 }
1200
1201                 //
1202                 // Currently handles the Unix-like command line options, but will be
1203                 // deprecated in favor of the CSCParseOption, which will also handle the
1204                 // options that start with a dash in the future.
1205                 //
1206                 ParseResult ParseOptionUnix (string arg, ref string[] args, ref int i, CompilerSettings settings)
1207                 {
1208                         switch (arg){
1209                         case "-v":
1210                                 settings.VerboseParserFlag++;
1211                                 return ParseResult.Success;
1212
1213                         case "--version":
1214                                 Version ();
1215                                 return ParseResult.Stop;
1216                                 
1217                         case "--parse":
1218                                 settings.ParseOnly = true;
1219                                 return ParseResult.Success;
1220                                 
1221                         case "--main": case "-m":
1222                                 report.Warning (-29, 1, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
1223                                 if ((i + 1) >= args.Length){
1224                                         Error_RequiresArgument (arg);
1225                                         return ParseResult.Error;
1226                                 }
1227                                 settings.MainClass = args[++i];
1228                                 return ParseResult.Success;
1229                                 
1230                         case "--unsafe":
1231                                 report.Warning (-29, 1, "Compatibility: Use -unsafe instead of --unsafe");
1232                                 settings.Unsafe = true;
1233                                 return ParseResult.Success;
1234                                 
1235                         case "/?": case "/h": case "/help":
1236                         case "--help":
1237                                 Usage ();
1238                                 return ParseResult.Stop;
1239
1240                         case "--define":
1241                                 report.Warning (-29, 1, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
1242                                 if ((i + 1) >= args.Length){
1243                                         Error_RequiresArgument (arg);
1244                                         return ParseResult.Error;
1245                                 }
1246
1247                                 settings.AddConditionalSymbol (args [++i]);
1248                                 return ParseResult.Success;
1249
1250                         case "--tokenize":
1251                                 settings.TokenizeOnly = true;
1252                                 return ParseResult.Success;
1253                                 
1254                         case "-o": 
1255                         case "--output":
1256                                 report.Warning (-29, 1, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
1257                                 if ((i + 1) >= args.Length){
1258                                         Error_RequiresArgument (arg);
1259                                         return ParseResult.Error;
1260                                 }
1261                                 settings.OutputFile = args[++i];
1262                                 return ParseResult.Success;
1263
1264                         case "--checked":
1265                                 report.Warning (-29, 1, "Compatibility: Use -checked instead of --checked");
1266                                 settings.Checked = true;
1267                                 return ParseResult.Success;
1268                                 
1269                         case "--stacktrace":
1270                                 settings.Stacktrace = true;
1271                                 return ParseResult.Success;
1272                                 
1273                         case "--linkresource":
1274                         case "--linkres":
1275                                 report.Warning (-29, 1, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
1276                                 if ((i + 1) >= args.Length){
1277                                         Error_RequiresArgument (arg);
1278                                         return ParseResult.Error;
1279                                 }
1280
1281                                 AddResource (new AssemblyResource (args[++i], args[i]), settings);
1282                                 return ParseResult.Success;
1283                                 
1284                         case "--resource":
1285                         case "--res":
1286                                 report.Warning (-29, 1, "Compatibility: Use -res:VALUE instead of --res VALUE");
1287                                 if ((i + 1) >= args.Length){
1288                                         Error_RequiresArgument (arg);
1289                                         return ParseResult.Error;
1290                                 }
1291
1292                                 AddResource (new AssemblyResource (args[++i], args[i], true), settings);
1293                                 return ParseResult.Success;
1294                                 
1295                         case "--target":
1296                                 report.Warning (-29, 1, "Compatibility: Use -target:KIND instead of --target KIND");
1297                                 if ((i + 1) >= args.Length){
1298                                         Error_RequiresArgument (arg);
1299                                         return ParseResult.Error;
1300                                 }
1301                                 
1302                                 string type = args [++i];
1303                                 switch (type){
1304                                 case "library":
1305                                         settings.Target = Target.Library;
1306                                         settings.TargetExt = ".dll";
1307                                         break;
1308                                         
1309                                 case "exe":
1310                                         settings.Target = Target.Exe;
1311                                         break;
1312                                         
1313                                 case "winexe":
1314                                         settings.Target = Target.WinExe;
1315                                         break;
1316                                         
1317                                 case "module":
1318                                         settings.Target = Target.Module;
1319                                         settings.TargetExt = ".dll";
1320                                         break;
1321                                 default:
1322                                         report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
1323                                         break;
1324                                 }
1325                                 return ParseResult.Success;
1326                                 
1327                         case "-r":
1328                                 report.Warning (-29, 1, "Compatibility: Use -r:LIBRARY instead of -r library");
1329                                 if ((i + 1) >= args.Length){
1330                                         Error_RequiresArgument (arg);
1331                                         return ParseResult.Error;
1332                                 }
1333                                 
1334                                 string val = args [++i];
1335                                 int idx = val.IndexOf ('=');
1336                                 if (idx > -1) {
1337                                         string alias = val.Substring (0, idx);
1338                                         string assembly = val.Substring (idx + 1);
1339                                         AddAssemblyReference (alias, assembly, settings);
1340                                         return ParseResult.Success;
1341                                 }
1342
1343                                 settings.AssemblyReferences.Add (val);
1344                                 return ParseResult.Success;
1345                                 
1346                         case "-L":
1347                                 report.Warning (-29, 1, "Compatibility: Use -lib:ARG instead of --L arg");
1348                                 if ((i + 1) >= args.Length){
1349                                         Error_RequiresArgument (arg);
1350                                         return ParseResult.Error;
1351                                 }
1352                                 settings.ReferencesLookupPaths.Add (args [++i]);
1353                                 return ParseResult.Success;
1354
1355                         case "--lint":
1356                                 settings.EnhancedWarnings = true;
1357                                 return ParseResult.Success;
1358                                 
1359                         case "--nostdlib":
1360                                 report.Warning (-29, 1, "Compatibility: Use -nostdlib instead of --nostdlib");
1361                                 settings.StdLib = false;
1362                                 return ParseResult.Success;
1363                                 
1364                         case "--nowarn":
1365                                 report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
1366                                 if ((i + 1) >= args.Length){
1367                                         Error_RequiresArgument (arg);
1368                                         return ParseResult.Error;
1369                                 }
1370                                 int warn = 0;
1371                                 
1372                                 try {
1373                                         warn = int.Parse (args [++i]);
1374                                 } catch {
1375                                         Usage ();
1376                                         Environment.Exit (1);
1377                                 }
1378                                 settings.SetIgnoreWarning (warn);
1379                                 return ParseResult.Success;
1380
1381                         case "--wlevel":
1382                                 report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
1383                                 if ((i + 1) >= args.Length){
1384                                         Error_RequiresArgument (arg);
1385                                         return ParseResult.Error;
1386                                 }
1387
1388                                 SetWarningLevel (args [++i], settings);
1389                                 return ParseResult.Success;
1390
1391                         case "--mcs-debug":
1392                                 if ((i + 1) >= args.Length){
1393                                         Error_RequiresArgument (arg);
1394                                         return ParseResult.Error;
1395                                 }
1396
1397                                 try {
1398                                         settings.DebugFlags = int.Parse (args [++i]);
1399                                 } catch {
1400                                         Error_RequiresArgument (arg);
1401                                         return ParseResult.Error;
1402                                 }
1403
1404                                 return ParseResult.Success;
1405                                 
1406                         case "--about":
1407                                 About ();
1408                                 return ParseResult.Stop;
1409                                 
1410                         case "--recurse":
1411                                 report.Warning (-29, 1, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
1412                                 if ((i + 1) >= args.Length){
1413                                         Error_RequiresArgument (arg);
1414                                         return ParseResult.Error;
1415                                 }
1416                                 ProcessSourceFiles (args [++i], true, settings.SourceFiles);
1417                                 return ParseResult.Success;
1418                                 
1419                         case "--timestamp":
1420                                 settings.Timestamps = true;
1421                                 return ParseResult.Success;
1422
1423                         case "--debug": case "-g":
1424                                 report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
1425                                 settings.GenerateDebugInfo = true;
1426                                 return ParseResult.Success;
1427                                 
1428                         case "--noconfig":
1429                                 report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
1430                                 settings.LoadDefaultReferences = false;
1431                                 return ParseResult.Success;
1432
1433                         case "--metadata-only":
1434                                 settings.WriteMetadataOnly = true;
1435                                 return ParseResult.Success;
1436
1437                         case "--break-on-ice":
1438                                 settings.BreakOnInternalError = true;
1439                                 return ParseResult.Success;
1440
1441                         default:
1442                                 if (arg.StartsWith ("--fatal", StringComparison.Ordinal)){
1443                                         int fatal = 1;
1444                                         if (arg.StartsWith ("--fatal=", StringComparison.Ordinal))
1445                                                 int.TryParse (arg.Substring (8), out fatal);
1446
1447                                         settings.FatalCounter = fatal;
1448                                         return ParseResult.Success;
1449                                 }
1450                                 if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
1451                                         string version = arg.Substring (10);
1452
1453                                         switch (version) {
1454                                         case "v1":
1455                                         case "V1":
1456                                                 settings.StdLibRuntimeVersion = RuntimeVersion.v1;
1457                                                 break;
1458                                         case "v2":
1459                                         case "V2":
1460                                                 settings.StdLibRuntimeVersion = RuntimeVersion.v2;
1461                                                 break;
1462                                         case "v4":
1463                                         case "V4":
1464                                                 settings.StdLibRuntimeVersion = RuntimeVersion.v4;
1465                                                 break;
1466                                         }
1467                                         return ParseResult.Success;
1468                                 }
1469
1470                                 return ParseResult.UnknownOption;
1471                         }
1472                 }
1473
1474                 void SetWarningLevel (string s, CompilerSettings settings)
1475                 {
1476                         int level = -1;
1477
1478                         try {
1479                                 level = int.Parse (s);
1480                         } catch {
1481                         }
1482                         if (level < 0 || level > 4) {
1483                                 report.Error (1900, "Warning level must be in the range 0-4");
1484                                 return;
1485                         }
1486                         settings.WarningLevel = level;
1487                 }
1488
1489                 //
1490                 // Given a path specification, splits the path from the file/pattern
1491                 //
1492                 static void SplitPathAndPattern (string spec, out string path, out string pattern)
1493                 {
1494                         int p = spec.LastIndexOf ('/');
1495                         if (p != -1) {
1496                                 //
1497                                 // Windows does not like /file.cs, switch that to:
1498                                 // "\", "file.cs"
1499                                 //
1500                                 if (p == 0) {
1501                                         path = "\\";
1502                                         pattern = spec.Substring (1);
1503                                 } else {
1504                                         path = spec.Substring (0, p);
1505                                         pattern = spec.Substring (p + 1);
1506                                 }
1507                                 return;
1508                         }
1509
1510                         p = spec.LastIndexOf ('\\');
1511                         if (p != -1) {
1512                                 path = spec.Substring (0, p);
1513                                 pattern = spec.Substring (p + 1);
1514                                 return;
1515                         }
1516
1517                         path = ".";
1518                         pattern = spec;
1519                 }
1520
1521                 void Usage ()
1522                 {
1523                         output.WriteLine (
1524                                 "Mono C# compiler, Copyright 2001-2011 Novell, Inc., Copyright 2011-2012 Xamarin, Inc\n" +
1525                                 "mcs [options] source-files\n" +
1526                                 "   --about              About the Mono C# compiler\n" +
1527                                 "   -addmodule:M1[,Mn]   Adds the module to the generated assembly\n" +
1528                                 "   -checked[+|-]        Sets default aritmetic overflow context\n" +
1529                                 "   -clscheck[+|-]       Disables CLS Compliance verifications\n" +
1530                                 "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
1531                                 "   -define:S1[;S2]      Defines one or more conditional symbols (short: -d)\n" +
1532                                 "   -debug[+|-], -g      Generate debugging information\n" +
1533                                 "   -delaysign[+|-]      Only insert the public key into the assembly (no signing)\n" +
1534                                 "   -doc:FILE            Process documentation comments to XML file\n" +
1535                                 "   -fullpaths           Any issued error or warning uses absolute file path\n" +
1536                                 "   -help                Lists all compiler options (short: -?)\n" +
1537                                 "   -keycontainer:NAME   The key pair container used to sign the output assembly\n" +
1538                                 "   -keyfile:FILE        The key file used to strongname the ouput assembly\n" +
1539                                 "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, 3, 4, 5, Default or Future\n" +
1540                                 "   -lib:PATH1[,PATHn]   Specifies the location of referenced assemblies\n" +
1541                                 "   -main:CLASS          Specifies the class with the Main method (short: -m)\n" +
1542                                 "   -noconfig            Disables implicitly referenced assemblies\n" +
1543                                 "   -nostdlib[+|-]       Does not reference mscorlib.dll library\n" +
1544                                 "   -nowarn:W1[,Wn]      Suppress one or more compiler warnings\n" +
1545                                 "   -optimize[+|-]       Enables advanced compiler optimizations (short: -o)\n" +
1546                                 "   -out:FILE            Specifies output assembly name\n" +
1547                                 "   -pkg:P1[,Pn]         References packages P1..Pn\n" +
1548                                 "   -platform:ARCH       Specifies the target platform of the output assembly\n" +
1549                                 "                        ARCH can be one of: anycpu, anycpu32bitpreferred, arm,\n" +
1550                                 "                        x86, x64 or itanium. The default is anycpu.\n" +
1551                                 "   -recurse:SPEC        Recursively compiles files according to SPEC pattern\n" +
1552                                 "   -reference:A1[,An]   Imports metadata from the specified assembly (short: -r)\n" +
1553                                 "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +
1554                                 "   -sdk:VERSION         Specifies SDK version of referenced assemblies\n" +
1555                                 "                        VERSION can be one of: 2, 4, 4.5 (default) or a custom value\n" +
1556                                 "   -target:KIND         Specifies the format of the output assembly (short: -t)\n" +
1557                                 "                        KIND can be one of: exe, winexe, library, module\n" +
1558                                 "   -unsafe[+|-]         Allows to compile code which uses unsafe keyword\n" +
1559                                 "   -warnaserror[+|-]    Treats all warnings as errors\n" +
1560                                 "   -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
1561                                 "   -warn:0-4            Sets warning level, the default is 4 (short -w:)\n" +
1562                                 "   -helpinternal        Shows internal and advanced compiler options\n" +
1563                                 "\n" +
1564                                 "Resources:\n" +
1565                                 "   -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
1566                                 "   -resource:FILE[,ID]     Embed FILE as a resource (short: -res)\n" +
1567                                 "   -win32res:FILE          Specifies Win32 resource file (.res)\n" +
1568                                 "   -win32icon:FILE         Use this icon for the output\n" +
1569                                                                 "   @file                   Read response file for more options\n\n" +
1570                                 "Options can be of the form -option or /option");
1571                 }
1572
1573                 void Version ()
1574                 {
1575                         string version = System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType.Assembly.GetName ().Version.ToString ();
1576                         output.WriteLine ("Mono C# compiler version {0}", version);
1577                 }
1578         }
1579
1580         public class RootContext
1581         {
1582                 //
1583                 // Contains the parsed tree
1584                 //
1585                 static ModuleContainer root;
1586
1587                 static public ModuleContainer ToplevelTypes {
1588                         get { return root; }
1589                         set { root = value; }
1590                 }
1591         }
1592 }