X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Frootcontext.cs;h=4c6335c0b79ab42689d99ed9f78a9572a51b8c8a;hb=d61eb6ded629db1bc89fc53df1ab2affc4a0b767;hp=4e1e1abfc3f14cea12cc384b4a12a6c7c1088723;hpb=6cfd2055426c190ca2f6a9f8ca3af2da6f6a79d0;p=mono.git diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs index 4e1e1abfc3f..4c6335c0b79 100644 --- a/mcs/mcs/rootcontext.cs +++ b/mcs/mcs/rootcontext.cs @@ -2,15 +2,17 @@ // rootcontext.cs: keeps track of our tree representation, and assemblies loaded. // // Author: Miguel de Icaza (miguel@ximian.com) -// Ravi Pratap (ravi@ximian.com) +// Ravi Pratap (ravi@ximian.com) +// Marek Safar (marek.safar@gmail.com) // -// Licensed under the terms of the GNU GPL // -// (C) 2001 Ximian, Inc (http://www.ximian.com) -// (C) 2004 Novell, Inc +// Dual licensed under the terms of the MIT X11 or GNU GPL +// +// Copyright 2001 Ximian, Inc (http://www.ximian.com) +// Copyright 2004-2008 Novell, Inc using System; -using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Diagnostics; @@ -19,92 +21,134 @@ namespace Mono.CSharp { public enum LanguageVersion { - Default = 0, - ISO_1 = 1 + ISO_1 = 1, + ISO_2 = 2, + V_3 = 3, + V_4 = 4, + Future = 100, + + Default = LanguageVersion.V_4, + } + + public enum MetadataVersion + { + v1, + v2, + v4 } public class RootContext { // - // Contains the parsed tree + // COMPILER OPTIONS CLASS // - static Tree tree; + public static Target Target; + public static Platform Platform; + public static string TargetExt; + public static bool VerifyClsCompliance = true; + public static bool Optimize = true; + public static LanguageVersion Version; + public static bool EnhancedWarnings; + + public static MetadataVersion MetadataCompatibilityVersion; // - // This hashtable contains all of the #definitions across the source code - // it is used by the ConditionalAttribute handler. + // We keep strongname related info here because + // it's also used as complier options from CSC 8.x // - public static Hashtable AllDefines = new Hashtable (); - + public static string StrongNameKeyFile; + public static string StrongNameKeyContainer; + public static bool StrongNameDelaySign; + // - // Whether we are being linked against the standard libraries. - // This is only used to tell whether `System.Object' should - // have a base class or not. + // If set, enable XML documentation generation // - public static bool StdLib; + public static Documentation Documentation; + + static public string MainClass; + // + // The default compiler checked state // - // This keeps track of the order in which classes were defined - // so that we can poulate them in that order. + static public bool Checked; + // - // Order is important, because we need to be able to tell, by - // examining the list of methods of the base class, which ones are virtual - // or abstract as well as the parent names (to implement new, - // override). + // If true, it means that the compiler is executing as + // in eval mode so unresolved variables are resolved in + // static classes maintained by the eval engine. // - static ArrayList type_container_resolve_order; + static public bool EvalMode; // - // Holds a reference to the Private Implementation Details - // class. + // If true, the compiler is operating in statement mode, + // this currently turns local variable declaration into + // static variables of a class // - static ArrayList helper_classes; + static public bool StatementMode; - static TypeBuilder impl_details_class; - - public static int WarningLevel; - - public static Target Target; - public static string TargetExt; + // + // Whether to allow Unsafe code + // + static public bool Unsafe; - public static bool VerifyClsCompliance = true; + // + // Whether we are being linked against the standard libraries. + // This is only used to tell whether `System.Object' should + // have a base class or not. + // + public static bool StdLib; - /// - /// Holds /optimize option - /// - public static bool Optimize = true; + public static bool NeedsEntryPoint { + get { return Target == Target.Exe || Target == Target.WinExe; } + } - public static LanguageVersion Version; + // + // COMPILER OPTIONS CLASS END + // // - // We keep strongname related info here because - // it's also used as complier options from CSC 8.x + // Contains the parsed tree // - public static string StrongNameKeyFile; - public static string StrongNameKeyContainer; - public static bool StrongNameDelaySign; + static ModuleCompiled root; // - // If set, enable XML documentation generation + // This hashtable contains all of the #definitions across the source code + // it is used by the ConditionalAttribute handler. // - public static Documentation Documentation; + static List AllDefines; + + // + // Holds a reference to the Private Implementation Details + // class. + // + static List helper_classes; + + static TypeBuilder impl_details_class; - static public string MainClass; + public static List hack_corlib_enums = new List (); // // Constructor // static RootContext () { - Reset (); + Reset (true); } - public static void Reset () + public static void PartialReset () + { + Reset (false); + } + + public static void Reset (bool full) { - tree = new Tree (); - type_container_resolve_order = new ArrayList (); + impl_details_class = null; + helper_classes = null; + + if (!full) + return; + EntryPoint = null; - WarningLevel = 3; Checked = false; Unsafe = false; StdLib = true; @@ -113,39 +157,43 @@ namespace Mono.CSharp { StrongNameDelaySign = false; MainClass = null; Target = Target.Exe; - TargetExt = ".exe"; + TargetExt = ".exe"; + Platform = Platform.AnyCPU; Version = LanguageVersion.Default; Documentation = null; impl_details_class = null; - } - - public static bool NeedsEntryPoint { - get { - return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe; - } + helper_classes = null; + +#if NET_4_0 + MetadataCompatibilityVersion = MetadataVersion.v4; +#else + MetadataCompatibilityVersion = MetadataVersion.v2; +#endif + + // + // Setup default defines + // + AllDefines = new List (); + AddConditional ("__MonoCS__"); } - static public Tree Tree { - get { - return tree; - } + public static void AddConditional (string p) + { + if (AllDefines.Contains (p)) + return; + AllDefines.Add (p); } - public static void RegisterOrder (TypeContainer tc) + public static bool IsConditionalDefined (string value) { - type_container_resolve_order.Add (tc); + return AllDefines.Contains (value); + } + + static public ModuleCompiled ToplevelTypes { + get { return root; } + set { root = value; } } - - // - // The default compiler checked state - // - static public bool Checked; - // - // Whether to allow Unsafe code - // - static public bool Unsafe; - // // This function is used to resolve the hierarchy tree. // It processes interfaces, structs and classes in that order. @@ -155,260 +203,59 @@ namespace Mono.CSharp { // static public void ResolveTree () { + root.Resolve (); + // // Interfaces are processed next, as classes and // structs might inherit from an object or implement // a set of interfaces, we need to be able to tell // them appart by just using the TypeManager. // - TypeContainer root = Tree.Types; - - ArrayList ifaces = root.Interfaces; - if (ifaces != null){ - foreach (TypeContainer i in ifaces) - i.DefineType (); - } + foreach (TypeContainer tc in root.Types) + tc.CreateType (); foreach (TypeContainer tc in root.Types) tc.DefineType (); - - if (root.Delegates != null) - foreach (Delegate d in root.Delegates) - d.DefineType (); - - if (root.Enums != null) - foreach (Enum e in root.Enums) - e.DefineType (); - } - - static void Error_TypeConflict (string name, Location loc) - { - Report.Error ( - 520, loc, "`" + name + "' conflicts with a predefined type"); - } - - static void Error_TypeConflict (string name) - { - Report.Error ( - 520, "`" + name + "' conflicts with a predefined type"); - } - - // - // Resolves a single class during the corlib bootstrap process - // - static TypeBuilder BootstrapCorlib_ResolveClass (TypeContainer root, string name) - { - object o = root.GetDefinition (name); - if (o == null){ - Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - return null; - } - - if (!(o is Class)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return null; - } - - return ((DeclSpace) o).DefineType (); - } - - // - // Resolves a struct during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveStruct (TypeContainer root, string name) - { - object o = root.GetDefinition (name); - if (o == null){ - Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - return; - } - - if (!(o is Struct)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return; - } - - ((DeclSpace) o).DefineType (); } - // - // Resolves a struct during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name) + static void HackCorlib () { - object o = root.GetDefinition (name); - if (o == null){ - Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); + if (StdLib) return; - } - if (!(o is Interface)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; + // + // HACK: When building corlib mcs uses loaded mscorlib which + // has different predefined types and this method sets mscorlib types + // to be same to avoid type check errors in CreateType. + // + var type = typeof (Type); + var system_4_type_arg = new[] { type, type, type, type }; - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); + MethodInfo set_corlib_type_builders = + typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod ( + "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null, + system_4_type_arg, null); + if (set_corlib_type_builders == null) { + root.Compiler.Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders(...)' method", + typeof (System.Reflection.Emit.AssemblyBuilder).FullName); return; } - ((DeclSpace) o).DefineType (); + object[] args = new object[4]; + args[0] = TypeManager.object_type.GetMetaInfo (); + args[1] = TypeManager.value_type.GetMetaInfo (); + args[2] = TypeManager.enum_type.GetMetaInfo (); + args[3] = TypeManager.void_type.GetMetaInfo (); + set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args); + + // Another Mono corlib HACK + // mono_class_layout_fields requires to have enums created + // before creating a class which used the enum for any of its fields + foreach (var e in hack_corlib_enums) + e.CloseType (); } - // - // Resolves a delegate during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveDelegate (TypeContainer root, string name) - { - object o = root.GetDefinition (name); - if (o == null){ - Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - return; - } - - if (!(o is Delegate)){ - Error_TypeConflict (name); - return; - } - - ((DeclSpace) o).DefineType (); - } - - - /// - /// Resolves the core types in the compiler when compiling with --nostdlib - /// - static public void ResolveCore () - { - TypeContainer root = Tree.Types; - - TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object"); - TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType"); - TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute"); - TypeManager.indexer_name_type = BootstrapCorlib_ResolveClass (root, "System.Runtime.CompilerServices.IndexerNameAttribute"); - - string [] interfaces_first_stage = { - "System.IComparable", "System.ICloneable", - "System.IConvertible", - - "System.Collections.IEnumerable", - "System.Collections.ICollection", - "System.Collections.IEnumerator", - "System.Collections.IList", - "System.IAsyncResult", - "System.IDisposable", - - "System.Runtime.Serialization.ISerializable", - - "System.Reflection.IReflect", - "System.Reflection.ICustomAttributeProvider" - }; - - foreach (string iname in interfaces_first_stage) - BootstrapCorlib_ResolveInterface (root, iname); - - // - // These are the base value types - // - string [] structs_first_stage = { - "System.Byte", "System.SByte", - "System.Int16", "System.UInt16", - "System.Int32", "System.UInt32", - "System.Int64", "System.UInt64", - }; - - foreach (string cname in structs_first_stage) - BootstrapCorlib_ResolveStruct (root, cname); - - // - // Now, we can load the enumerations, after this point, - // we can use enums. - // - TypeManager.InitEnumUnderlyingTypes (); - - string [] structs_second_stage = { - "System.Single", "System.Double", - "System.Char", "System.Boolean", - "System.Decimal", "System.Void", - "System.RuntimeFieldHandle", - "System.RuntimeArgumentHandle", - "System.RuntimeTypeHandle", - "System.IntPtr", - "System.TypedReference", - "System.ArgIterator" - }; - - foreach (string cname in structs_second_stage) - BootstrapCorlib_ResolveStruct (root, cname); - - // - // These are classes that depends on the core interfaces - // - string [] classes_second_stage = { - "System.Enum", - "System.String", - "System.Array", - "System.Reflection.MemberInfo", - "System.Type", - "System.Exception", - - // - // These are not really important in the order, but they - // are used by the compiler later on (typemanager/CoreLookupType-d) - // - "System.Runtime.CompilerServices.RuntimeHelpers", - "System.Reflection.DefaultMemberAttribute", - "System.Threading.Monitor", - - "System.AttributeUsageAttribute", - "System.Runtime.InteropServices.DllImportAttribute", - "System.Runtime.CompilerServices.MethodImplAttribute", - "System.Runtime.InteropServices.MarshalAsAttribute", - "System.Diagnostics.ConditionalAttribute", - "System.ObsoleteAttribute", - "System.ParamArrayAttribute", - "System.CLSCompliantAttribute", - "System.Security.UnverifiableCodeAttribute", - "System.Security.Permissions.SecurityAttribute", - "System.Runtime.CompilerServices.DecimalConstantAttribute", - "System.Runtime.InteropServices.InAttribute", - "System.Runtime.InteropServices.OutAttribute", - "System.Runtime.InteropServices.StructLayoutAttribute", - "System.Runtime.InteropServices.FieldOffsetAttribute", - "System.InvalidOperationException", - "System.NotSupportedException", - "System.MarshalByRefObject", - "System.Security.CodeAccessPermission", - "System.Runtime.CompilerServices.RequiredAttributeAttribute", - "System.Runtime.InteropServices.GuidAttribute", - "System.Reflection.AssemblyCultureAttribute" - }; - - foreach (string cname in classes_second_stage) - BootstrapCorlib_ResolveClass (root, cname); - - BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback"); - - // These will be defined indirectly during the previous ResolveDelegate. - // However make sure the rest of the checks happen. - string [] delegate_types = { "System.Delegate", "System.MulticastDelegate" }; - foreach (string cname in delegate_types) - BootstrapCorlib_ResolveClass (root, cname); - } - // // Closes all open types // @@ -421,50 +268,27 @@ namespace Mono.CSharp { // static public void CloseTypes () { - TypeContainer root = Tree.Types; - - if (root.Enums != null) - foreach (Enum en in root.Enums) - en.CloseType (); + HackCorlib (); - // - // We do this in two passes, first we close the structs, - // then the classes, because it seems the code needs it this - // way. If this is really what is going on, we should probably - // make sure that we define the structs in order as well. - // - foreach (TypeContainer tc in type_container_resolve_order){ - if (tc.Kind == Kind.Struct && tc.Parent == tree.Types){ - tc.CloseType (); - } + foreach (TypeContainer tc in root.Types){ + tc.CloseType (); } - foreach (TypeContainer tc in type_container_resolve_order){ - if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types)) - tc.CloseType (); - } - - if (root.Delegates != null) - foreach (Delegate d in root.Delegates) - d.CloseType (); - + if (root.CompilerGeneratedClasses != null) + foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses) + c.CloseType (); // // If we have a class, close it // if (helper_classes != null){ foreach (TypeBuilder type_builder in helper_classes) { -#if NET_2_0 - type_builder.SetCustomAttribute (TypeManager.compiler_generated_attr); -#endif + PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (type_builder); type_builder.CreateType (); } } - type_container_resolve_order = null; helper_classes = null; - //tree = null; - TypeManager.CleanUp (); } /// @@ -474,29 +298,11 @@ namespace Mono.CSharp { public static void RegisterCompilerGeneratedType (TypeBuilder helper_class) { if (helper_classes == null) - helper_classes = new ArrayList (); + helper_classes = new List (); helper_classes.Add (helper_class); } - static public void PopulateCoreType (TypeContainer root, string name) - { - DeclSpace ds = (DeclSpace) root.GetDefinition (name); - - ds.DefineMembers (root); - ds.Define (); - } - - static public void BootCorlib_PopulateCoreTypes () - { - TypeContainer root = tree.Types; - - PopulateCoreType (root, "System.Object"); - PopulateCoreType (root, "System.ValueType"); - PopulateCoreType (root, "System.Attribute"); - PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute"); - } - // // Populates the structs and classes with fields and methods // @@ -505,139 +311,45 @@ namespace Mono.CSharp { // have been defined through `ResolveTree' static public void PopulateTypes () { - TypeContainer root = Tree.Types; - - if (type_container_resolve_order != null){ - if (RootContext.StdLib){ - foreach (TypeContainer tc in type_container_resolve_order) - tc.DefineMembers (root); - - } else { - foreach (TypeContainer tc in type_container_resolve_order) { - // When compiling corlib, these types have already been - // populated from BootCorlib_PopulateCoreTypes (). - if (((tc.Name == "System.Object") || - (tc.Name == "System.Attribute") || - (tc.Name == "System.ValueType") || - (tc.Name == "System.Runtime.CompilerServices.IndexerNameAttribute"))) - continue; - - tc.DefineMembers (root); - } - } - } - - ArrayList delegates = root.Delegates; - if (delegates != null){ - foreach (Delegate d in delegates) - d.DefineMembers (root); - } - - ArrayList enums = root.Enums; - if (enums != null){ - foreach (Enum en in enums) - en.DefineMembers (root); - } - - // - // Check for cycles in the struct layout - // - if (type_container_resolve_order != null){ - Hashtable seen = new Hashtable (); - foreach (TypeContainer tc in type_container_resolve_order) - TypeManager.CheckStructCycles (tc, seen); - } - } - - // - // A generic hook delegate - // - public delegate void Hook (); - - // - // A hook invoked when the code has been generated. - // - public static event Hook EmitCodeHook; - - // - // DefineTypes is used to fill in the members of each type. - // - static public void DefineTypes () - { - TypeContainer root = Tree.Types; - - ArrayList delegates = root.Delegates; - if (delegates != null){ - foreach (Delegate d in delegates) - d.Define (); - } - - if (type_container_resolve_order != null){ - 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") || - (tc.Name == "System.Runtime.CompilerServices.IndexerNameAttribute"))) - continue; + foreach (TypeContainer tc in ToplevelTypes.Types) + tc.ResolveTypeParameters (); + foreach (TypeContainer tc in ToplevelTypes.Types) { + try { tc.Define (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); } } - - ArrayList enums = root.Enums; - if (enums != null){ - foreach (Enum en in enums) - en.Define (); - } } static public void EmitCode () { - if (Tree.Types.Enums != null) { - foreach (Enum e in Tree.Types.Enums) - e.Emit (); - } + foreach (var tc in ToplevelTypes.Types) + tc.DefineConstants (); - if (type_container_resolve_order != null) { - foreach (TypeContainer tc in type_container_resolve_order) - tc.EmitType (); + foreach (TypeContainer tc in ToplevelTypes.Types) + tc.EmitType (); - if (Report.Errors > 0) - return; + if (ToplevelTypes.Compiler.Report.Errors > 0) + return; - foreach (TypeContainer tc in type_container_resolve_order) - tc.VerifyMembers (); - } - - if (Tree.Types.Delegates != null) { - foreach (Delegate d in Tree.Types.Delegates) - d.Emit (); - } - // - // Run any hooks after all the types have been defined. - // This is used to create nested auxiliary classes for example - // + foreach (TypeContainer tc in ToplevelTypes.Types) + tc.VerifyMembers (); - if (EmitCodeHook != null) - EmitCodeHook (); + if (root.CompilerGeneratedClasses != null) + foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses) + c.EmitType (); - CodeGen.Assembly.Emit (Tree.Types); - CodeGen.Module.Emit (Tree.Types); + CodeGen.Assembly.Emit (root); + root.Emit (); } // // Public Field, used to track which method is the public entry // point. // - static public MethodInfo EntryPoint; - - // - // Track the location of the entry point. - // - static public Location EntryPointLocation; + static public Method EntryPoint; // // These are used to generate unique names on the structs and fields. @@ -663,10 +375,10 @@ namespace Mono.CSharp { FieldBuilder fb; if (impl_details_class == null){ - impl_details_class = CodeGen.Module.Builder.DefineType ( + impl_details_class = ToplevelTypes.Builder.DefineType ( "", TypeAttributes.NotPublic, - TypeManager.object_type); + TypeManager.object_type.GetMetaInfo ()); RegisterCompilerGeneratedType (impl_details_class); } @@ -678,7 +390,7 @@ namespace Mono.CSharp { return fb; } - public static void CheckUnsafeOption (Location loc) + public static void CheckUnsafeOption (Location loc, Report Report) { if (!Unsafe) { Report.Error (227, loc, @@ -687,5 +399,3 @@ namespace Mono.CSharp { } } } - -