Fixes cloning of a variable declarator.
[mono.git] / mcs / mcs / rootcontext.cs
index 18830c78c0acaf43e3813fae506ec3dad52fd08c..8ee0ce47a95f61bdac7dd8f8a4b3e85c78e0bb82 100644 (file)
@@ -12,7 +12,7 @@
 // Copyright 2004-2008 Novell, Inc
 
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
@@ -23,8 +23,8 @@ namespace Mono.CSharp {
        {
                ISO_1           = 1,
                ISO_2           = 2,
-               V_3                     = 3,
-               V_4                     = 4,
+               V_3             = 3,
+               V_4             = 4,
                Future          = 100,
 
                Default         = LanguageVersion.V_4,
@@ -48,6 +48,7 @@ namespace Mono.CSharp {
                public static bool VerifyClsCompliance = true;
                public static bool Optimize = true;
                public static LanguageVersion Version;
+               public static bool EnhancedWarnings;
 
                public static MetadataVersion MetadataCompatibilityVersion;
 
@@ -114,27 +115,18 @@ namespace Mono.CSharp {
                // This hashtable contains all of the #definitions across the source code
                // it is used by the ConditionalAttribute handler.
                //
-               static ArrayList AllDefines;
+               static List<string> 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 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;
-
                //
                // Holds a reference to the Private Implementation Details
                // class.
                //
-               static ArrayList helper_classes;
+               static List<TypeBuilder> helper_classes;
                
                static TypeBuilder impl_details_class;
 
+               public static List<Enum> hack_corlib_enums = new List<Enum> ();
+
                //
                // Constructor
                //
@@ -150,10 +142,12 @@ namespace Mono.CSharp {
                
                public static void Reset (bool full)
                {
-                       if (full)
-                               root = null;
+                       impl_details_class = null;
+                       helper_classes = null;
+
+                       if (!full)
+                               return;
                        
-                       type_container_resolve_order = new ArrayList ();
                        EntryPoint = null;
                        Checked = false;
                        Unsafe = false;
@@ -179,7 +173,7 @@ namespace Mono.CSharp {
                        //
                        // Setup default defines
                        //
-                       AllDefines = new ArrayList ();
+                       AllDefines = new List<string> ();
                        AddConditional ("__MonoCS__");
                }
 
@@ -200,11 +194,6 @@ namespace Mono.CSharp {
                        set { root = value; }
                }
 
-               public static void RegisterOrder (TypeContainer tc)
-               {
-                       type_container_resolve_order.Add (tc);
-               }
-               
                // <remarks>
                //   This function is used to resolve the hierarchy tree.
                //   It processes interfaces, structs and classes in that order.
@@ -227,10 +216,50 @@ namespace Mono.CSharp {
 
                        foreach (TypeContainer tc in root.Types)
                                tc.DefineType ();
+               }
 
-                       if (root.Delegates != null)
-                               foreach (Delegate d in root.Delegates) 
-                                       d.DefineType ();
+               static void HackCorlib ()
+               {
+                       if (StdLib)
+                               return;
+
+                       //
+                       // 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 };
+
+                       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;
+                       }
+
+                       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);
+               }
+
+               static void HackCorlibEnums ()
+               {
+                       if (StdLib)
+                               return;
+
+                       // 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 ();
                }
 
                // <summary>
@@ -243,44 +272,30 @@ namespace Mono.CSharp {
                //   methods, fields, etc) we need to "Define" them before we
                //   can save the Assembly
                // </remarks>
-               static public void CloseTypes ()
+               static public void CloseTypes (CompilerContext ctx)
                {
-                       //
-                       // 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 ();
-                               }
-                       }
+                       HackCorlibEnums ();
 
-                       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 <PrivateImplementationDetails> class, close it
                        //
                        if (helper_classes != null){
+                               var cg = ctx.PredefinedAttributes.CompilerGenerated;
                                foreach (TypeBuilder type_builder in helper_classes) {
-                                       PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (type_builder);
+                                       cg.EmitAttribute (type_builder);
                                        type_builder.CreateType ();
                                }
                        }
                        
-                       type_container_resolve_order = null;
                        helper_classes = null;
-                       //root = null;
-                       TypeManager.CleanUp ();
                }
 
                /// <summary>
@@ -290,33 +305,11 @@ namespace Mono.CSharp {
                public static void RegisterCompilerGeneratedType (TypeBuilder helper_class)
                {
                        if (helper_classes == null)
-                               helper_classes = new ArrayList ();
+                               helper_classes = new List<TypeBuilder> ();
 
                        helper_classes.Add (helper_class);
                }
                
-               static public DeclSpace PopulateCoreType (TypeContainer root, string name)
-               {
-                       DeclSpace ds = (DeclSpace) root.GetDefinition (name);
-                       // Core type was imported
-                       if (ds == null)
-                               return null;
-
-                       ds.Define ();
-                       return ds;
-               }
-               
-               static public void BootCorlib_PopulateCoreTypes ()
-               {
-                       // Clear -nostdlib flag when object type is imported
-                       if (PopulateCoreType (root, "System.Object") == null)
-                               RootContext.StdLib = true;
-
-                       PopulateCoreType (root, "System.ValueType");
-                       PopulateCoreType (root, "System.Attribute");
-                       PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
-               }
-               
                // <summary>
                //   Populates the structs and classes with fields and methods
                // </summary>
@@ -325,52 +318,37 @@ namespace Mono.CSharp {
                // have been defined through `ResolveTree' 
                static public void PopulateTypes ()
                {
-
-                       if (type_container_resolve_order != null){
-                               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);
-                                       }
+                       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 delegates = root.Delegates;
-                       if (delegates != null){
-                               foreach (Delegate d in delegates)
-                                       d.Define ();
-                       }
-
-                       //
-                       // 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);
-                       }
                }
 
                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 (RootContext.ToplevelTypes.Compiler.Report.Errors > 0)
-                                       return;
+                       HackCorlib ();
 
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.VerifyMembers ();
-                       }
-                       
-                       if (root.Delegates != null) {
-                               foreach (Delegate d in root.Delegates)
-                                       d.Emit ();
-                       }                       
+                       foreach (TypeContainer tc in ToplevelTypes.Types)
+                               tc.EmitType ();
+
+                       if (ToplevelTypes.Compiler.Report.Errors > 0)
+                               return;
+
+                       foreach (TypeContainer tc in ToplevelTypes.Types)
+                               tc.VerifyMembers ();
+
+                       if (root.CompilerGeneratedClasses != null)
+                               foreach (CompilerGeneratedClass c in root.CompilerGeneratedClasses)
+                                       c.EmitType ();
 
                        CodeGen.Assembly.Emit (root);
                        root.Emit ();
@@ -409,7 +387,7 @@ namespace Mono.CSharp {
                                impl_details_class = ToplevelTypes.Builder.DefineType (
                                        "<PrivateImplementationDetails>",
                                         TypeAttributes.NotPublic,
-                                        TypeManager.object_type);
+                                        TypeManager.object_type.GetMetaInfo ());
                                 
                                RegisterCompilerGeneratedType (impl_details_class);
                        }
@@ -420,13 +398,5 @@ namespace Mono.CSharp {
                        
                        return fb;
                }
-
-               public static void CheckUnsafeOption (Location loc, Report Report)
-               {
-                       if (!Unsafe) {
-                               Report.Error (227, loc, 
-                                       "Unsafe code requires the `unsafe' command line option to be specified");
-                       }
-               }
        }
 }