X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdriver.cs;h=56ab9f3a7e78893cddf7e32c43d3c68631745c76;hb=985fca6fd28bd88ca224ddefcf76a819e1359b41;hp=c796d8b552e63cfeead0a352c9894d04fae1d4be;hpb=16f05aed1dba34dc06e0c9383ae018acfa369b99;p=mono.git diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs index c796d8b552e..56ab9f3a7e7 100755 --- a/mcs/mcs/driver.cs +++ b/mcs/mcs/driver.cs @@ -8,7 +8,7 @@ // (C) 2001 Ximian, Inc (http://www.ximian.com) // -namespace CSC +namespace CIR { using System; using System.Reflection; @@ -17,13 +17,17 @@ namespace CSC using System.IO; using CIR; using Generator; - using CSC; /// - /// Summary description for Class1. + /// The compiler driver. /// public class Driver { + + enum Target { + Library, Exe, Module, WinExe + }; + // // Assemblies references to be linked. Initialized with // mscorlib.dll here. @@ -32,14 +36,17 @@ namespace CSC // Lookup paths ArrayList link_paths; - // Our parser context. - Tree context; - + RootContext context; + bool yacc_verbose = false; int error_count = 0; - public int parse (Tree context, string input_file) + string first_source; + + Target target = Target.Exe; + + public int parse (string input_file) { CSharpParser parser; System.IO.Stream input; @@ -67,20 +74,24 @@ namespace CSC public void Usage () { Console.WriteLine ( - "compiler [-v] [-t tree] [-o output] [-L path] [-r reference] sources.cs\n" + - "-v Verbose parsing\n"+ - "-o Specifies output file\n" + - "-L Specifies path for loading assemblies\n" + - "-r References an assembly\n"); + "compiler [options] source-files\n\n" + + "-v Verbose parsing\n"+ + "-o Specifies output file\n" + + "-L Specifies path for loading assemblies\n" + + "--nostdlib Does not load core libraries\n" + + "--target Specifies the target (exe, winexe, library, module)\n" + + "--dumper Specifies a tree dumper\n" + + "-r References an assembly\n"); } - public IGenerator lookup_output (string name) + public ITreeDump lookup_dumper (string name) { if (name == "tree") return new Generator.TreeDump (); - if (name == "il") - return new MSIL.Generator (); + + // if (name == "il") + // return new MSIL.Generator (); return null; } @@ -110,6 +121,7 @@ namespace CSC string full_path = dir + "/" + assembly; try { + Console.WriteLine ("Loading: " + assembly); a = Assembly.Load (assembly); } catch (FileNotFoundException f) { error ("// File not found: " + full_path); @@ -127,11 +139,14 @@ namespace CSC return 1; } - context.AddAssembly (a); + context.TypeManager.AddAssembly (a); } return 0; } - + + // + // Loads all assemblies referenced on the command line + // public int LoadReferences () { int errors = 0; @@ -143,21 +158,26 @@ namespace CSC return errors; } - + // + // Parses the arguments, and drives the compilation + // process. + // + // TODO: Mostly structured to debug the compiler + // now, needs to be turned into a real driver soon. + // public Driver (string [] args) { - Stream output_stream = Console.OpenStandardOutput (); - IGenerator generator = null; + ITreeDump generator = null; int errors = 0, i; + string output_file = null; - context = new Tree (); + context = new RootContext (); references = new ArrayList (); link_paths = new ArrayList (); // // Setup defaults // - references.Add ("mscorlib"); link_paths.Add ("file:///C:/WINNT/Microsoft.NET/Framework/v1.0.2914"); for (i = 0; i < args.Length; i++){ @@ -169,8 +189,8 @@ namespace CSC continue; } - if (arg.StartsWith ("-t")){ - generator = lookup_output (args [++i]); + if (arg.StartsWith ("--dumper")){ + generator = lookup_dumper (args [++i]); continue; } @@ -181,7 +201,7 @@ namespace CSC if (arg.StartsWith ("-o")){ try { - output_stream = File.Create (args [++i]); + output_file = args [++i]; } catch (Exception){ error ("Could not write to `"+args [i]); error_count++; @@ -190,6 +210,28 @@ namespace CSC continue; } + if (arg.StartsWith ("--target")){ + string type = args [++i]; + + switch (type){ + case "library": + target = Target.Library; + break; + + case "exe": + target = Target.Exe; + break; + + case "winexe": + target = Target.WinExe; + break; + + case "module": + target = Target.Module; + break; + } + } + if (arg.StartsWith ("-r")){ references.Add (args [++i]); continue; @@ -200,62 +242,152 @@ namespace CSC continue; } + if (arg == "--nostdlib"){ + context.StdLib = false; + } + Usage (); error_count++; return; } if (!arg.EndsWith (".cs")){ + error ("Do not know how to compile " + arg); errors++; continue; } - errors += parse (context, arg); + if (first_source == null) + first_source = arg; + + errors += parse (arg); + } + + if (first_source == null){ + context.Report.Error (2008, "No files to compile were specified"); + return; } - if (errors > 0) - error ("// Parsing failed"); - else - notice ("// Parsing successful"); + + // + // Load Core Library for default compilation + // + if (context.StdLib) + references.Insert (0, "mscorlib"); + + if (errors > 0){ + error ("Parsing failed"); + return; + } else + notice ("Parsing successful"); // // Load assemblies required // errors += LoadReferences (); - if (errors > 0) - error ("// Could not load one or more assemblies"); - else - notice ("// Assemblies loaded"); - + if (errors > 0){ + error ("Could not load one or more assemblies"); + return; + } - errors += context.BuilderInit ("Module", "Module.exe"); // - // Name resolution on the tree. - // - errors += context.Resolve (); - + // Dumping the parsed tree. // - // Code generation from the tree + // This code generation interface is only here + // for debugging the parser. // if (generator != null){ + if (output_file == null){ + error ("Error: no output file specified"); + return; + } + + Stream output_stream = File.Create (output_file); StreamWriter output = new StreamWriter (output_stream); - errors += generator.GenerateFromTree (context, output); + errors += generator.Dump (context.Tree, output); - if (errors > 0) - error ("// Compilation failed"); - else - notice ("// Compilation successful"); + if (errors > 0){ + error ("Compilation failed"); + return; + } else + notice ("Compilation successful"); output.Flush (); output.Close (); - } + } + error_count = errors; + + // + // Quick hack + // + if (output_file == null){ + int pos = first_source.LastIndexOf ("."); + + output_file = first_source.Substring (0, pos) + ".exe"; + } + + context.CodeGen = new CodeGen (output_file, output_file); + + // + // The second pass of the compiler + // + context.ResolveTree (); + context.PopulateTypes (); + + // + // Before emitting, we need to get the core + // types emitted from the user defined types + // or from the system ones. + // + context.TypeManager.InitCoreTypes (); + + // + // The code generator + // + context.EmitCode (); + + if (context.Report.Errors > 0){ + error ("Compilation failed"); + return; + } + + context.CloseTypes (); + + PEFileKinds k = PEFileKinds.ConsoleApplication; + + if (target == Target.Library || target == Target.Module) + k = PEFileKinds.Dll; + else if (target == Target.Exe) + k = PEFileKinds.ConsoleApplication; + else if (target == Target.WinExe) + k = PEFileKinds.WindowApplication; + + if (target == Target.Exe || target == Target.WinExe){ + MethodInfo ep = context.EntryPoint; + + if (ep == null){ + context.Report.Error (5001, "Program " + output_file + + " does not have an entry point defined"); + return; + } + + context.CodeGen.AssemblyBuilder.SetEntryPoint (ep, k); + } + + context.CodeGen.Save (context.Report, output_file); + + if (context.Report.Errors > 0){ + error ("Compilation failed"); + return; + } + + notice ("Success"); } } } -