X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Frootcontext.cs;h=e6c2c4b2f1dc5ea543ad89cab34d2add27f13dc4;hb=cd5d5a8abe403c911b2a348122d9bc2f75b350c4;hp=f9cc920d2adabce8f5cb92fe44ea05cc0385e08b;hpb=a883b630bfe06753c768c7a2fe0304575eebc21e;p=mono.git diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs old mode 100755 new mode 100644 index f9cc920d2ad..e6c2c4b2f1d --- a/mcs/mcs/rootcontext.cs +++ b/mcs/mcs/rootcontext.cs @@ -2,12 +2,14 @@ // 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; @@ -19,41 +21,105 @@ namespace Mono.CSharp { public enum LanguageVersion { - Default = 0, - ISO_1 = 1 + ISO_1 = 1, + Default_MCS = 2, + ISO_2 = 3, + LINQ = 4, + Future = 5, + +#if GMCS_SOURCE + Default = LINQ +#else + Default = Default_MCS +#endif } public class RootContext { // - // Contains the parsed tree + // COMPILER OPTIONS CLASS // - static Tree tree; + public static Target Target; + public static string TargetExt; + public static bool VerifyClsCompliance = true; + public static bool Optimize = true; + public static LanguageVersion Version; // - // 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; + + // + // If set, enable XML documentation generation + // + public static Documentation Documentation; + + static public string MainClass; + + // + // The default compiler checked state + // + static public bool Checked; + + // + // 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 public bool EvalMode; + + // + // If true, the compiler is operating in statement mode, + // this currently turns local variable declaration into + // static variables of a class + // + static public bool StatementMode; + // + // Whether to allow Unsafe code + // + static public bool Unsafe; + // // Whether we are being linked against the standard libraries. // This is only used to tell whether `System.Object' should - // have a parent or not. + // have a base class or not. + // + public static bool StdLib; + + public static bool NeedsEntryPoint { + get { return Target == Target.Exe || Target == Target.WinExe; } + } + + // + // COMPILER OPTIONS CLASS END // - public static bool StdLib = true; + // + // Contains the parsed tree + // + static ModuleContainer root; + + // + // This hashtable contains all of the #definitions across the source code + // it is used by the ConditionalAttribute handler. + // + static ArrayList AllDefines; + // // This keeps track of the order in which classes were defined // so that we can poulate them in that order. // - // Order is important, because we need to be able to tell by - // examining the parent's list of methods which ones are virtual + // 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). // static ArrayList type_container_resolve_order; - static ArrayList attribute_types; // // Holds a reference to the Private Implementation Details @@ -63,81 +129,70 @@ namespace Mono.CSharp { static TypeBuilder impl_details_class; - public static int WarningLevel = 2; - - public static Target Target = Target.Exe; - public static string TargetExt = ".exe"; - - public static bool VerifyClsCompliance = true; - - public static LanguageVersion Version = LanguageVersion.Default; - - // - // We keep strongname related info here because - // it's also used as complier options from CSC 8.x - // - public static string StrongNameKeyFile; - public static string StrongNameKeyContainer; - public static bool StrongNameDelaySign = false; - - // - // If set, enable XML documentation generation - // - public static Documentation Documentation; - // // Constructor // static RootContext () { - tree = new Tree (); - type_container_resolve_order = new ArrayList (); - } - - public static bool NeedsEntryPoint { - get { - return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe; - } + Reset (true); } - static public Tree Tree { - get { - return tree; - } + public static void PartialReset () + { + Reset (false); } - - static public string MainClass; - public static void RegisterOrder (TypeContainer tc) + public static void Reset (bool full) { - type_container_resolve_order.Add (tc); + if (full) + root = null; + + type_container_resolve_order = new ArrayList (); + EntryPoint = null; + Report.WarningLevel = 4; + Checked = false; + Unsafe = false; + StdLib = true; + StrongNameKeyFile = null; + StrongNameKeyContainer = null; + StrongNameDelaySign = false; + MainClass = null; + Target = Target.Exe; + TargetExt = ".exe"; + Version = LanguageVersion.Default; + Documentation = null; + impl_details_class = null; + helper_classes = null; + + // + // Setup default defines + // + AllDefines = new ArrayList (); + AddConditional ("__MonoCS__"); } - public static void RegisterAttribute (TypeContainer tc) + public static void AddConditional (string p) { - if (attribute_types == null) - attribute_types = new ArrayList (); - - attribute_types.Add (tc); + if (AllDefines.Contains (p)) + return; + AllDefines.Add (p); } - - // - // The default compiler checked state - // - static public bool Checked = false; - // - // Whether to allow Unsafe code - // - static public bool Unsafe = false; - - static string MakeFQN (string nsn, string name) + public static bool IsConditionalDefined (string value) { - if (nsn == "") - return name; - return String.Concat (nsn, ".", name); + return AllDefines.Contains (value); + } + + static public ModuleContainer ToplevelTypes { + get { return root; } + set { root = value; } } + public static void RegisterOrder (TypeContainer tc) + { + type_container_resolve_order.Add (tc); + } + // // This function is used to resolve the hierarchy tree. // It processes interfaces, structs and classes in that order. @@ -147,26 +202,16 @@ namespace Mono.CSharp { // static public void ResolveTree () { - // - // Process the attribute types separately and before anything else - // - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.DefineType (); - + 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 (Interface i in ifaces) - i.DefineType (); - } + foreach (TypeContainer tc in root.Types) + tc.CreateType (); foreach (TypeContainer tc in root.Types) tc.DefineType (); @@ -174,234 +219,8 @@ namespace Mono.CSharp { 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"); - 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"); - 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) - { - object o = root.GetDefinition (name); - if (o == null){ - Report.Error (518, "The predefined type `" + name + "' is not defined"); - return; - } - - if (!(o is Interface)){ - if (o is DeclSpace){ - DeclSpace d = (DeclSpace) o; - - Error_TypeConflict (name, d.Location); - } else - Error_TypeConflict (name); - - return; - } - - ((DeclSpace) o).DefineType (); - } - - // - // 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"); - Environment.Exit (1); - } - - 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"); - - 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.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.IndexerNameAttribute", - "System.Runtime.CompilerServices.DecimalConstantAttribute", - "System.Runtime.InteropServices.InAttribute", - "System.Runtime.InteropServices.StructLayoutAttribute", - "System.Runtime.InteropServices.FieldOffsetAttribute", - "System.InvalidOperationException", - "System.NotSupportedException", - "System.MarshalByRefObject", - "System.Security.CodeAccessPermission" - }; - - // 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); - - BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback"); - } - // // Closes all open types // @@ -414,16 +233,6 @@ namespace Mono.CSharp { // static public void CloseTypes () { - TypeContainer root = Tree.Types; - - if (root.Enums != null) - foreach (Enum en in root.Enums) - en.CloseType (); - - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.CloseType (); - // // We do this in two passes, first we close the structs, // then the classes, because it seems the code needs it this @@ -431,13 +240,13 @@ namespace Mono.CSharp { // 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){ + if (tc.Kind == Kind.Struct && tc.Parent == root){ tc.CloseType (); } } foreach (TypeContainer tc in type_container_resolve_order){ - if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types)) + if (!(tc.Kind == Kind.Struct && tc.Parent == root)) tc.CloseType (); } @@ -450,14 +259,15 @@ namespace Mono.CSharp { // If we have a class, close it // if (helper_classes != null){ - foreach (TypeBuilder type_builder in helper_classes) + foreach (TypeBuilder type_builder in helper_classes) { + PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (type_builder); type_builder.CreateType (); + } } - attribute_types = null; type_container_resolve_order = null; helper_classes = null; - //tree = null; + //root = null; TypeManager.CleanUp (); } @@ -465,135 +275,30 @@ namespace Mono.CSharp { /// Used to register classes that need to be closed after all the /// user defined classes /// - public static void RegisterHelperClass (TypeBuilder helper_class) + public static void RegisterCompilerGeneratedType (TypeBuilder helper_class) { if (helper_classes == null) helper_classes = new ArrayList (); - helper_classes.Add (helper_class); - } - - // - // This idea is from Felix Arrese-Igor - // - // Returns : the implicit parent of a composite namespace string - // eg. Implicit parent of A.B is A - // - static public string ImplicitParent (string ns) - { - int i = ns.LastIndexOf ('.'); - if (i < 0) - return null; - - return ns.Substring (0, i); - } - - static Type NamespaceLookup (DeclSpace ds, string name, Location loc) - { - object result = ds.NamespaceEntry.LookupNamespaceOrType (ds, name, loc); - if (result == null) - return null; - - if (result is Type) - return (Type) result; - - return null; - } - - // - // Public function used to locate types, this can only - // be used after the ResolveTree function has been invoked. - // - // Returns: Type or null if they type can not be found. - // - // Come to think of it, this should be a DeclSpace - // - static public Type LookupType (DeclSpace ds, string name, bool silent, Location loc) - { - Type t; - - if (ds.Cache.Contains (name)) { - t = (Type) ds.Cache [name]; - } else { - // - // For the case the type we are looking for is nested within this one - // or is in any base class - // - DeclSpace containing_ds = ds; - while (containing_ds != null){ - - // if the member cache has been created, lets use it. - // the member cache is MUCH faster. - if (containing_ds.MemberCache != null) { - t = containing_ds.MemberCache.FindNestedType (name); - if (t == null) { - containing_ds = containing_ds.Parent; - continue; - } - - ds.Cache [name] = t; - return t; - } - - // no member cache. Do it the hard way -- reflection - Type current_type = containing_ds.TypeBuilder; - - while (current_type != null && - current_type != TypeManager.object_type) { - // - // nested class - // - t = TypeManager.LookupType (current_type.FullName + "." + name); - if (t != null){ - ds.Cache [name] = t; - return t; - } - - current_type = current_type.BaseType; - } - - containing_ds = containing_ds.Parent; - } - - t = NamespaceLookup (ds, name, loc); - if (!silent || t != null) - ds.Cache [name] = t; - } - - if (t == null && !silent) - Report.Error (246, loc, "Cannot find type `"+name+"'"); - - return t; - } - - // - // This is the silent version of LookupType, you can use this - // to `probe' for a type - // - static public Type LookupType (TypeContainer tc, string name, Location loc) - { - return LookupType (tc, name, true, loc); - } - static void Report1530 (Location loc) - { - Report.Error (1530, loc, "Keyword new not allowed for namespace elements"); + 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 (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"); } // @@ -604,46 +309,23 @@ namespace Mono.CSharp { // have been defined through `ResolveTree' static public void PopulateTypes () { - TypeContainer root = Tree.Types; - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.DefineMembers (root); - 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"))) - continue; - - tc.DefineMembers (root); + foreach (TypeContainer tc in type_container_resolve_order) + tc.ResolveType (); + foreach (TypeContainer tc in type_container_resolve_order) { + try { + tc.Define (); + } catch (Exception e) { + throw new InternalErrorException (tc, e); } - } + } } ArrayList delegates = root.Delegates; if (delegates != null){ foreach (Delegate d in delegates) - if ((d.ModFlags & Modifiers.NEW) == 0) - d.DefineMembers (root); - else - Report1530 (d.Location); - } - - ArrayList enums = root.Enums; - if (enums != null){ - foreach (Enum en in enums) - if ((en.ModFlags & Modifiers.NEW) == 0) - en.DefineMembers (root); - else - Report1530 (en.Location); + d.Define (); } // @@ -656,99 +338,33 @@ namespace Mono.CSharp { } } - // - // 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; - - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) - tc.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"))) - continue; - - if ((tc.ModFlags & Modifiers.NEW) == 0) - tc.Define (); - } - } - - ArrayList delegates = root.Delegates; - if (delegates != null){ - foreach (Delegate d in delegates) - if ((d.ModFlags & Modifiers.NEW) == 0) - d.Define (); - } - - ArrayList enums = root.Enums; - if (enums != null){ - foreach (Enum en in enums) - if ((en.ModFlags & Modifiers.NEW) == 0) - en.Define (); - } - } - static public void EmitCode () { - if (attribute_types != null) - foreach (TypeContainer tc in attribute_types) + if (type_container_resolve_order != null) { + foreach (TypeContainer tc in type_container_resolve_order) tc.EmitType (); - CodeGen.Assembly.Emit (Tree.Types); - CodeGen.Module.Emit (Tree.Types); - - if (Tree.Types.Enums != null) { - foreach (Enum e in Tree.Types.Enums) - e.Emit (); - } + if (Report.Errors > 0) + return; - if (type_container_resolve_order != null) { foreach (TypeContainer tc in type_container_resolve_order) - tc.EmitType (); + tc.VerifyMembers (); } - if (Tree.Types.Delegates != null) { - foreach (Delegate d in Tree.Types.Delegates) + 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 (EmitCodeHook != null) - EmitCodeHook (); + 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. @@ -774,12 +390,12 @@ 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); - RegisterHelperClass (impl_details_class); + RegisterCompilerGeneratedType (impl_details_class); } fb = impl_details_class.DefineInitializedData ( @@ -788,6 +404,14 @@ 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"); + } + } } }