+2002-07-06 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
+ * merged attribute.cs, class.cs, codegen.cs, ecore.cs, expression.cs,
+ modifiers.cs, namespace.cs, report.cs, rootcontext.cs, statement.cs and typemanager.cs from mcs/mcs, to resync
+ * changed driver.cs to follow mcs lead on error/warning counting and reporting
+
2002-06-23 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
* merged attribute.cs, class.cs, ecore.cs, rootcontext.cs, support.cs and typemanager.cs from mcs/mcs, to resync
* makefile makes csc reference a copy of Mono.GetOptions.dll (mbas.sln now compiles to mbas dir instead of mbas/bin/Debug)
return;
}
- if (kind is Method || kind is Operator || kind is InterfaceMethod) {
+ if (kind is Method || kind is Operator || kind is InterfaceMethod ||
+ kind is Accessor) {
if (a.Type == TypeManager.methodimpl_attr_type) {
if (a.ImplOptions == MethodImplOptions.InternalCall)
((MethodBuilder) builder).
((ModuleBuilder) builder).SetCustomAttribute (cb);
} else if (kind is FieldBuilder) {
((FieldBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is Accessor) {
- ((MethodBuilder) builder).SetCustomAttribute (cb);
} else
throw new Exception ("Unknown kind: " + kind);
}
}
}
+ // add interfaces that were not added at type creation (weird API issue)
+ if (!is_class && !have_nonstatic_fields && (ifaces != null)) {
+ foreach (Type i in ifaces)
+ TypeBuilder.AddInterfaceImplementation (i);
+ }
+
//
// Finish the setup for the EmitContext
//
TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
- if (parent == TypeManager.attribute_type ||
- parent.IsSubclassOf (TypeManager.attribute_type)) {
+ if ((parent != null) &&
+ (parent == TypeManager.attribute_type ||
+ parent.IsSubclassOf (TypeManager.attribute_type))) {
RootContext.RegisterAttribute (this);
TypeManager.RegisterAttrType (TypeBuilder, this);
} else
foreach (Enum en in Enums)
if (filter (en.TypeBuilder, criteria) == true)
members.Add (en.TypeBuilder);
-
}
if ((mt & MemberTypes.Constructor) != 0){
public bool MethodModifiersValid (int flags, string n, Location loc)
{
const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
+ const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
bool ok = true;
string name = MakeName (n);
}
}
+ if (this is Struct){
+ if ((flags & va) != 0){
+ Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
+ ok = false;
+ }
+ }
+
if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
Report.Error (
113, loc, name +
if ((ModFlags & Modifiers.STATIC) != 0)
implementing = null;
} else {
- if ((ModFlags & (Modifiers.PUBLIC | Modifiers.ABSTRACT)) != 0){
- Report.Error (
- 106, Location, "`public' or `abstract' modifiers "+
- "are not allowed in explicit interface declarations"
- );
+ if ((ModFlags & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
+ Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
implementing = null;
}
}
public void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldarg_0);
+ if (parent_constructor != null)
+ ec.ig.Emit (OpCodes.Ldarg_0);
if (argument_list != null)
Invocation.EmitArguments (ec, null, argument_list);
if (parent_constructor != null)
if ((ModFlags & Modifiers.STATIC) != 0)
implementing = null;
} else {
- if ((ModFlags & (Modifiers.PUBLIC | Modifiers.ABSTRACT)) != 0){
- Report.Error (
- 106, Location, "`public' or `abstract' modifiers "+
- "are not allowed in explicit interface declarations"
- );
+ if ((ModFlags & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
+ Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
implementing = null;
}
}
//
if (PropertyBuilder != null)
Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
-
+ if (Get != null)
+ Attribute.ApplyAttributes (ec, GetBuilder, Get, Get.OptAttributes, Location);
+ if (Set != null)
+ Attribute.ApplyAttributes (ec, SetBuilder, Set, Set.OptAttributes, Location);
//
// abstract or extern properties have no bodies
ig = GetBuilder.GetILGenerator ();
ec = new EmitContext (tc, Location, ig, PropertyType, ModFlags);
- Attribute.ApplyAttributes (ec, GetBuilder, Get, Get.OptAttributes, Location);
ec.EmitTopBlock (Get.Block, Location);
}
ig = SetBuilder.GetILGenerator ();
ec = new EmitContext (tc, Location, ig, null, ModFlags);
- Attribute.ApplyAttributes (ec, SetBuilder, Set, Set.OptAttributes, Location);
ec.EmitTopBlock (Set.Block, Location);
}
}
if ((ModFlags & Modifiers.STATIC) != 0)
implementing = null;
} else {
- if((ModFlags&(Modifiers.PUBLIC | Modifiers.ABSTRACT)) != 0){
- Report.Error (
- 106, Location,
- "`public' or `abstract' modifiers are not "+
- "allowed in explicit interface declarations"
- );
+ if((ModFlags&(Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
+ Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
implementing = null;
}
}
if (PropertyBuilder != null)
Attribute.ApplyAttributes (
ec, PropertyBuilder, this, OptAttributes, Location);
+ if (Get != null)
+ Attribute.ApplyAttributes (ec, GetBuilder, Get, Get.OptAttributes, Location);
+ if (Set != null)
+ Attribute.ApplyAttributes (ec, SetBuilder, Set, Set.OptAttributes, Location);
if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
return;
/// Whether we are inside an unsafe block
/// </summary>
public bool InUnsafe;
+
+ /// <summary>
+ /// Whether we break from a loop or not
+ /// </summary>
+ public bool Breaks;
/// <summary>
/// Location for this EmitContext
Options.AddAbout(' ',"about", "About the MonoBASIC compiler");
Options.AddBooleanSwitch('v',"verbose", "Verbose parsing (for debugging the parser)", new OptionFound(SetVerboseParsing) );
Options.AddSymbolAdder('m',"main", "Specifies CLASS as main (starting) class", "CLASS", new OptionFound(SetMainClass) );
- MainDriver(args);
- return (error_count + Report.Errors) != 0 ? 1 : 0;
+
+ bool ok = MainDriver (args);
+
+ if (ok && Report.Errors == 0)
+ {
+ Console.Write("Compilation succeeded");
+ if (Report.Warnings > 0)
+ {
+ Console.Write(" - {0} warning(s)", Report.Warnings);
+ }
+ Console.WriteLine();
+ return 0;
+ }
+ else
+ {
+ Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
+ Report.Errors, Report.Warnings);
+ return 1;
+ }
}
static public int LoadAssembly (string assembly, bool soft)
static bool AddFiles (string spec, bool recurse)
{
string path, pattern;
- int errors = 0;
SplitPathAndPattern (spec, out path, out pattern);
if (pattern.IndexOf ("*") == -1){
/// TODO: Mostly structured to debug the compiler
/// now, needs to be turned into a real driver soon.
/// </remarks>
- static void MainDriver (string [] args)
+ static bool MainDriver (string [] args)
{
- int errors = 0, i;
+ int errors = 0;//, i;
string output_file = null;
- bool parsing_options = true;
+ //bool parsing_options = true;
references = new ArrayList ();
soft_references = new ArrayList ();
link_paths.Add (GetSystemDir ());
if (!Options.ProcessArgs(args))
- return;
+ return false;
-/* int argc = args.Length;
- for (i = 0; i < argc; i++){
- string arg = args [i];
- //
- // Prepare to recurse
- //
+ /* int argc = args.Length;
+ for (i = 0; i < argc; i++){
+ string arg = args [i];
+ //
+ // Prepare to recurse
+ //
- if (parsing_options && (arg.StartsWith ("-"))){
- switch (arg){
-
- case "--":
- parsing_options = false;
- continue;
-
- case "--parse":
- parse_only = true;
- continue;
-
- case "--unsafe":
- RootContext.Unsafe = true;
- continue;
-
- case "/?": case "/h": case "/help":
- case "--help":
- Usage (false);
- return;
-
- case "--define":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
- defines.Add (args [++i]);
- continue;
+ if (parsing_options && (arg.StartsWith ("-"))){
+ switch (arg){
+
+ case "--":
+ parsing_options = false;
+ continue;
+
+ case "--parse":
+ parse_only = true;
+ continue;
+
+ case "--unsafe":
+ RootContext.Unsafe = true;
+ continue;
+
+ case "/?": case "/h": case "/help":
+ case "--help":
+ Usage (false);
+ return false;
+
+ case "--define":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
+ defines.Add (args [++i]);
+ continue;
- case "--probe": {
- int code = 0;
-
- try {
- code = Int32.Parse (
- args [++i], NumberStyles.AllowLeadingSign);
- Report.SetProbe (code);
- } catch {
- Report.Error (-14, "Invalid number specified");
- }
- continue;
- }
-
- case "--tokenize": {
- tokenize = true;
- continue;
- }
+ case "--probe": {
+ int code = 0;
+
+ try {
+ code = Int32.Parse (
+ args [++i], NumberStyles.AllowLeadingSign);
+ Report.SetProbe (code);
+ } catch {
+ Report.Error (-14, "Invalid number specified");
+ }
+ continue;
+ }
+
+ case "--tokenize": {
+ tokenize = true;
+ continue;
+ }
- case "-o":
- case "--output":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
- output_file = args [++i];
- string bname = CodeGen.Basename (output_file);
- if (bname.IndexOf (".") == -1)
- output_file += ".exe";
- continue;
-
- case "--checked":
- RootContext.Checked = true;
- continue;
-
- case "--stacktrace":
- Report.Stacktrace = true;
- continue;
-
- case "--target":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
-
- string type = args [++i];
- switch (type){
- case "library":
- target = Target.Library;
- target_ext = ".dll";
- break;
+ case "-o":
+ case "--output":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
+ output_file = args [++i];
+ string bname = CodeGen.Basename (output_file);
+ if (bname.IndexOf (".") == -1)
+ output_file += ".exe";
+ continue;
+
+ case "--checked":
+ RootContext.Checked = true;
+ continue;
+
+ case "--stacktrace":
+ Report.Stacktrace = true;
+ continue;
+
+ case "--target":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
+
+ string type = args [++i];
+ switch (type){
+ case "library":
+ target = Target.Library;
+ target_ext = ".dll";
+ break;
- case "exe":
- target = Target.Exe;
- break;
+ case "exe":
+ target = Target.Exe;
+ break;
- case "winexe":
- target = Target.WinExe;
- break;
+ case "winexe":
+ target = Target.WinExe;
+ break;
- case "module":
- target = Target.Module;
- target_ext = ".dll";
- break;
- default:
- Usage (true);
- return;
- }
- continue;
-
- case "-r":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
+ case "module":
+ target = Target.Module;
+ target_ext = ".dll";
+ break;
+ default:
+ Usage (true);
+ return false;
+ }
+ continue;
+
+ case "-r":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
- references.Add(args [++i]);
- continue;
+ references.Add(args [++i]);
+ continue;
- case "--resource":
- if ((i + 1) >= argc)
- {
- Usage (true);
- Console.WriteLine("Missing argument to --resource");
- return;
- }
+ case "--resource":
+ if ((i + 1) >= argc)
+ {
+ Usage (true);
+ Console.WriteLine("Missing argument to --resource");
+ return false;
+ }
- resources.Add(args [++i]);
- continue;
+ resources.Add(args [++i]);
+ continue;
- case "-L":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
- link_paths.Add (args [++i]);
- continue;
+ case "-L":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
+ link_paths.Add (args [++i]);
+ continue;
- case "--nostdlib":
- RootContext.StdLib = false;
- continue;
+ case "--nostdlib":
+ RootContext.StdLib = false;
+ continue;
- case "--fatal":
- Report.Fatal = true;
- continue;
-
- case "--werror":
- Report.WarningsAreErrors = true;
- continue;
-
- case "--nowarn":
- if ((i + 1) >= argc){
- Usage (true);
- return;
- }
- int warn;
+ case "--fatal":
+ Report.Fatal = true;
+ continue;
+
+ case "--werror":
+ Report.WarningsAreErrors = true;
+ continue;
+
+ case "--nowarn":
+ if ((i + 1) >= argc){
+ Usage (true);
+ return false;
+ }
+ int warn;
- try {
- warn = Int32.Parse (args [++i]);
- } catch {
- Usage (true);
- return;
- }
- Report.SetIgnoreWarning (warn);
- continue;
-
- case "--wlevel":
- if ((i + 1) >= argc){
- Report.Error (
- 1900,
- "--wlevel requires an value from 0 to 4");
- error_count++;
- return;
- }
- int level;
+ try {
+ warn = Int32.Parse (args [++i]);
+ } catch {
+ Usage (true);
+ return false;
+ }
+ Report.SetIgnoreWarning (warn);
+ continue;
+
+ case "--wlevel":
+ if ((i + 1) >= argc){
+ Report.Error (
+ 1900,
+ "--wlevel requires an value from 0 to 4");
+ error_count++;
+ return false;
+ }
+ int level;
- try {
- level = Int32.Parse (args [++i]);
- } catch {
- Report.Error (
- 1900,
- "--wlevel requires an value from 0 to 4");
- return;
- }
- if (level < 0 || level > 4){
- Report.Error (1900, "Warning level must be 0 to 4");
- return;
- } else
- RootContext.WarningLevel = level;
- continue;
+ try {
+ level = Int32.Parse (args [++i]);
+ } catch {
+ Report.Error (
+ 1900,
+ "--wlevel requires an value from 0 to 4");
+ return false;
+ }
+ if (level < 0 || level > 4){
+ Report.Error (1900, "Warning level must be 0 to 4");
+ return false;
+ } else
+ RootContext.WarningLevel = level;
+ continue;
- case "--about":
- About ();
- return;
-
- case "--recurse":
- if ((i + 1) >= argc){
- Console.WriteLine ("--recurse requires an argument");
- error_count++;
- return;
- }
- AddFiles (args [++i], true);
- continue;
+ case "--about":
+ About ();
+ return false;
+
+ case "--recurse":
+ if ((i + 1) >= argc){
+ Console.WriteLine ("--recurse requires an argument");
+ error_count++;
+ return false;
+ }
+ AddFiles (args [++i], true);
+ continue;
- case "--timestamp":
- timestamps = true;
- last_time = DateTime.Now;
- debug_arglist.Add("timestamp");
- continue;
-
- case "--debug": case "-g":
- want_debugging_support = true;
- continue;
-
- case "--debug-args":
- if ((i + 1) >= argc){
- Console.WriteLine ("--debug-args requires an argument");
- error_count++;
- return;
+ case "--timestamp":
+ timestamps = true;
+ last_time = DateTime.Now;
+ debug_arglist.Add("timestamp");
+ continue;
+
+ case "--debug": case "-g":
+ want_debugging_support = true;
+ continue;
+
+ case "--debug-args":
+ if ((i + 1) >= argc){
+ Console.WriteLine ("--debug-args requires an argument");
+ error_count++;
+ return false;
+ }
+ char[] sep = { ',' };
+ debug_arglist.AddRange (args [++i].Split (sep));
+ continue;
+
+ case "--noconfig":
+ load_default_config = false;
+ continue;
+
+ default:
+ Console.WriteLine ("Unknown option: " + arg);
+ errors++;
+ continue;
+ }
+ }
+
+ // Rafael: Does not compile them yet!!!
+ errors += AddFiles(arg, false);
}
- char[] sep = { ',' };
- debug_arglist.AddRange (args [++i].Split (sep));
- continue;
-
- case "--noconfig":
- load_default_config = false;
- continue;
-
- default:
- Console.WriteLine ("Unknown option: " + arg);
- errors++;
- continue;
- }
- }
-
- // Rafael: Does not compile them yet!!!
- errors += AddFiles(arg, false);
- }
-*/
+ */
//Rafael: Compile all source files!!!
foreach(string filename in source_files.Values)
errors += ProcessSourceFile(filename);
if (first_source == null)
{
Report.Error (2008, "No files to compile were specified");
- return;
+ return false;
}
if (tokenize)
- return;
+ return true;
if (Report.Errors > 0)
- return;
+ return false;
if (parse_only)
- return;
+ return true;
//
// Load Core Library for default compilation
if (load_default_config)
DefineDefaultConfig ();
- if (errors > 0){
+ if (errors > 0)
+ {
error ("Parsing failed");
- return;
+ return false;
}
//
if (timestamps)
ShowTime (" References loaded");
- if (errors > 0){
+ if (errors > 0)
+ {
error ("Could not load one or more assemblies");
- return;
+ return false;
}
error_count = errors;
//
// Quick hack
//
- if (output_file == null){
+ if (output_file == null)
+ {
int pos = first_source.LastIndexOf (".");
if (pos > 0)
//
if (timestamps)
ShowTime ("Initializing Core Types");
- if (!RootContext.StdLib){
+ if (!RootContext.StdLib)
+ {
RootContext.ResolveCore ();
if (Report.Errors > 0)
- return;
+ return false;
}
TypeManager.InitCoreTypes ();
if (timestamps)
ShowTime ("Populate tree");
- if (Report.Errors > 0){
+ if (Report.Errors > 0)
+ {
error ("Compilation failed");
- return;
+ return false;
}
if (!RootContext.StdLib)
TypeManager.InitCodeHelpers ();
- if (Report.Errors > 0){
+ if (Report.Errors > 0)
+ {
error ("Compilation failed");
- return;
+ return false;
}
//
if (timestamps)
ShowTime (" done");
- if (Report.Errors > 0){
+ if (Report.Errors > 0)
+ {
error ("Compilation failed");
- return;
+ return false;
}
if (timestamps)
RootContext.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 = RootContext.EntryPoint;
-//
-// if (ep == null){
-// Report.Error (5001, "Program " + output_file +
-// " does not have an entry point defined");
-// return;
-// }
-//
-// CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
-// }
+ // 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);
+ // }
//
// Add the resources
//
- if (resources != null){
+ if (resources != null)
+ {
foreach (string file in resources)
CodeGen.AssemblyBuilder.AddResourceFile (file, file);
}
if (timestamps)
ShowTime ("Saved output");
- if (want_debugging_support) {
+ if (want_debugging_support)
+ {
CodeGen.SaveSymbols ();
if (timestamps)
ShowTime ("Saved symbols");
}
- if (Report.Errors > 0){
- error ("Compilation failed");
- return;
- } else if (Report.ProbeCode != 0){
- error ("Failed to report code " + Report.ProbeCode);
- Environment.Exit (124);
+ if (Report.ExpectedError != 0)
+ {
+ Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
+ Environment.Exit (1);
+ return false;
}
+ return (Report.Errors == 0);
}
}
}
// from an array-type to System.Array
- if (expr_type.IsArray && target_type.IsAssignableFrom (expr_type))
+ if (expr_type.IsArray && (target_type == TypeManager.array_type))
return true;
// from any delegate type to System.Delegate
return true;
// from the null type to any reference-type.
- if (expr is NullLiteral && !target_type.IsValueType)
+ if (expr is NullLiteral && !target_type.IsValueType &&
+ !TypeManager.IsEnumType (target_type))
return true;
}
ig.Emit (OpCodes.Ldind_I1);
else if (t == TypeManager.intptr_type)
ig.Emit (OpCodes.Ldind_I);
- else if (TypeManager.IsEnumType (t))
- LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
- else if (t.IsValueType)
+ else if (TypeManager.IsEnumType (t)) {
+ if (t == TypeManager.enum_type)
+ ig.Emit (OpCodes.Ldind_Ref);
+ else
+ LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
+ } else if (t.IsValueType)
ig.Emit (OpCodes.Ldobj, t);
else
ig.Emit (OpCodes.Ldind_Ref);
}
return e;
- }
+ }
+
+ if (e is PropertyExpr) {
+ PropertyExpr pe = (PropertyExpr) e;
+
+ if (ec.IsStatic){
+ if (allow_static)
+ return e;
+
+ return MemberStaticCheck (e);
+ } else {
+ // If we are not in static code and this
+ // field is not static, set the instance to `this'.
+
+ if (!pe.IsStatic)
+ pe.InstanceExpression = ec.This;
+ }
+
+ return e;
+ }
if (e is EventExpr) {
//
else
Accessors = new MethodInfo [2];
- type = pi.PropertyType;
+ type = TypeManager.TypeToCoreType (pi.PropertyType);
}
//
public Indirection (Expression expr)
{
this.expr = expr;
- this.type = expr.Type.GetElementType ();
+ this.type = TypeManager.TypeToCoreType (expr.Type.GetElementType ());
eclass = ExprClass.Variable;
}
array = ig.DeclareLocal (Type.GetType (array_type));
IntConstant.EmitInt (ig, count);
- ig.Emit (OpCodes.Newarr, t);
+ ig.Emit (OpCodes.Newarr, TypeManager.TypeToCoreType (t));
ig.Emit (OpCodes.Stloc, array);
int top = arguments.Count;
/// The MethodBase argument might be null if the
/// emission of the arguments is known not to contain
/// a `params' field (for example in constructors or other routines
- /// that keep their arguments in this structure
+ /// that keep their arguments in this structure)
/// </summary>
public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments)
{
Type decl_type = method.DeclaringType;
+ if (!RootContext.StdLib) {
+ // Replace any calls to the system's System.Array type with calls to
+ // the newly created one.
+ if (method == TypeManager.system_int_array_get_length)
+ method = TypeManager.int_array_get_length;
+ else if (method == TypeManager.system_int_array_get_rank)
+ method = TypeManager.int_array_get_rank;
+ else if (method == TypeManager.system_object_array_clone)
+ method = TypeManager.object_array_clone;
+ else if (method == TypeManager.system_int_array_get_length_int)
+ method = TypeManager.int_array_get_length_int;
+ else if (method == TypeManager.system_int_array_get_lower_bound_int)
+ method = TypeManager.int_array_get_lower_bound_int;
+ else if (method == TypeManager.system_int_array_get_upper_bound_int)
+ method = TypeManager.int_array_get_upper_bound_int;
+ else if (method == TypeManager.system_void_array_copyto_array_int)
+ method = TypeManager.void_array_copyto_array_int;
+ }
+
//
// This checks the `ConditionalAttribute' on the method, and the
// ObsoleteAttribute
Arguments, loc);
}
-
- if (method == null && !is_struct) {
- Error (1501, loc,
- "New invocation: Can not find a constructor for " +
- "this argument list");
- return null;
+
+ if (method == null) {
+ if (!is_struct || Arguments.Count > 0) {
+ Error (1501, loc,
+ "New invocation: Can not find a constructor for " +
+ "this argument list");
+ return null;
+ }
}
return this;
}
void EmitArrayArguments (EmitContext ec)
{
- foreach (Argument a in arguments)
+ ILGenerator ig = ec.ig;
+
+ foreach (Argument a in arguments) {
+ Type atype = a.Type;
a.Emit (ec);
+ if (atype == TypeManager.uint64_type || atype == TypeManager.int64_type)
+ ig.Emit (OpCodes.Conv_Ovf_U4);
+ }
}
void DoEmit (EmitContext ec, bool is_statement)
public override void Emit (EmitContext ec)
{
- ec.ig.Emit (OpCodes.Ldarg_0);
+ ILGenerator ig = ec.ig;
+
+ ig.Emit (OpCodes.Ldarg_0);
+ if (ec.TypeContainer is Struct)
+ ig.Emit (OpCodes.Ldobj, type);
}
public void EmitAssign (EmitContext ec, Expression source)
{
- source.Emit (ec);
- ec.ig.Emit (OpCodes.Starg, 0);
+ ILGenerator ig = ec.ig;
+
+ if (ec.TypeContainer is Struct){
+ ig.Emit (OpCodes.Ldarg_0);
+ source.Emit (ec);
+ ig.Emit (OpCodes.Stobj, type);
+ } else {
+ source.Emit (ec);
+ ig.Emit (OpCodes.Starg, 0);
+ }
}
public void AddressOf (EmitContext ec, AddressOp mode)
{
//
// We are the sole users of ResolveWithSimpleName (ie, the only
- // ones that can cope with it
+ // ones that can cope with it)
//
Expression original = expr;
expr = expr.ResolveWithSimpleName (ec);
else if (t == TypeManager.intptr_type)
ig.Emit (OpCodes.Stelem_I);
else if (t.IsValueType)
- ig.Emit (OpCodes.Stobj, t);
+ ig.Emit (OpCodes.Stobj, TypeManager.TypeToCoreType (t));
else
ig.Emit (OpCodes.Stelem_Ref);
}
}
}
-public override void parse ()
+public override int parse ()
{
current_namespace = new Namespace (null, "");
current_container = RootContext.Tree.Types;
Console.WriteLine (lexer.location + " : Parsing error ");
Console.WriteLine (e);
}
+
+ return Report.Errors;
}
/* end end end */
return s;
}
-
+
public static TypeAttributes TypeAttr (int mod_flags, TypeContainer caller)
{
TypeAttributes t = 0;
if ((i & invalid_flags) == 0)
continue;
- Report.Error (106, l, "the modifier `" + Name (i) +
- "' is not valid for this item");
+ Error_InvalidModifier (l, Name (i));
}
return allowed & mod;
}
+
+ public static void Error_InvalidModifier (Location l, string name)
+ {
+ Report.Error (106, l, "the modifier " + name + " is not valid for this item");
+ }
}
}
public void Using (string ns)
{
if (decl_found){
- GenericParser.error (1529, "A using clause must precede all other namespace elements");
+ Report.Error (1529, "A using clause must precede all other namespace elements");
return;
}
if (de.Value == null){
string name = (string) de.Key;
- GenericParser.error (234, "The type or namespace `" +
+ Report.Error (234, "The type or namespace `" +
name + "' does not exist in the " +
"class or namespace `" + name + "'");
}
static public bool Stacktrace;
//
- // If the error code is reported on the given line,
- // then the process exits with a unique error code.
+ // If the 'expected' error code is reported then the
+ // compilation succeeds.
//
// Used for the test suite to excercise the error codes
//
- static int probe_error = 0;
+ static int expected_error = 0;
//
// Keeps track of the warnings that we are ignoring
static void Check (int code)
{
- if (code == probe_error){
+ if (code == expected_error){
if (Fatal)
throw new Exception ();
- Environment.Exit (123);
+ Environment.Exit (0);
}
}
warning_ignore_table [code] = true;
}
- static public void SetProbe (int code)
- {
- probe_error = code;
- }
-
- static public int ProbeCode {
- get {
- return probe_error;
- }
- }
+ static public int ExpectedError {
+ set {
+ expected_error = value;
+ }
+ get {
+ return expected_error;
+ }
+ }
}
public class Message {
// These are classes that depends on the core interfaces
//
string [] classes_second_stage = {
- "System.String", "System.Enum",
- "System.Array", "System.MulticastDelegate",
- "System.Delegate",
-
"System.Reflection.MemberInfo",
"System.Type",
"System.Security.UnverifiableCodeAttribute",
"System.Runtime.CompilerServices.IndexerNameAttribute",
};
+
+ // We must store them here before calling BootstrapCorlib_ResolveDelegate.
+ TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String");
+ TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum");
+ TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array");
+ TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
+ TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
foreach (string cname in classes_second_stage)
BootstrapCorlib_ResolveClass (root, cname);
if (type_container_resolve_order != null){
- foreach (TypeContainer tc in type_container_resolve_order)
+ foreach (TypeContainer tc in type_container_resolve_order) {
+ // When compiling corlib, these types have already been
+ // populated from BootCorlib_PopulateCoreTypes ().
+ if (!RootContext.StdLib &&
+ ((tc.Name == "System.Object") ||
+ (tc.Name == "System.Attribute") ||
+ (tc.Name == "System.ValueType")))
+ continue;
+
if ((tc.ModFlags & Modifiers.NEW) == 0)
tc.Define (root);
else
Report1530 (tc.Location);
+ }
}
ArrayList delegates = root.Delegates;
}
if (Unsafe) {
- ConstructorInfo ci = TypeManager.unverifiable_code_type.GetConstructor (new Type [0]);
-
- if (ci == null) {
- Console.WriteLine ("Internal error !");
+ if (TypeManager.unverifiable_code_ctor == null) {
+ Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
return;
}
- CustomAttributeBuilder cb = new CustomAttributeBuilder (ci, new object [0]);
+ CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]);
CodeGen.ModuleBuilder.SetCustomAttribute (cb);
}
}
if (impl_details_class == null)
impl_details_class = CodeGen.ModuleBuilder.DefineType (
- "<PrivateImplementationDetails>", TypeAttributes.NotPublic);
+ "<PrivateImplementationDetails>", TypeAttributes.NotPublic, TypeManager.object_type);
fb = impl_details_class.DefineInitializedData (
"$$field-" + (field_count++), data,
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ec.InLoop = true;
ig.MarkLabel (loop);
+ ec.Breaks = false;
EmbeddedStatement.Emit (ec);
+ bool breaks = ec.Breaks;
ig.MarkLabel (ec.LoopBegin);
//
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
//
// Inform whether we are infinite or not
BoolConstant bc = (BoolConstant) expr;
if (bc.Value == true)
- return true;
+ return breaks == false;
}
return false;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label while_loop = ig.DefineLabel ();
bool ret;
Warning_DeadCodeFound (Statement.loc);
ret = false;
} else {
+ bool breaks;
+
+ ec.Breaks = false;
Statement.Emit (ec);
+ breaks = ec.Breaks;
ig.Emit (OpCodes.Br, ec.LoopBegin);
//
- // Inform that we are infinite (ie, `we return')
+ // Inform that we are infinite (ie, `we return'), only
+ // if we do not `break' inside the code.
//
- ret = true;
+ ret = breaks == false;
}
ig.MarkLabel (ec.LoopEnd);
} else {
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
return ret;
}
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label loop = ig.DefineLabel ();
if (InitStatement != null)
//
if (Test != null)
EmitBoolExpression (ec, Test, ec.LoopEnd, false);
-
+
+ ec.Breaks = false;
Statement.Emit (ec);
+ bool breaks = ec.Breaks;
+
ig.MarkLabel (ec.LoopBegin);
if (!(Increment is EmptyStatement))
Increment.Emit (ec);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
-
+ ec.Breaks = old_breaks;
+
//
// Inform whether we are infinite or not
//
BoolConstant bc = (BoolConstant) Test;
if (bc.Value)
- return true;
+ return breaks == false;
}
return false;
} else
Report.Error (139, loc, "No enclosing loop or switch to continue to");
return false;
}
-
+
+ ec.Breaks = true;
ig.Emit (OpCodes.Br, ec.LoopEnd);
return false;
// fill the key lists
int iBlockCurr = 0;
- kbCurr = (KeyBlock) rgKeyBlocks [0];
- foreach (object key in rgKeys)
- {
- bool fNextBlock = (key is UInt64) ? (ulong) key > (ulong) kbCurr.nLast : Convert.ToInt64 (key) > kbCurr.nLast;
- if (fNextBlock)
- kbCurr = (KeyBlock) rgKeyBlocks [++iBlockCurr];
- kbCurr.rgKeys.Add (key);
+ if (rgKeyBlocks.Count > 0) {
+ kbCurr = (KeyBlock) rgKeyBlocks [0];
+ foreach (object key in rgKeys)
+ {
+ bool fNextBlock = (key is UInt64) ? (ulong) key > (ulong) kbCurr.nLast : Convert.ToInt64 (key) > kbCurr.nLast;
+ if (fNextBlock)
+ kbCurr = (KeyBlock) rgKeyBlocks [++iBlockCurr];
+ kbCurr.rgKeys.Add (key);
+ }
}
// sort the blocks so we can tackle the largest ones first
// okay now we can start...
ILGenerator ig = ec.ig;
Label lblEnd = ig.DefineLabel (); // at the end ;-)
- Label lblDefault = new Label ();
- Type typeKeys = rgKeys [0].GetType (); // used for conversions
+ Label lblDefault = ig.DefineLabel ();
+
+ Type typeKeys = null;
+ if (rgKeys.Length > 0)
+ typeKeys = rgKeys [0].GetType (); // used for conversions
for (int iBlock = rgKeyBlocks.Count - 1; iBlock >= 0; --iBlock)
{
static public Type [] NoTypes;
+ //
+ // This is only used when compiling corlib
+ //
+ static public Type system_int32_type;
+ static public Type system_array_type;
+ static public Type system_type_type;
+ static public Type system_assemblybuilder_type;
+ static public MethodInfo system_int_array_get_length;
+ static public MethodInfo system_int_array_get_rank;
+ static public MethodInfo system_object_array_clone;
+ static public MethodInfo system_int_array_get_length_int;
+ static public MethodInfo system_int_array_get_lower_bound_int;
+ static public MethodInfo system_int_array_get_upper_bound_int;
+ static public MethodInfo system_void_array_copyto_array_int;
+ static public MethodInfo system_void_set_corlib_type_builders;
+
//
// Internal, not really used outside
static public MethodInfo delegate_remove_delegate_delegate;
static public MethodInfo int_get_offset_to_string_data;
static public MethodInfo int_array_get_length;
+ static public MethodInfo int_array_get_rank;
+ static public MethodInfo object_array_clone;
+ static public MethodInfo int_array_get_length_int;
+ static public MethodInfo int_array_get_lower_bound_int;
+ static public MethodInfo int_array_get_upper_bound_int;
+ static public MethodInfo void_array_copyto_array_int;
//
// The attribute constructors.
//
static public ConstructorInfo cons_param_array_attribute;
static public ConstructorInfo void_decimal_ctor_five_args;
+ static public ConstructorInfo unverifiable_code_ctor;
// <remarks>
// Holds the Array of Assemblies that have been loaded
//
obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute");
conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute");
+
+ //
+ // When compiling corlib, store the "real" types here.
+ //
+ if (!RootContext.StdLib) {
+ system_int32_type = typeof (System.Int32);
+ system_array_type = typeof (System.Array);
+ system_type_type = typeof (System.Type);
+ system_assemblybuilder_type = typeof (System.Reflection.Emit.AssemblyBuilder);
+
+ Type [] void_arg = { };
+ system_int_array_get_length = GetMethod (
+ system_array_type, "get_Length", void_arg);
+ system_int_array_get_rank = GetMethod (
+ system_array_type, "get_Rank", void_arg);
+ system_object_array_clone = GetMethod (
+ system_array_type, "Clone", void_arg);
+
+ Type [] system_int_arg = { system_int32_type };
+ system_int_array_get_length_int = GetMethod (
+ system_array_type, "GetLength", system_int_arg);
+ system_int_array_get_upper_bound_int = GetMethod (
+ system_array_type, "GetUpperBound", system_int_arg);
+ system_int_array_get_lower_bound_int = GetMethod (
+ system_array_type, "GetLowerBound", system_int_arg);
+
+ Type [] system_array_int_arg = { system_array_type, system_int32_type };
+ system_void_array_copyto_array_int = GetMethod (
+ system_array_type, "CopyTo", system_array_int_arg);
+
+ Type [] system_type_type_arg = { system_type_type, system_type_type };
+ system_void_set_corlib_type_builders = GetMethod (
+ system_assemblybuilder_type, "SetCorlibTypeBuilders",
+ system_type_type_arg);
+
+ object[] args = new object [2];
+ args [0] = object_type;
+ args [1] = value_type;
+
+ system_void_set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ }
}
//
runtime_helpers_type, "get_OffsetToStringData", void_arg);
int_array_get_length = GetMethod (
array_type, "get_Length", void_arg);
+ int_array_get_rank = GetMethod (
+ array_type, "get_Rank", void_arg);
+
+ //
+ // Int32 arguments
+ //
+ Type [] int_arg = { int32_type };
+ int_array_get_length_int = GetMethod (
+ array_type, "GetLength", int_arg);
+ int_array_get_upper_bound_int = GetMethod (
+ array_type, "GetUpperBound", int_arg);
+ int_array_get_lower_bound_int = GetMethod (
+ array_type, "GetLowerBound", int_arg);
+
+ //
+ // System.Array methods
+ //
+ object_array_clone = GetMethod (
+ array_type, "Clone", void_arg);
+ Type [] array_int_arg = { array_type, int32_type };
+ void_array_copyto_array_int = GetMethod (
+ array_type, "CopyTo", array_int_arg);
//
// object arguments
//
// Array functions
//
- Type [] int_arg = { int32_type };
int_getlength_int = GetMethod (
array_type, "GetLength", int_arg);
//
cons_param_array_attribute = GetConstructor (
param_array_type, void_arg);
+
+ unverifiable_code_ctor = GetConstructor (
+ unverifiable_code_type, void_arg);
}
t = t.UnderlyingSystemType;
if (!TypeManager.IsEnumType (t))
return t;
-
+
+ if (t is TypeBuilder) {
+ // slow path needed to compile corlib
+ if (t == TypeManager.bool_type ||
+ t == TypeManager.byte_type ||
+ t == TypeManager.sbyte_type ||
+ t == TypeManager.char_type ||
+ t == TypeManager.short_type ||
+ t == TypeManager.ushort_type ||
+ t == TypeManager.int32_type ||
+ t == TypeManager.uint32_type ||
+ t == TypeManager.int64_type ||
+ t == TypeManager.uint64_type)
+ return t;
+ throw new Exception ("Unhandled typecode in enum " + " from " + t.AssemblyQualifiedName);
+ }
TypeCode tc = Type.GetTypeCode (t);
switch (tc){
case TypeCode.UInt64:
return TypeManager.uint64_type;
}
- throw new Exception ("Unhandled typecode in enum" + tc);
+ throw new Exception ("Unhandled typecode in enum " + tc + " from " + t.AssemblyQualifiedName);
}
//
//
public static Type TypeToCoreType (Type t)
{
- if (RootContext.StdLib)
+ if (RootContext.StdLib || (t is TypeBuilder))
return t;
TypeCode tc = Type.GetTypeCode (t);
return true;
}
+ if (!RootContext.StdLib && (t == TypeManager.decimal_type))
+ // We need this explicit check here to make it work when
+ // compiling corlib.
+ return true;
+
Report.Error (
208, loc,
"Cannot take the address or size of a variable of a managed type ('" +