* Makefile (centum_tests): Add Mono.Security and
[mono.git] / mcs / gmcs / rootcontext.cs
old mode 100755 (executable)
new mode 100644 (file)
index 9c1c20c..10b5bc8
@@ -7,15 +7,23 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 
 using System;
 using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
+using System.Xml;
 
 namespace Mono.CSharp {
 
+       public enum LanguageVersion
+       {
+               Default = 0,
+               ISO_1   = 1
+       }
+
        public class RootContext {
 
                //
@@ -29,30 +37,23 @@ namespace Mono.CSharp {
                //
                public static Hashtable AllDefines = new Hashtable ();
                
-               //
-               // The list of global attributes (those that target the assembly)
-               //
-               static Hashtable global_attributes = new Hashtable ();
-               
                //
                // 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 = true;
+               public static bool StdLib;
 
                //
                // 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 interface_resolve_order;
-               static ArrayList attribute_types;
 
                //
                // Holds a reference to the Private Implementation Details
@@ -62,20 +63,66 @@ namespace Mono.CSharp {
                
                static TypeBuilder impl_details_class;
 
-               public static int WarningLevel = 2;
+               public static int WarningLevel;
+
+               public static Target Target;
+               public static string TargetExt = ".exe";
+
+               public static bool VerifyClsCompliance = true;
+
+               /// <summary>
+               /// Holds /optimize option
+               /// </summary>
+               public static bool Optimize = true;
+
+               public static LanguageVersion Version;
 
                //
-               // If set, enable C# version 2 features
+               // We keep strongname related info here because
+               // it's also used as complier options from CSC 8.x
                //
-               public static bool V2;
+               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;
+
                //
                // Constructor
                //
                static RootContext ()
+               {
+                       Reset ();
+               }
+
+               public static void Reset ()
                {
                        tree = new Tree ();
-                       interface_resolve_order = new ArrayList ();
                        type_container_resolve_order = new ArrayList ();
+                       EntryPoint = null;
+                       WarningLevel = 3;
+                       Checked = false;
+                       Unsafe = false;
+                       StdLib = true;
+                       StrongNameKeyFile = null;
+                       StrongNameKeyContainer = null;
+                       StrongNameDelaySign = false;
+                       MainClass = null;
+                       Target = Target.Exe;
+                       Version = LanguageVersion.Default;
+                       Documentation = null;
+                       impl_details_class = null;
+               }
+
+               public static bool NeedsEntryPoint {
+                       get {
+                               return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe;
+                       }
                }
 
                static public Tree Tree {
@@ -84,43 +131,21 @@ namespace Mono.CSharp {
                        }
                }
 
-               static public string MainClass;
-               
-               public static void RegisterOrder (Interface iface)
-               {
-                       interface_resolve_order.Add (iface);
-               }
-               
                public static void RegisterOrder (TypeContainer tc)
                {
                        type_container_resolve_order.Add (tc);
                }
-
-               public static void RegisterAttribute (TypeContainer tc)
-               {
-                       if (attribute_types == null)
-                               attribute_types = new ArrayList ();
-                       
-                       attribute_types.Add (tc);
-               }
                
                // 
                // The default compiler checked state
                //
-               static public bool Checked = false;
+               static public bool Checked;
 
                //
                // Whether to allow Unsafe code
                //
-               static public bool Unsafe = false;
+               static public bool Unsafe;
                
-               static string MakeFQN (string nsn, string name)
-               {
-                       if (nsn == "")
-                               return name;
-                       return String.Concat (nsn, ".", name);
-               }
-
                // <remarks>
                //   This function is used to resolve the hierarchy tree.
                //   It processes interfaces, structs and classes in that order.
@@ -130,13 +155,6 @@ namespace Mono.CSharp {
                // </remarks>
                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 ();
-                       
                        //
                        // Interfaces are processed next, as classes and
                        // structs might inherit from an object or implement
@@ -147,7 +165,7 @@ namespace Mono.CSharp {
 
                        ArrayList ifaces = root.Interfaces;
                        if (ifaces != null){
-                               foreach (Interface i in ifaces) 
+                               foreach (TypeContainer i in ifaces) 
                                        i.DefineType ();
                        }
 
@@ -258,7 +276,7 @@ namespace Mono.CSharp {
                        object o = root.GetDefinition (name);
                        if (o == null){
                                Report.Error (518, "The predefined type `" + name + "' is not defined");
-                               Environment.Exit (0);
+                               return;
                        }
 
                        if (!(o is Delegate)){
@@ -280,6 +298,7 @@ namespace Mono.CSharp {
                        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",
@@ -293,9 +312,16 @@ namespace Mono.CSharp {
                                "System.IDisposable",
                                
                                "System.Runtime.Serialization.ISerializable",
+                               "System.Runtime.InteropServices._Exception",
 
                                "System.Reflection.IReflect",
-                               "System.Reflection.ICustomAttributeProvider"
+                               "System.Reflection.ICustomAttributeProvider",
+
+                               //
+                               // Generic types
+                               //
+                               "System.Collections.Generic.IEnumerator`1",
+                               "System.Collections.Generic.IEnumerable`1",
                        };
 
                        foreach (string iname in interfaces_first_stage)
@@ -325,8 +351,11 @@ namespace Mono.CSharp {
                                "System.Char",    "System.Boolean",
                                "System.Decimal", "System.Void",
                                "System.RuntimeFieldHandle",
+                               "System.RuntimeArgumentHandle",
                                "System.RuntimeTypeHandle",
-                               "System.IntPtr"
+                               "System.IntPtr",
+                               "System.TypedReference",
+                               "System.ArgIterator"
                        };
                        
                        foreach (string cname in structs_second_stage)
@@ -336,9 +365,13 @@ namespace Mono.CSharp {
                        // 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",
+                               "System.Activator",
 
                                //
                                // These are not really important in the order, but they
@@ -352,27 +385,40 @@ namespace Mono.CSharp {
                                "System.Runtime.InteropServices.DllImportAttribute",
                                "System.Runtime.CompilerServices.MethodImplAttribute",
                                "System.Runtime.InteropServices.MarshalAsAttribute",
+                               "System.Runtime.CompilerServices.NewConstraintAttribute",
+                               "System.Runtime.CompilerServices.CompilerGeneratedAttribute",
+                               "System.Runtime.CompilerServices.FixedBufferAttribute",
                                "System.Diagnostics.ConditionalAttribute",
                                "System.ObsoleteAttribute",
                                "System.ParamArrayAttribute",
+                               "System.CLSCompliantAttribute",
                                "System.Security.UnverifiableCodeAttribute",
-                               "System.Runtime.CompilerServices.IndexerNameAttribute",
+                               "System.Security.Permissions.SecurityAttribute",
+                               "System.Runtime.CompilerServices.DecimalConstantAttribute",
                                "System.Runtime.InteropServices.InAttribute",
-                               "System.InvalidOperationException"
-
+                               "System.Runtime.InteropServices.OutAttribute",
+                               "System.Runtime.InteropServices.StructLayoutAttribute",
+                               "System.Runtime.InteropServices.FieldOffsetAttribute",
+                               "System.Runtime.InteropServices.DefaultCharSetAttribute",
+                               "System.InvalidOperationException",
+                               "System.NotSupportedException",
+                               "System.MarshalByRefObject",
+                               "System.Security.CodeAccessPermission",
+                               "System.Runtime.CompilerServices.RequiredAttributeAttribute"
                        };
 
-                       // 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_ResolveStruct (root, "System.Nullable`1");
+
                        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);
                }
                        
                // <summary>
@@ -389,19 +435,10 @@ namespace Mono.CSharp {
                {
                        TypeContainer root = Tree.Types;
                        
-                       ArrayList ifaces = root.Interfaces;
-
                        if (root.Enums != null)
                                foreach (Enum en in root.Enums)
                                        en.CloseType ();
 
-                       if (attribute_types != null)
-                               foreach (TypeContainer tc in attribute_types)
-                                       tc.CloseType ();
-                       
-                       foreach (Interface iface in interface_resolve_order)
-                               iface.CloseType ();
-
                        //
                        // We do this in two passes, first we close the structs,
                        // then the classes, because it seems the code needs it this
@@ -409,13 +446,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 is Struct && tc.Parent == tree.Types){
+                               if (tc.Kind == Kind.Struct && tc.Parent == tree.Types){
                                        tc.CloseType ();
                                }
                        }
 
                        foreach (TypeContainer tc in type_container_resolve_order){
-                               if (!(tc is Struct && tc.Parent == tree.Types))
+                               if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types))
                                        tc.CloseType ();                                        
                        }
                        
@@ -428,135 +465,30 @@ namespace Mono.CSharp {
                        // If we have a <PrivateImplementationDetails> class, close it
                        //
                        if (helper_classes != null){
-                               foreach (TypeBuilder type_builder in helper_classes)
+                               foreach (TypeBuilder type_builder in helper_classes) {
+                                       type_builder.SetCustomAttribute (TypeManager.compiler_generated_attr);
                                        type_builder.CreateType ();
+                               }
                        }
+                       
+                       type_container_resolve_order = null;
+                       helper_classes = null;
+                       //tree = null;
+                       TypeManager.CleanUp ();
                }
 
                /// <summary>
                ///   Used to register classes that need to be closed after all the
                ///   user defined classes
                /// </summary>
-               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)
-               {
-                       Type t;
-
-                       //
-                       // Try in the current namespace and all its implicit parents
-                       //
-                       for (NamespaceEntry ns = ds.Namespace; ns != null; ns = ns.ImplicitParent) {
-                               object result = ns.Lookup (ds, name, loc);
-                               if (result == null)
-                                       continue;
-
-                               if (result is Type)
-                                       return (Type) result;
-
-                               return null;
-                       }
-
-                       return null;
+                       helper_classes.Add (helper_class);
                }
                
-               //
-               // 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];
-                               if (t != null)
-                                       return t;
-                       } 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){
-                                       Type current_type = containing_ds.TypeBuilder;
-                                       
-                                       while (current_type != null) {
-                                               //
-                                               // 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 (t != null){
-                                       ds.Cache [name] = t;
-                                       return t;
-                               }
-                       }
-
-                       if (!silent)
-                               Report.Error (246, loc, "Cannot find type `"+name+"'");
-                       
-                       return null;
-               }
-
-               // <summary>
-               //   This is the silent version of LookupType, you can use this
-               //   to `probe' for a type
-               // </summary>
-               static public Type LookupType (TypeContainer tc, string name, Location loc)
-               {
-                       return LookupType (tc, name, true, loc);
-               }
-
-               static public bool IsNamespace (string name)
-               {
-                       Namespace ns;
-
-                       if (tree.Namespaces != null){
-                               ns = (Namespace) tree.Namespaces [name];
-
-                               if (ns != null)
-                                       return true;
-                       }
-
-                       return false;
-               }
-
                static void Report1530 (Location loc)
                {
                        Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
@@ -567,7 +499,7 @@ namespace Mono.CSharp {
                        DeclSpace ds = (DeclSpace) root.GetDefinition (name);
 
                        ds.DefineMembers (root);
-                       ds.Define (root);
+                       ds.Define ();
                }
                
                static public void BootCorlib_PopulateCoreTypes ()
@@ -577,6 +509,7 @@ namespace Mono.CSharp {
                        PopulateCoreType (root, "System.Object");
                        PopulateCoreType (root, "System.ValueType");
                        PopulateCoreType (root, "System.Attribute");
+                       PopulateCoreType (root, "System.Runtime.CompilerServices.IndexerNameAttribute");
                }
                
                // <summary>
@@ -589,19 +522,6 @@ namespace Mono.CSharp {
                {
                        TypeContainer root = Tree.Types;
 
-                       if (attribute_types != null)
-                               foreach (TypeContainer tc in attribute_types)
-                                       tc.DefineMembers (root);
-                       
-                       if (interface_resolve_order != null){
-                               foreach (Interface iface in interface_resolve_order)
-                                       if ((iface.ModFlags & Modifiers.NEW) == 0)
-                                               iface.DefineMembers (root);
-                                       else
-                                               Report1530 (iface.Location);
-                       }
-
-
                        if (type_container_resolve_order != null){
                                if (RootContext.StdLib){
                                        foreach (TypeContainer tc in type_container_resolve_order)
@@ -611,8 +531,9 @@ namespace Mono.CSharp {
                                                // 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.Attribute") ||
+                                                       (tc.Name == "System.ValueType") ||
+                                                       (tc.Name == "System.Runtime.CompilerServices.IndexerNameAttribute")))
                                                continue;
 
                                                tc.DefineMembers (root);
@@ -637,6 +558,15 @@ namespace Mono.CSharp {
                                        else
                                                Report1530 (en.Location);
                        }
+
+                       //
+                       // 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);
+                       }
                }
 
                //
@@ -656,17 +586,6 @@ namespace Mono.CSharp {
                {
                        TypeContainer root = Tree.Types;
 
-                       if (attribute_types != null)
-                               foreach (TypeContainer tc in attribute_types)
-                                       tc.Define (root);
-                       
-                       if (interface_resolve_order != null){
-                               foreach (Interface iface in interface_resolve_order)
-                                       if ((iface.ModFlags & Modifiers.NEW) == 0)
-                                               iface.Define (root);
-                       }
-
-
                        if (type_container_resolve_order != null){
                                foreach (TypeContainer tc in type_container_resolve_order) {
                                        // When compiling corlib, these types have already been
@@ -674,11 +593,12 @@ namespace Mono.CSharp {
                                        if (!RootContext.StdLib &&
                                            ((tc.Name == "System.Object") ||
                                             (tc.Name == "System.Attribute") ||
-                                            (tc.Name == "System.ValueType")))
+                                            (tc.Name == "System.ValueType") ||
+                                            (tc.Name == "System.Runtime.CompilerServices.IndexerNameAttribute")))
                                                continue;
 
                                        if ((tc.ModFlags & Modifiers.NEW) == 0)
-                                               tc.Define (root);
+                                               tc.Define ();
                                }
                        }
 
@@ -686,55 +606,36 @@ namespace Mono.CSharp {
                        if (delegates != null){
                                foreach (Delegate d in delegates)
                                        if ((d.ModFlags & Modifiers.NEW) == 0)
-                                               d.Define (root);
+                                               d.Define ();
                        }
 
                        ArrayList enums = root.Enums;
                        if (enums != null){
                                foreach (Enum en in enums)
                                        if ((en.ModFlags & Modifiers.NEW) == 0)
-                                               en.Define (root);
+                                               en.Define ();
                        }
                }
 
                static public void EmitCode ()
                {
-                       //
-                       // Because of the strange way in which we do things, global
-                       // attributes must be processed first.
-                       //
-                       if (global_attributes.Count > 0){
-                               AssemblyBuilder ab = CodeGen.AssemblyBuilder;
-                               TypeContainer dummy = new TypeContainer (null, "", new Location (-1));
-                               EmitContext temp_ec = new EmitContext (
-                                       dummy, Mono.CSharp.Location.Null, null, null, 0, false);
-                       
-                               foreach (DictionaryEntry de in global_attributes){
-                                       NamespaceEntry ns = (NamespaceEntry) de.Key;
-                                       Attributes attrs = (Attributes) de.Value;
-                                       
-                                       dummy.Namespace = ns;
-                                       Attribute.ApplyAttributes (temp_ec, ab, ab, attrs);
-                               }
+                       if (Tree.Types.Enums != null) {
+                               foreach (Enum e in Tree.Types.Enums)
+                                       e.Emit ();
                        }
-                        
-                       if (attribute_types != null)
-                               foreach (TypeContainer tc in attribute_types)
-                                       tc.Emit ();
-
-                        if (interface_resolve_order != null){
-                               foreach (Interface iface in interface_resolve_order)
-                                        iface.Emit (Tree.Types);
-                       }                        
-                       
+
                        if (type_container_resolve_order != null) {
                                foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.EmitConstants ();
-                               
+                                       tc.EmitType ();
+
                                foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.Emit ();
+                                       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
@@ -743,17 +644,8 @@ namespace Mono.CSharp {
                        if (EmitCodeHook != null)
                                EmitCodeHook ();
 
-                       
-                       if (Unsafe) {
-                               if (TypeManager.unverifiable_code_ctor == null) {
-                                       Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
-                                       return;
-                               }
-                               
-                               CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor,
-                                                                                       new object [0]);
-                               CodeGen.ModuleBuilder.SetCustomAttribute (cb);
-                       }
+                       CodeGen.Assembly.Emit (Tree.Types);
+                       CodeGen.Module.Emit (Tree.Types);
                }
                
                //
@@ -789,15 +681,14 @@ namespace Mono.CSharp {
                static public FieldBuilder MakeStaticData (byte [] data)
                {
                        FieldBuilder fb;
-                       int size = data.Length;
                        
                        if (impl_details_class == null){
-                               impl_details_class = CodeGen.ModuleBuilder.DefineType (
+                               impl_details_class = CodeGen.Module.Builder.DefineType (
                                        "<PrivateImplementationDetails>",
                                         TypeAttributes.NotPublic,
                                         TypeManager.object_type);
                                 
-                               RegisterHelperClass (impl_details_class);
+                               RegisterCompilerGeneratedType (impl_details_class);
                        }
 
                        fb = impl_details_class.DefineInitializedData (
@@ -806,21 +697,6 @@ namespace Mono.CSharp {
                        
                        return fb;
                }
-
-               //
-               // Adds a global attribute that was declared in `container', 
-               // the attribute is in `attr', and it was defined at `loc'
-               //
-               static public void AddGlobalAttributeSection (TypeContainer container, AttributeSection attr)
-               {
-                       NamespaceEntry ns = container.Namespace;
-                       Attributes a = (Attributes) global_attributes [ns];
-
-                       if (a == null)
-                               global_attributes [ns] = new Attributes (attr);
-                       else
-                               a.AddAttributeSection (attr);
-               }
        }
 }