+2002-08-31 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
+ * merged many sources from mcs/mcs, to resync
+
2002-09-03 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
* integrated new version of Mono.GetOptions (reflection/attributes-based)
return null;
e = a.Expr;
+
if (e is Constant) {
pos_values [i] = ((Constant) e).GetValue ();
} else if (e is TypeOf) {
this.Inherited = (bool) o;
}
- } else {
+ } else if (e is TypeOf) {
+ prop_values.Add (((TypeOf) e).TypeArg);
+ } else {
Error_AttributeArgumentNotValid ();
return null;
}
object value = ((Constant) e).GetValue ();
field_values.Add (value);
- } else {
+ } else if (e is TypeOf) {
+ field_values.Add (((TypeOf) e).TypeArg);
+ } else {
Error_AttributeArgumentNotValid ();
return null;
}
Error_AttributeConstructorMismatch (Location);
return null;
}
+
+ //
+ // Now we perform some checks on the positional args as they
+ // cannot be null for a constructor which expects a parameter
+ // of type object
+ //
+
+ ParameterData pd = Invocation.GetParameterData (constructor);
+
+ for (int j = 0; j < pos_arg_count; ++j) {
+ Argument a = (Argument) pos_args [j];
+
+ if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {
+ Error_AttributeArgumentNotValid ();
+ return null;
+ }
+ }
PropertyInfo [] prop_info_arr = new PropertyInfo [prop_infos.Count];
FieldInfo [] field_info_arr = new FieldInfo [field_infos.Count];
(ConstructorInfo) constructor, pos_values,
prop_info_arr, prop_values_arr,
field_info_arr, field_values_arr);
+
} catch (NullReferenceException) {
- Report.Warning (
- -23, Location,
- "The compiler can not encode this attribute in the Mono runtime\n" +
- "\tdue to a known bug in it. We know about the problem and will\n" +
- "\tfix it as soon as possible.");
+ //
+ // Don't know what to do here
+ //
} catch {
//
// Sample:
// (uint, uint)
// (int, int)
//
- static void DoConstantNumericPromotions (Binary.Operator oper,
+ static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
ref Constant left, ref Constant right,
Location loc)
{
}
return;
+ } else if (left is EnumConstant || right is EnumConstant){
+ //
+ // If either operand is an enum constant, the other one must
+ // be implicitly convertable to that enum's underlying type.
+ //
+ EnumConstant match;
+ Constant other;
+ if (left is EnumConstant){
+ other = right;
+ match = (EnumConstant) left;
+ } else {
+ other = left;
+ match = (EnumConstant) right;
+ }
+
+ bool need_check = (other is EnumConstant) ||
+ ((oper != Binary.Operator.Addition) &&
+ (oper != Binary.Operator.Subtraction));
+
+ if (need_check &&
+ !Expression.ImplicitConversionExists (ec, match, other.Type)) {
+ Expression.Error_CannotConvertImplicit (loc, match.Type, other.Type);
+ left = null;
+ right = null;
+ return;
+ }
+
+ if (left is EnumConstant)
+ left = ((EnumConstant) left).Child;
+ if (right is EnumConstant)
+ right = ((EnumConstant) right).Child;
+ return;
+
} else {
//
// Force conversions to int32
switch (oper){
case Binary.Operator.BitwiseOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.BitwiseAnd:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.ExclusiveOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
}
result = null;
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return result;
case Binary.Operator.Subtraction:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Multiply:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Division:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
break;
case Binary.Operator.Modulus:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
}
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
((StringConstant) right).Value);
}
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.LessThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.GreaterThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.GreaterThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
return new BoolConstant (bool_res);
case Binary.Operator.LessThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
if (Delegates != null)
foreach (Delegate d in Delegates)
- d.CloseDelegate ();
+ d.CloseType ();
}
public string MakeName (string n)
//
if (implementing.DeclaringType.IsInterface)
flags |= MethodAttributes.NewSlot;
-
+
flags |=
MethodAttributes.Virtual |
MethodAttributes.HideBySig;
//
using System;
+using System.IO;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
//
// This routine initializes the Mono runtime SymbolWriter.
//
- static bool InitMonoSymbolWriter (string basename, string output_file,
- string[] debug_args)
+ static bool InitMonoSymbolWriter (string basename, string symbol_output,
+ string exe_output_file, string[] debug_args)
{
- string symbol_output = basename + ".dbg";
-
Type itype = SymbolWriter.GetType ();
if (itype == null)
return false;
return false;
object[] args = new object [3];
- args [0] = output_file;
+ args [0] = exe_output_file;
args [1] = symbol_output;
args [2] = debug_args;
//
// Initializes the symbol writer
//
- static void InitializeSymbolWriter (string basename, string output_file,
- string[] args)
+ static void InitializeSymbolWriter (string basename, string symbol_output,
+ string exe_output_file, string[] args)
{
SymbolWriter = ModuleBuilder.GetSymWriter ();
switch (sym_type.Name){
case "MonoSymbolWriter":
- if (!InitMonoSymbolWriter (basename, output_file, args))
+ if (!InitMonoSymbolWriter (basename, symbol_output,
+ exe_output_file, args))
Report.Error (
-18, "Cannot initialize the symbol writer");
break;
ModuleBuilder = AssemblyBuilder.DefineDynamicModule (
Basename (name), Basename (output), want_debugging_support);
- if (want_debugging_support) {
- int pos = output.LastIndexOf (".");
+ int pos = output.LastIndexOf (".");
- string basename;
- if (pos > 0)
- basename = output.Substring (0, pos);
- else
- basename = output;
+ string basename;
+ if (pos > 0)
+ basename = output.Substring (0, pos);
+ else
+ basename = output;
- InitializeSymbolWriter (basename, output, debug_args);
+ string symbol_output = basename + ".dbg";
+
+ if (want_debugging_support)
+ InitializeSymbolWriter (basename, symbol_output, output, debug_args);
+ else {
+ try {
+ File.Delete (symbol_output);
+ } catch {
+ // Ignore errors.
+ }
}
}
if (using_list == null)
continue;
- foreach (string n in using_list){
- t = LookupInterfaceOrClass (n, name, out error);
+ foreach (Namespace.UsingEntry ue in using_list){
+ t = LookupInterfaceOrClass (ue.Name, name, out error);
if (error)
return null;
- if (t != null)
+ if (t != null){
+ ue.Used = true;
return t;
+ }
}
}
}
}
- public void CloseDelegate ()
- {
- TypeBuilder.CreateType ();
- }
-
public Expression InstanceExpression {
get {
return instance_expr;
else
delegate_instance_expr.Emit (ec);
- ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method);
+ if (delegate_method.IsVirtual) {
+ ec.ig.Emit (OpCodes.Dup);
+ ec.ig.Emit (OpCodes.Ldvirtftn, (MethodInfo) delegate_method);
+ } else
+ ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method);
ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method);
}
}
}
[Option("Adds PARAM to the assembly link path", 'L')]
- public static string[] LinkPaths = null;
+ public string[] LinkPaths = null;
[Option("Defines the symbol PARAM", "define")]
- public static string[] Defines = null;
+ public string[] Defines = null;
[Option("Only parses the source file (for debugging the tokenizer)", "parse")]
- public static bool parse_only = false;
+ public bool parse_only = false;
- private static bool load_default_config = true;
[Option("Disables implicit references to assemblies", "noconfig")]
public bool NoConfig { set { load_default_config = !value; } }
[Option("Allows unsafe code", "unsafe")]
public bool AllowUnsafeCode { set { RootContext.Unsafe = value; } }
- private string output_file;
-
[Option("Specifies output file", 'o', "output")]
- public WhatToDoNext SetOutputFile(string FileName)
- {
- output_file = FileName;
- string bname = CodeGen.Basename (output_file);
- if (bname.IndexOf (".") == -1)
- output_file += ".exe";
- return WhatToDoNext.GoAhead;
- }
-
+ public string output_file = null;
[Option("Only tokenizes source files", "tokenize")]
- public static bool tokenize = true;
+ public bool tokenize = false;
[Option("Set default context to checked", "checked")]
public bool Checked { set { RootContext.Checked = value; } }
- [Option("Shows stack trace at error location", "Stacktrace")]
+ [Option("Shows stack trace at Error location", "Stacktrace")]
public bool Stacktrace { set { Report.Stacktrace = value; } }
- private static ArrayList references = new ArrayList();
-
[Option("References an assembly", 'r')]
- public static string reference { set { references.Add(value); } }
+ public string reference { set { references.Add(value); } }
[Option("Adds PARAM as a resource", "resource")]
- public static string[] resources;
+ public string[] resources;
[Option("Set default context to checked", "nostdlib")]
public bool nostdlib { set { RootContext.StdLib = !value; } }
[Option("Write symbolic debugging information to FILE-debug.s", 'g', "debug")]
- public static bool want_debugging_support = false;
+ public bool want_debugging_support = false;
[Option("Debugger arguments", "debug-args")]
public WhatToDoNext SetDebugArgs(string args)
[Option("Sets warning level (the highest is 4, the default)", "wlevel")]
public int wlevel { set { RootContext.WarningLevel = value; } }
- [Option("Sets warning level (the highest is 4, the default)")]
+ [Option("Displays time stamps of various compiler events")]
public bool timestamp
{
set
}
}
- static void Usage (bool is_error)
- {
- Console.WriteLine ( @"
-MonoBASIC Compiler, Copyright (C)2002 Rafael Teixeira.
- --timestamp Displays time stamps of various compiler events
- @file Read response file for more options
-");
- }
-
- //
- // If any of these fail, we ignore the problem. This is so
- // that we can list all the assemblies in Windows and not fail
- // if they are missing on Linux.
- //
- static ArrayList soft_references;
-
- static int error_count = 0;
+ // TODO : response file support
- static string first_source;
-
- static Target target = Target.Exe;
- static string target_ext = ".exe";
-
- static ArrayList debug_arglist = new ArrayList ();
-
- static bool timestamps = false;
-
- static Hashtable source_files = new Hashtable ();
-
- //
- // An array of the defines from the command line
- //
- static ArrayList defines;
+
+ ArrayList defines = new ArrayList();
+ ArrayList references = new ArrayList();
+ ArrayList soft_references = new ArrayList();
+ string first_source = null;
+ Target target = Target.Exe;
+ string target_ext = ".exe";
+ ArrayList debug_arglist = new ArrayList ();
+ bool timestamps = false;
+ Hashtable source_files = new Hashtable ();
+ bool load_default_config = true;
-
//
// Last time we took the time
//
- static DateTime last_time;
- static void ShowTime (string msg)
+ DateTime last_time;
+ void ShowTime (string msg)
{
DateTime now = DateTime.Now;
TimeSpan span = now - last_time;
(int) span.TotalSeconds, span.Milliseconds, msg);
}
- static void error (string msg)
- {
- Console.WriteLine ("Error: " + msg);
- }
-
- static void notice (string msg)
- {
- Console.WriteLine (msg);
- }
-
public static int Main (string[] args)
{
Driver Exec = new Driver();
- if (Exec.MainDriver(args) && Report.Errors == 0)
+ Exec.MainDriver(args);
+
+ if (Report.Errors == 0)
{
Console.Write("Compilation succeeded");
if (Report.Warnings > 0)
}
else
{
- Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
+ Console.WriteLine("Compilation failed: {0} Error(s), {1} warnings",
Report.Errors, Report.Warnings);
return 1;
}
}
- static public int LoadAssembly (string assembly, bool soft)
+ public int LoadAssembly (string assembly, bool soft)
{
Assembly a;
string total_log = "";
try {
- char[] path_chars = { '/', '\\', '.' };
+ char[] path_chars = { '/', '\\' };
if (assembly.IndexOfAny (path_chars) != -1)
- a = Assembly.LoadFrom (assembly);
+ a = Assembly.LoadFrom(assembly);
else
- a = Assembly.Load (assembly);
+ a = Assembly.Load(assembly);
TypeManager.AddAssembly (a);
return 0;
} catch (FileNotFoundException){
if (soft)
return 0;
} catch (BadImageFormatException f) {
- error ("// Bad file format while loading assembly");
- error ("Log: " + f.FusionLog);
+ Error ("// Bad file format while loading assembly");
+ Error ("Log: " + f.FusionLog);
return 1;
} catch (FileLoadException f){
- error ("File Load Exception: " + assembly);
- error ("Log: " + f.FusionLog);
+ Error ("File Load Exception: " + assembly);
+ Error ("Log: " + f.FusionLog);
return 1;
} catch (ArgumentNullException){
- error ("// Argument Null exception ");
+ Error ("// Argument Null exception ");
return 1;
}
return 0;
}
+ void Error(string message)
+ {
+ Console.WriteLine(message);
+ }
+
/// <summary>
/// Loads all assemblies referenced on the command line
/// </summary>
- static public int LoadReferences ()
+ public int LoadReferences ()
{
int errors = 0;
return errors;
}
- static void SetupDefaultDefines ()
+ void SetupDefaultDefines ()
{
defines = new ArrayList ();
defines.Add ("__MonoBASIC__");
//
// Returns the directory where the system assemblies are installed
//
- static string GetSystemDir ()
+ string GetSystemDir ()
{
Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
//
// Given a path specification, splits the path from the file/pattern
//
- static void SplitPathAndPattern (string spec, out string path, out string pattern)
+ void SplitPathAndPattern (string spec, out string path, out string pattern)
{
int p = spec.LastIndexOf ("/");
if (p != -1){
pattern = spec;
}
-
- static int ProcessSourceFile(string filename)
- {
- if (tokenize)
- GenericParser.Tokenize(filename);
- else
- return GenericParser.Parse(filename);
-
- return 0;
- }
-
- static bool AddFiles (string spec, bool recurse)
+ bool AddFiles (string spec, bool recurse)
{
string path, pattern;
- SplitPathAndPattern (spec, out path, out pattern);
- if (pattern.IndexOf ("*") == -1){
- return AddFile (spec);
+ SplitPathAndPattern(spec, out path, out pattern);
+ if (pattern.IndexOf("*") == -1)
+ {
+ AddFile(spec);
+ return true;
}
string [] files = null;
try {
- files = Directory.GetFiles (path, pattern);
+ files = Directory.GetFiles(path, pattern);
} catch (System.IO.DirectoryNotFoundException) {
Report.Error (2001, "Source file `" + spec + "' could not be found");
return false;
string [] dirs = null;
try {
- dirs = Directory.GetDirectories (path);
+ dirs = Directory.GetDirectories(path);
} catch {
}
// directory entry already does
AddFiles (d + "/" + pattern, true);
}
-
return true;
}
- static void DefineDefaultConfig ()
+ void DefineDefaultConfig ()
{
//
// For now the "default config" is harcoded into the compiler
#endif
};
- int p = 0;
foreach (string def in default_config)
- soft_references.Insert (p++, def);
+ soft_references.Add(def);
}
- private static bool AddFile(string fileName)
+ [ArgumentProcessor]
+ public void AddFile(string fileName)
{
string f = fileName;
if (first_source == null)
first_source = f;
if (source_files.Contains(f))
- {
- Report.Error (1516, "Source file `" + f + "' specified multiple times");
- return false;
- }
+ Report.Error(1516, "Source file '" + f + "' specified multiple times");
else
source_files.Add(f, f);
+ }
- return true;
+ void ProcessSourceFile(string filename)
+ {
+ if (tokenize)
+ GenericParser.Tokenize(filename);
+ else
+ GenericParser.Parse(filename);
+ }
+
+ string outputFile_Name = null;
+
+ string outputFileName
+ {
+ get
+ {
+ if (outputFile_Name == null)
+ {
+ if (output_file == null)
+ {
+ int pos = first_source.LastIndexOf(".");
+
+ if (pos > 0)
+ output_file = first_source.Substring(0, pos);
+ else
+ output_file = first_source;
+ }
+ string bname = CodeGen.Basename(output_file);
+ if (bname.IndexOf(".") == -1)
+ output_file += target_ext;
+ outputFile_Name = output_file;
+ }
+ return outputFile_Name;
+ }
}
-
/// <summary>
- /// Parses the arguments, and drives the compilation
- /// process.
+ /// Parses the arguments, and calls the compilation process.
/// </summary>
- ///
- /// <remarks>
- /// TODO: Mostly structured to debug the compiler
- /// now, needs to be turned into a real driver soon.
- /// </remarks>
- bool MainDriver(string [] args)
+ void MainDriver(string [] args)
{
- int errors = 0;//, i;
- string output_file = null;
-
- soft_references = new ArrayList ();
- SetupDefaultDefines ();
-
- this.ProcessArgs(args);
-
- foreach(string arg in this.RemainingArguments)
- AddFile(arg);
+ ProcessArgs(args);
+ CompileAll();
+ }
- foreach(string filename in source_files.Values)
- errors += ProcessSourceFile(filename);
+ public Driver()
+ {
+ SetupDefaultDefines();
+ }
+ bool ParseAll() // Phase 1
+ {
if (first_source == null)
{
- Report.Error (2008, "No files to compile were specified");
+ Report.Error(2008, "No files to compile were specified");
return false;
}
- if (tokenize)
- return true;
-
- if (Report.Errors > 0)
- return false;
-
- if (parse_only)
- return true;
-
- //
+ foreach(string filename in source_files.Values)
+ ProcessSourceFile(filename);
+
+ if (tokenize || parse_only || (Report.Errors > 0))
+ return false;
+
+ return true; // everything went well go ahead
+ }
+
+ void InitializeDebuggingSupport()
+ {
+ string[] debug_args = new string [debug_arglist.Count];
+ debug_arglist.CopyTo(debug_args);
+ CodeGen.Init(outputFileName, outputFileName, want_debugging_support, debug_args);
+ TypeManager.AddModule(CodeGen.ModuleBuilder);
+ }
+
+ public bool ResolveAllTypes() // Phase 2
+ {
// Load Core Library for default compilation
- //
if (RootContext.StdLib)
- references.Insert (0, "mscorlib");
+ references.Insert(0, "mscorlib");
if (load_default_config)
- DefineDefaultConfig ();
+ DefineDefaultConfig();
- if (errors > 0)
- {
- error ("Parsing failed");
- return false;
- }
+ if (timestamps)
+ ShowTime("Loading references");
- //
// Load assemblies required
- //
- if (timestamps)
- ShowTime ("Loading references");
- errors += LoadReferences ();
- if (timestamps)
- ShowTime (" References loaded");
-
- if (errors > 0)
+ if (LoadReferences() > 0)
{
- error ("Could not load one or more assemblies");
+ Error ("Could not load one or more assemblies");
return false;
}
- error_count = errors;
-
- //
- // Quick hack
- //
- if (output_file == null)
- {
- int pos = first_source.LastIndexOf (".");
-
- if (pos > 0)
- output_file = first_source.Substring (0, pos) + target_ext;
- else
- output_file = first_source + target_ext;
- }
-
- string[] debug_args = new string [debug_arglist.Count];
- debug_arglist.CopyTo(debug_args);
- CodeGen.Init (output_file, output_file, want_debugging_support, debug_args);
+ if (timestamps)
+ ShowTime("References loaded");
- TypeManager.AddModule (CodeGen.ModuleBuilder);
+ InitializeDebuggingSupport();
//
// Before emitting, we need to get the core
//
if (timestamps)
ShowTime ("Initializing Core Types");
+
if (!RootContext.StdLib)
- {
RootContext.ResolveCore ();
- if (Report.Errors > 0)
- return false;
- }
+ if (Report.Errors > 0)
+ return false;
- TypeManager.InitCoreTypes ();
+ TypeManager.InitCoreTypes();
+ if (Report.Errors > 0)
+ return false;
+
if (timestamps)
ShowTime (" Core Types done");
-
- //
- // The second pass of the compiler
- //
+
if (timestamps)
ShowTime ("Resolving tree");
+
+ // The second pass of the compiler
RootContext.ResolveTree ();
+ if (Report.Errors > 0)
+ return false;
+
if (timestamps)
ShowTime ("Populate tree");
+ if (!RootContext.StdLib)
+ RootContext.BootCorlib_PopulateCoreTypes();
if (Report.Errors > 0)
- {
- error ("Compilation failed");
return false;
- }
- if (!RootContext.StdLib)
- RootContext.BootCorlib_PopulateCoreTypes ();
- RootContext.PopulateTypes ();
-
- TypeManager.InitCodeHelpers ();
-
+ RootContext.PopulateTypes();
if (Report.Errors > 0)
- {
- error ("Compilation failed");
return false;
- }
+ TypeManager.InitCodeHelpers();
+ if (Report.Errors > 0)
+ return false;
+
+ return true;
+ }
+
+ bool GenerateAssembly()
+ {
//
// The code generator
//
if (timestamps)
ShowTime ("Emitting code");
- RootContext.EmitCode ();
- if (timestamps)
- ShowTime (" done");
+ RootContext.EmitCode();
if (Report.Errors > 0)
- {
- error ("Compilation failed");
return false;
- }
+
+ if (timestamps)
+ ShowTime (" done");
+
if (timestamps)
ShowTime ("Closing types");
-
+
RootContext.CloseTypes ();
+ if (Report.Errors > 0)
+ return false;
- // 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 = RootContext.EntryPoint;
- //
- // if (ep == null){
- // Report.Error (5001, "Program " + output_file +
- // " does not have an entry point defined");
- // return;
- // }
- //
- // CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
- // }
+ if (timestamps)
+ ShowTime (" done");
+
+ 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 = RootContext.EntryPoint;
+
+ if (ep == null)
+ {
+ Report.Error (5001, "Program " + outputFileName +
+ " does not have an entry point defined");
+ return false;
+ }
+
+ CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+ }
- //
// Add the resources
- //
if (resources != null)
- {
foreach (string file in resources)
CodeGen.AssemblyBuilder.AddResourceFile (file, file);
- }
- CodeGen.Save (output_file);
+ CodeGen.Save(outputFileName);
+
if (timestamps)
ShowTime ("Saved output");
+
if (want_debugging_support)
{
CodeGen.SaveSymbols ();
ShowTime ("Saved symbols");
}
+ return true;
+ }
+
+ public void CompileAll()
+ {
+ if (!ParseAll()) // Phase 1
+ return;
+
+ if (!ResolveAllTypes()) // Phase 2
+ return;
+
+ if (!GenerateAssembly()) // Phase 3
+ return;
+
if (Report.ExpectedError != 0)
- {
- Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
- Environment.Exit (1);
- return false;
- }
- return (Report.Errors == 0);
+ Error("Failed to report expected Error " + Report.ExpectedError);
}
}
get;
}
+ /// <summary>
+ /// The type which declares this member.
+ /// </summary>
+ Type DeclaringType {
+ get;
+ }
+
/// <summary>
/// The instance expression associated with this member, if it's a
/// non-static member.
return new ULongConstant ((ulong) v);
}
- //
- // If we have an enumeration, extract the underlying type,
- // use this during the comparission, but wrap around the original
- // target_type
- //
- Type real_target_type = target_type;
-
- if (TypeManager.IsEnumType (real_target_type))
- real_target_type = TypeManager.EnumToUnderlying (real_target_type);
+ Type real_target_type = target_type;
- if (expr_type == real_target_type)
- return new EmptyCast (expr, target_type);
-
if (expr_type == TypeManager.sbyte_type){
//
// From sbyte to short, int, long, float, double.
return false;
}
-
+
/// <summary>
/// Determines if a standard implicit conversion exists from
/// expr_type to target_type
//
// If we have an enumeration, extract the underlying type,
- // use this during the comparission, but wrap around the original
+ // use this during the comparison, but wrap around the original
// target_type
//
Type real_target_type = target_type;
if (TypeManager.IsEnumType (real_target_type))
real_target_type = TypeManager.EnumToUnderlying (real_target_type);
+ if (StandardConversionExists (expr, real_target_type))
+ return new EmptyCast (expr, target_type);
+
if (expr_type == TypeManager.sbyte_type){
//
// From sbyte to byte, ushort, uint, ulong, char
if (!me.IsStatic && (me.InstanceExpression == null))
return e;
+ if (!me.IsStatic &&
+ TypeManager.IsNestedChildOf (me.InstanceExpression.Type, me.DeclaringType)) {
+ Error (38, "Cannot access nonstatic member `" + me.Name + "' of " +
+ "outer type `" + me.DeclaringType + "' via nested type `" +
+ me.InstanceExpression.Type + "'");
+ return null;
+ }
+
if (right_side != null)
e = e.DoResolveLValue (ec, right_side);
else
eclass = ExprClass.MethodGroup;
type = TypeManager.object_type;
}
+
+ public Type DeclaringType {
+ get {
+ return Methods [0].DeclaringType;
+ }
+ }
//
// `A method group may have associated an instance expression'
}
}
+ public Type DeclaringType {
+ get {
+ return FieldInfo.DeclaringType;
+ }
+ }
+
public Expression InstanceExpression {
get {
return instance_expr;
}
}
+ public Type DeclaringType {
+ get {
+ return PropertyInfo.DeclaringType;
+ }
+ }
+
//
// The instance expression associated with this expression
//
return null;
}
+ if ((instance_expr == null) && ec.IsStatic && !is_static) {
+ SimpleName.Error_ObjectRefRequired (ec, loc, PropertyInfo.Name);
+ return null;
+ }
+
return this;
}
//
// Special case: length of single dimension array is turned into ldlen
//
- if (method == TypeManager.int_array_get_length){
+ if ((method == TypeManager.system_int_array_get_length) ||
+ (method == TypeManager.int_array_get_length)){
Type iet = instance_expr.Type;
//
}
}
+ public Type DeclaringType {
+ get {
+ return EventInfo.DeclaringType;
+ }
+ }
+
public Expression InstanceExpression {
get {
return instance_expr;
return;
}
+ /// <summary>
+ /// Determines if a standard implicit conversion exists from
+ /// expr_type to target_type
+ /// </summary>
+ public static bool ImplicitConversionExists (Type expr_type, Type target_type)
+ {
+ expr_type = TypeManager.TypeToCoreType (expr_type);
+
+ if (expr_type == TypeManager.void_type)
+ return false;
+
+ if (expr_type == target_type)
+ return true;
+
+ // First numeric conversions
+
+ if (expr_type == TypeManager.sbyte_type){
+ //
+ // From sbyte to short, int, long, float, double.
+ //
+ if ((target_type == TypeManager.int32_type) ||
+ (target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.short_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.byte_type){
+ //
+ // From byte to short, ushort, int, uint, long, ulong, float, double
+ //
+ if ((target_type == TypeManager.short_type) ||
+ (target_type == TypeManager.ushort_type) ||
+ (target_type == TypeManager.int32_type) ||
+ (target_type == TypeManager.uint32_type) ||
+ (target_type == TypeManager.uint64_type) ||
+ (target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.short_type){
+ //
+ // From short to int, long, float, double
+ //
+ if ((target_type == TypeManager.int32_type) ||
+ (target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.ushort_type){
+ //
+ // From ushort to int, uint, long, ulong, float, double
+ //
+ if ((target_type == TypeManager.uint32_type) ||
+ (target_type == TypeManager.uint64_type) ||
+ (target_type == TypeManager.int32_type) ||
+ (target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.int32_type){
+ //
+ // From int to long, float, double
+ //
+ if ((target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.uint32_type){
+ //
+ // From uint to long, ulong, float, double
+ //
+ if ((target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.uint64_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if ((expr_type == TypeManager.uint64_type) ||
+ (expr_type == TypeManager.int64_type)) {
+ //
+ // From long/ulong to float, double
+ //
+ if ((target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.char_type){
+ //
+ // From char to ushort, int, uint, long, ulong, float, double
+ //
+ if ((target_type == TypeManager.ushort_type) ||
+ (target_type == TypeManager.int32_type) ||
+ (target_type == TypeManager.uint32_type) ||
+ (target_type == TypeManager.uint64_type) ||
+ (target_type == TypeManager.int64_type) ||
+ (target_type == TypeManager.float_type) ||
+ (target_type == TypeManager.double_type) ||
+ (target_type == TypeManager.decimal_type))
+ return true;
+
+ } else if (expr_type == TypeManager.float_type){
+ //
+ // float to double
+ //
+ if (target_type == TypeManager.double_type)
+ return true;
+ }
+
+ return false;
+ }
+
/// <summary>
/// This is used to lookup the value of an enum member. If the member is undefined,
/// it attempts to define it and return its value
val = val.Resolve (ec);
in_transit.Remove (name);
ec.InEnumContext = old;
-
+
if (val == null)
return null;
- if (IsValidEnumConstant (val)) {
- c = (Constant) val;
- default_value = c.GetValue ();
-
- if (default_value == null) {
- Error_ConstantValueCannotBeConverted (c, loc);
- return null;
- }
-
- } else {
+ if (!IsValidEnumConstant (val)) {
Report.Error (
1008, loc,
"Type byte, sbyte, short, ushort, int, uint, long, or " +
"ulong expected (have: " + val + ")");
return null;
}
+
+ c = (Constant) val;
+ default_value = c.GetValue ();
+
+ if (default_value == null) {
+ Error_ConstantValueCannotBeConverted (c, loc);
+ return null;
+ }
+
+ if ((val is EnumConstant) &&
+ !ImplicitConversionExists (default_value.GetType (), UnderlyingType)) {
+ Expression.Error_CannotConvertImplicit (
+ loc, default_value.GetType (), UnderlyingType);
+ return null;
+ }
}
FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
int errors = Report.Errors;
- target_type = target_type.Resolve (ec, ResolveFlags.Type);
+ type = ec.DeclSpace.ResolveType (target_type, false, Location);
- if (target_type == null){
- if (errors == Report.Errors)
- Error (-10, "Can not resolve type");
+ if (type == null)
return null;
- }
- type = target_type.Type;
eclass = ExprClass.Value;
- if (type == null)
- return null;
-
if (expr is Constant){
Expression e = TryReduce (ec, type);
if (argument_type == null)
throw new Exception ("Expression of type " + a.Expr + " does not resolve its type");
+ //
+ // This is a special case since csc behaves this way. I can't find
+ // it anywhere in the spec but oh well ...
+ //
+ if (argument_expr is NullLiteral && p == TypeManager.string_type && q == TypeManager.object_type)
+ return 1;
+ else if (argument_expr is NullLiteral && p == TypeManager.object_type && q == TypeManager.string_type)
+ return 0;
+
if (p == q)
return 0;
}
}
- if (method == null)
+ if (method == null) {
+ //
+ // Okay so we have failed to find anything so we
+ // return by providing info about the closest match
+ //
+ for (int i = 0; i < me.Methods.Length; ++i) {
+
+ MethodBase c = (MethodBase) me.Methods [i];
+ ParameterData pd = GetParameterData (c);
+
+ if (pd.Count != argument_count)
+ continue;
+
+ VerifyArgumentsCompat (ec, Arguments, argument_count, c, false,
+ null, loc);
+ }
+
return null;
+ }
//
// Now check that there are no ambiguities i.e the selected method
byte [] element;
int count = array_data.Count;
+ if (underlying_type.IsEnum)
+ underlying_type = TypeManager.EnumToUnderlying (underlying_type);
+
factor = GetTypeSize (underlying_type);
if (factor == 0)
- return null;
+ throw new Exception ("Unrecognized type in MakeByteBlob");
data = new byte [(count * factor + 4) & ~3];
int idx = 0;
ILGenerator ig = ec.ig;
byte [] data = MakeByteBlob (array_data, underlying_type, loc);
-
- if (data != null) {
- fb = RootContext.MakeStaticData (data);
- if (is_expression)
- ig.Emit (OpCodes.Dup);
- ig.Emit (OpCodes.Ldtoken, fb);
- ig.Emit (OpCodes.Call,
- TypeManager.void_initializearray_array_fieldhandle);
- }
+ fb = RootContext.MakeStaticData (data);
+
+ if (is_expression)
+ ig.Emit (OpCodes.Dup);
+ ig.Emit (OpCodes.Ldtoken, fb);
+ ig.Emit (OpCodes.Call,
+ TypeManager.void_initializearray_array_fieldhandle);
}
//
public override Expression DoResolve (EmitContext ec)
{
+ if (!ec.InUnsafe) {
+ Error (233, "Sizeof may only be used in an unsafe context " +
+ "(consider using System.Runtime.InteropServices.Marshal.Sizeof");
+ return null;
+ }
+
type_queried = ec.DeclSpace.ResolveType (QueriedType, false, loc);
if (type_queried == null)
return null;
if (Expr == null)
return null;
+ if (Expr is Constant)
+ return Expr;
+
eclass = Expr.eclass;
type = Expr.Type;
return this;
if (Expr == null)
return null;
+ if (Expr is Constant)
+ return Expr;
+
eclass = Expr.eclass;
type = Expr.Type;
return this;
IMemberContainer parent_container;
MemberCache member_cache;
+ bool members_defined;
+
// These will happen after the semantic analysis
// Hashtable defined_indexers;
return true;
}
- public MethodInfo [] GetMethods ()
+ //
+ // This might trigger a definition of the methods. This happens only
+ // with Attributes, as Attribute classes are processed before interfaces.
+ // Ideally, we should make everything just define recursively in terms
+ // of its dependencies.
+ //
+ public MethodInfo [] GetMethods (TypeContainer container)
{
- int n = method_builders.Count;
+ int n = 0;
+
+ if (!members_defined){
+ if (DefineMembers (container))
+ n = method_builders.Count;
+ } else
+ n = method_builders.Count;
+
MethodInfo [] mi = new MethodInfo [n];
method_builders.CopyTo (mi, 0);
if (return_type.IsPointer && !UnsafeOK (this))
return;
+ if (arg_types == null)
+ return;
+
foreach (Type t in arg_types){
if (t == null)
member_cache = new MemberCache (this);
#endif
-
+ members_defined = true;
return true;
}
//
using System;
+using System.IO;
using System.Collections;
using System.Diagnostics.SymbolStore;
if (sw == null)
return null;
- if (sym_docs.Contains (Name))
+ string path = Path.GetFullPath (Name);
+
+ if (sym_docs.Contains (path))
// If we already created an ISymbolDocumentWriter
// instance for this document, return it.
- doc = (ISymbolDocumentWriter) sym_docs [Name];
+ doc = (ISymbolDocumentWriter) sym_docs [path];
else {
// Create a new ISymbolDocumentWriter instance and
// store it in the hash table.
- doc = sw.DefineDocument (Name, SymLanguageType.CSharp,
+ doc = sw.DefineDocument (path, SymLanguageType.CSharp,
SymLanguageVendor.Microsoft,
SymDocumentType.Text);
- sym_docs.Add (Name, doc);
+ sym_docs.Add (path, doc);
}
return doc;
/// Keeps track of the namespaces defined in the C# code.
/// </summary>
public class Namespace {
+ static ArrayList all_namespaces = new ArrayList ();
+
Namespace parent;
string name;
ArrayList using_clauses;
Hashtable aliases;
public bool DeclarationFound = false;
+
+ //
+ // This class holds the location where a using definition is
+ // done, and whether it has been used by the program or not.
+ //
+ // We use this to flag using clauses for namespaces that do not
+ // exist.
+ //
+ public class UsingEntry {
+ public string Name;
+ public bool Used;
+ public Location Location;
+
+ public UsingEntry (string name, Location loc)
+ {
+ Name = name;
+ Location = loc;
+ Used = false;
+ }
+ }
/// <summary>
/// Constructor Takes the current namespace and the
{
this.name = name;
this.parent = parent;
+
+ all_namespaces.Add (this);
}
/// <summary>
if (using_clauses == null)
using_clauses = new ArrayList ();
- using_clauses.Add (ns);
+ UsingEntry ue = new UsingEntry (ns, loc);
+ using_clauses.Add (ue);
}
public ArrayList UsingTable {
/// <summary>
/// Used to validate that all the using clauses are correct
- /// after we are finished parsing all the files
+ /// after we are finished parsing all the files.
/// </summary>
- public void VerifyUsing ()
+ public static bool VerifyUsing ()
{
- foreach (DictionaryEntry de in using_clauses){
- if (de.Value == null){
- string name = (string) de.Key;
-
- Report.Error (234, "The type or namespace `" +
- name + "' does not exist in the " +
- "class or namespace `" + name + "'");
+ ArrayList unused = new ArrayList ();
+ int errors = 0;
+
+ foreach (Namespace ns in all_namespaces){
+ ArrayList uses = ns.UsingTable;
+ if (uses == null)
+ continue;
+
+ foreach (UsingEntry ue in uses){
+ if (ue.Used)
+ continue;
+ unused.Add (ue);
}
}
+
+ //
+ // If we have unused using aliases, load all namespaces and check
+ // whether it is unused, or it was missing
+ //
+ if (unused.Count > 0){
+ Hashtable namespaces = TypeManager.GetNamespaces ();
+
+ foreach (UsingEntry ue in unused){
+ if (namespaces.Contains (ue.Name)){
+ Report.Warning (6024, ue.Location, "Unused namespace in `using' declaration");
+ continue;
+ }
+
+ errors++;
+ Report.Error (246, ue.Location, "The namespace `" + ue.Name +
+ "' can not be found (missing assembly reference?)");
+ }
+ }
+
+ return errors == 0;
}
}
}
-
//
}
- static void error100 (string name)
+ static void Error_DuplicateParameterName (string name)
{
Report.Error (
100, "The parameter name `" + name + "' is a duplicate");
for (j = i + 1; j < count; j++){
if (base_name != FixedParameters [j].Name)
continue;
- error100 (base_name);
+ Error_DuplicateParameterName (base_name);
return false;
}
if (base_name == array_par_name){
- error100 (base_name);
+ Error_DuplicateParameterName (base_name);
return false;
}
}
}
}
- if (failed)
- types = null;
-
if (extra > 0){
if (ArrayParameter.Resolve (ds, loc))
types [i] = ArrayParameter.ExternalType (ds, loc);
- else
- return false;
+ else
+ failed = true;
+ }
+
+ if (failed){
+ types = null;
+ return false;
}
return true;
iface = TypeManager.LookupInterface (t);
- mi = iface.GetMethods ();
+ mi = iface.GetMethods (container);
} else
mi = t.GetMethods ();
if (root.Delegates != null)
foreach (Delegate d in root.Delegates)
- d.CloseDelegate ();
+ d.CloseType ();
//
if (using_list == null)
continue;
- foreach (string n in using_list) {
- t = TypeManager.LookupType (MakeFQN (n, name));
- if (t != null)
+ foreach (Namespace.UsingEntry ue in using_list) {
+ t = TypeManager.LookupType (MakeFQN (ue.Name, name));
+ if (t != null){
+ ue.Used = true;
return t;
+ }
}
//
ec.LoopBeginTryCatchLevel = old_loop_begin_try_catch_level;
//
- // Inform whether we are infinite or not
+ // Inform whether we are infinite or not
//
if (Test != null){
if (Test is BoolConstant){
}
return false;
} else
- return true;
+ return breaks == false;
}
}
if (e is StringConstant || e is NullLiteral){
if (required_type == TypeManager.string_type){
- converted = label;
+ converted = e;
ILLabel = ec.ig.DefineLabel ();
return true;
}
public readonly Block Block;
public readonly Location Location;
- Expression type;
+ Expression type_expr;
+ Type type;
public Catch (Expression type, string name, Block block, Location l)
{
- this.type = type;
+ type_expr = type;
Name = name;
Block = block;
Location = l;
public Type CatchType {
get {
- if (type == null)
- throw new InvalidOperationException ();
-
- return type.Type;
+ return type;
}
}
public bool IsGeneral {
get {
- return type == null;
+ return type_expr == null;
}
}
public bool Resolve (EmitContext ec)
{
- if (type != null) {
- type = type.DoResolve (ec);
+ if (type_expr != null) {
+ type = ec.DeclSpace.ResolveType (type_expr, false, Location);
if (type == null)
return false;
- Type t = type.Type;
- if (t != TypeManager.exception_type && !t.IsSubclassOf (TypeManager.exception_type)){
+ if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_type)){
Report.Error (155, Location,
"The type caught or thrown must be derived " +
"from System.Exception");
return false;
}
- }
+ } else
+ type = null;
if (!Block.Resolve (ec))
return false;
return null;
}
+ //
+ // Returns a list of all namespaces in the assemblies and types loaded.
+ //
+ public static Hashtable GetNamespaces ()
+ {
+ Hashtable namespaces = new Hashtable ();
+
+ foreach (Assembly a in assemblies){
+ foreach (Type t in a.GetTypes ()){
+ string ns = t.Namespace;
+
+ if (namespaces.Contains (ns))
+ continue;
+ namespaces [ns] = ns;
+ }
+ }
+
+ foreach (ModuleBuilder mb in modules){
+ foreach (Type t in mb.GetTypes ()){
+ string ns = t.Namespace;
+
+ if (namespaces.Contains (ns))
+ continue;
+ namespaces [ns] = ns;
+ }
+ }
+ return namespaces;
+ }
+
/// <summary>
/// Returns the C# name of a type if possible, or the full type name otherwise
/// </summary>
return false;
}
+ //
+ // Checks whether `type' is a nested child of `parent'.
+ //
+ public static bool IsNestedChildOf (Type type, Type parent)
+ {
+ return IsSubclassOrNestedChildOf (type, parent) && !type.IsSubclassOf (parent);
+ }
+
/// <summary>
/// Returns the User Defined Types
/// </summary>