X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Frootcontext.cs;h=3d3e7dde9ac226c3835914f30ac317bd2ba6016d;hb=b34ee5f60611886990b39ab5fda526cbb9bff6c5;hp=7be4a193cf45dc2b9ad04faa8e041d78210e2226;hpb=81a37cf902858a5d670cf03b5bd39fe5dd131ecc;p=mono.git diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs index 7be4a193cf4..3d3e7dde9ac 100644 --- a/mcs/mcs/rootcontext.cs +++ b/mcs/mcs/rootcontext.cs @@ -6,13 +6,13 @@ // Marek Safar (marek.safar@gmail.com) // // -// Licensed under the terms of the GNU GPL +// Dual licensed under the terms of the MIT X11 or GNU GPL // -// (C) 2001 Ximian, Inc (http://www.ximian.com) -// (C) 2004 Novell, Inc +// 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; @@ -21,91 +21,134 @@ namespace Mono.CSharp { public enum LanguageVersion { - Default = 0, - ISO_1 = 1, - LINQ + 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 RootTypes root; + 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 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) { - root = new RootTypes (); - type_container_resolve_order = new ArrayList (); + impl_details_class = null; + helper_classes = null; + + if (!full) + return; + EntryPoint = null; - Report.WarningLevel = 3; Checked = false; Unsafe = false; StdLib = true; @@ -115,35 +158,42 @@ namespace Mono.CSharp { MainClass = null; Target = Target.Exe; TargetExt = ".exe"; + Platform = Platform.AnyCPU; Version = LanguageVersion.Default; Documentation = null; impl_details_class = null; helper_classes = null; - } - public static bool NeedsEntryPoint { - get { return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe; } +#if NET_4_0 + MetadataCompatibilityVersion = MetadataVersion.v4; +#else + MetadataCompatibilityVersion = MetadataVersion.v2; +#endif + + // + // Setup default defines + // + AllDefines = new List (); + AddConditional ("__MonoCS__"); } - static public RootTypes ToplevelTypes { - get { return root; } + 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. @@ -153,6 +203,8 @@ namespace Mono.CSharp { // static public void ResolveTree () { + root.Resolve (); + // // Interfaces are processed next, as classes and // structs might inherit from an object or implement @@ -164,247 +216,46 @@ namespace Mono.CSharp { foreach (TypeContainer tc in root.Types) tc.DefineType (); - - if (root.Delegates != null) - foreach (Delegate d in root.Delegates) - d.DefineType (); } - delegate bool VerifyBootstrapType (Type t); - - static Type BootstrapCorlib_ResolveType (TypeContainer root, string name, VerifyBootstrapType typeVerifier) + static void HackCorlib () { - TypeLookupExpression tle = new TypeLookupExpression (name); - Report.DisableReporting (); - TypeExpr te = tle.ResolveAsTypeTerminal (root, false); - Report.EnableReporting (); - if (te == null) { - Report.Error (518, "The predefined type `{0}' is not defined or imported", name); - return null; - } - - Type t = te.Type; - if (!typeVerifier (t)) { - MemberCore mc = root.GetDefinition (name); - Location loc = Location.Null; - if (mc != null) { - name = mc.GetSignatureForError (); - loc = mc.Location; - } - - Report.Error (520, loc, "The predefined type `{0}' is not declared correctly", name); - return null; - } - - AttributeTester.RegisterNonObsoleteType (t); - return t; - } - // - // Resolves a single class during the corlib bootstrap process - // - static Type BootstrapCorlib_ResolveClass (TypeContainer root, string name) - { - return BootstrapCorlib_ResolveType (root, name, IsClass); - } - - static bool IsClass (Type t) - { - DeclSpace ds = TypeManager.LookupDeclSpace (t); - if (ds != null) - return ds is Class; - return t.IsClass; - } - - // - // Resolves a struct during the corlib bootstrap process - // - static Type BootstrapCorlib_ResolveStruct (TypeContainer root, string name) - { - return BootstrapCorlib_ResolveType (root, name, IsStruct); - } - - static bool IsStruct (Type t) - { - DeclSpace ds = TypeManager.LookupDeclSpace (t); - if (ds != null) - return ds is Struct; - - return TypeManager.IsSubclassOf (t, TypeManager.value_type); - } - - // - // Resolves an interface during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name) - { - BootstrapCorlib_ResolveType (root, name, IsInterface); - } - - static bool IsInterface (Type t) - { - return t.IsInterface; - } - - // - // Resolves a delegate during the corlib bootstrap process - // - static void BootstrapCorlib_ResolveDelegate (TypeContainer root, string name) - { - BootstrapCorlib_ResolveType (root, name, IsDelegate); - } - - static bool IsDelegate (Type t) - { - return TypeManager.IsDelegateType (t); - } - - /// - /// Resolves the core types in the compiler when compiling with --nostdlib - /// - static public void ResolveCore () - { - TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object"); - TypeManager.system_object_expr.Type = TypeManager.object_type; - TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType"); - TypeManager.system_valuetype_expr.Type = TypeManager.value_type; - - // - // The core attributes - // - BootstrapCorlib_ResolveInterface (root, "System.Runtime.InteropServices._Attribute"); - TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute"); - TypeManager.obsolete_attribute_type = BootstrapCorlib_ResolveClass (root, "System.ObsoleteAttribute"); - 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", -#if GMCS_SOURCE - "System.Runtime.InteropServices._Exception", - - // - // Generic types - // - "System.Collections.Generic.IEnumerator`1", - "System.Collections.Generic.IEnumerable`1" -#endif - }; - - foreach (string iname in interfaces_first_stage) - BootstrapCorlib_ResolveInterface (root, iname); + if (StdLib) + return; // - // These are the base value types + // 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. // - 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); + var type = typeof (Type); + var system_4_type_arg = new[] { type, type, type, type }; - // - // 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.Decimal", "System.Void", - "System.RuntimeFieldHandle", - "System.RuntimeArgumentHandle", - "System.RuntimeTypeHandle", - "System.IntPtr", - "System.TypedReference", - "System.ArgIterator" - }; - - TypeManager.bool_type = BootstrapCorlib_ResolveStruct (root, "System.Boolean"); - - 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", -#if GMCS_SOURCE - "System.Activator", -#endif + MethodInfo set_corlib_type_builders = + typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod ( + "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null, + system_4_type_arg, null); - // - // 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.Threading.Interlocked", - - "System.AttributeUsageAttribute", - "System.Runtime.InteropServices.DllImportAttribute", - "System.Runtime.CompilerServices.MethodImplAttribute", - "System.Runtime.InteropServices.MarshalAsAttribute", -#if GMCS_SOURCE - "System.Runtime.CompilerServices.CompilerGeneratedAttribute", - "System.Runtime.CompilerServices.FixedBufferAttribute", -#endif - "System.Diagnostics.ConditionalAttribute", - "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", -#if GMCS_SOURCE - "System.Runtime.InteropServices.DefaultCharSetAttribute", -#endif - "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); -#if GMCS_SOURCE - BootstrapCorlib_ResolveStruct (root, "System.Nullable`1"); -#endif - TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate"); - BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate"); + 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; + } - BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback"); + 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 (); } - + // // Closes all open types // @@ -417,44 +268,27 @@ namespace Mono.CSharp { // static public void CloseTypes () { - // - // 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 == root){ - tc.CloseType (); - } - } + HackCorlib (); - foreach (TypeContainer tc in type_container_resolve_order){ - if (!(tc.Kind == Kind.Struct && tc.Parent == root)) - tc.CloseType (); + foreach (TypeContainer tc in root.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 GMCS_SOURCE - 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; - //root = null; - TypeManager.CleanUp (); } /// @@ -464,30 +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); - // Core type was imported - if (ds == null) - return; - - ds.DefineMembers (); - ds.Define (); - } - - static public void BootCorlib_PopulateCoreTypes () - { - 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 // @@ -496,106 +311,45 @@ namespace Mono.CSharp { // have been defined through `ResolveTree' static public void PopulateTypes () { + foreach (TypeContainer tc in ToplevelTypes.Types) + tc.ResolveTypeParameters (); - if (type_container_resolve_order != null){ - foreach (TypeContainer tc in type_container_resolve_order) - tc.ResolveType (); - foreach (TypeContainer tc in type_container_resolve_order) - tc.DefineMembers (); - } - - ArrayList delegates = root.Delegates; - if (delegates != null){ - foreach (Delegate d in delegates) - d.DefineMembers (); - } - - // - // 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 () - { - 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) { + try { tc.Define (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); } } } static public void EmitCode () { - if (type_container_resolve_order != null) { - foreach (TypeContainer tc in type_container_resolve_order) - tc.EmitType (); + foreach (var tc in ToplevelTypes.Types) + tc.DefineConstants (); - if (Report.Errors > 0) - return; + foreach (TypeContainer tc in ToplevelTypes.Types) + tc.EmitType (); - foreach (TypeContainer tc in type_container_resolve_order) - tc.VerifyMembers (); - } - - if (root.Delegates != null) { - foreach (Delegate d in root.Delegates) - d.Emit (); - } - // - // Run any hooks after all the types have been defined. - // This is used to create nested auxiliary classes for example - // + if (ToplevelTypes.Compiler.Report.Errors > 0) + return; + + 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 (root); - CodeGen.Module.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. @@ -621,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); } @@ -635,15 +389,5 @@ namespace Mono.CSharp { return fb; } - - public static void CheckUnsafeOption (Location loc) - { - if (!Unsafe) { - Report.Error (227, loc, - "Unsafe code requires the `unsafe' command line option to be specified"); - } - } } } - -