2002-03-06 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / typemanager.cs
index dc50afcf4007cda7f04852119f30c9eecf0486c8..6527047fdb87834e5a60acb60304580dbea10f7c 100755 (executable)
@@ -30,6 +30,7 @@ public class TypeManager {
        static public Type float_type;
        static public Type double_type;
        static public Type char_type;
+       static public Type char_ptr_type;
        static public Type short_type;
        static public Type decimal_type;
        static public Type bool_type;
@@ -55,8 +56,12 @@ public class TypeManager {
        static public Type runtime_field_handle_type;
        static public Type attribute_usage_type;
        static public Type dllimport_type;
+       static public Type unverifiable_code_type;
        static public Type methodimpl_attr_type;
        static public Type param_array_type;
+       static public Type void_ptr_type;
+
+       static public Type [] NoTypes;
        
        //
        // Internal, not really used outside
@@ -79,6 +84,7 @@ public class TypeManager {
        static public MethodInfo int_getlength_int;
        static public MethodInfo delegate_combine_delegate_delegate;
        static public MethodInfo delegate_remove_delegate_delegate;
+       static public MethodInfo int_get_offset_to_string_data;
        
        //
        // The attribute constructors.
@@ -90,13 +96,13 @@ public class TypeManager {
        //   (either because it is the default or the user used the
        //   -r command line option)
        // </remarks>
-       ArrayList assemblies;
+       Assembly [] assemblies;
 
        // <remarks>
        //  Keeps a list of module builders. We used this to do lookups
        //  on the modulebuilder using GetType -- needed for arrays
        // </remarks>
-       ArrayList modules;
+       ModuleBuilder [] modules;
 
        // <remarks>
        //   This is the type_cache from the assemblies to avoid
@@ -155,8 +161,8 @@ public class TypeManager {
 
        public TypeManager ()
        {
-               assemblies = new ArrayList ();
-               modules = new ArrayList ();
+               assemblies = null;
+               modules = null;
                user_types = new ArrayList ();
                types = new Hashtable ();
                typecontainers = new Hashtable ();
@@ -172,6 +178,7 @@ public class TypeManager {
                method_internal_params = new PtrHashtable ();
                builder_to_container = new PtrHashtable ();
                type_interface_cache = new PtrHashtable ();
+               NoTypes = new Type [0];
        }
 
        public void AddUserType (string name, TypeBuilder t)
@@ -244,7 +251,13 @@ public class TypeManager {
        /// </summary>
        public void AddAssembly (Assembly a)
        {
-               assemblies.Add (a);
+               int top = assemblies != null ? assemblies.Length : 0;
+               Assembly [] n = new Assembly [top + 1];
+
+               if (assemblies != null)
+                       assemblies.CopyTo (n, 0);
+               n [top] = a;
+               assemblies = n;
        }
 
        /// <summary>
@@ -252,7 +265,13 @@ public class TypeManager {
        /// </summary>
        public void AddModule (ModuleBuilder mb)
        {
-               modules.Add (mb);
+               int top = modules != null ? modules.Length : 0;
+               ModuleBuilder [] n = new ModuleBuilder [top + 1];
+
+               if (modules != null)
+                       modules.CopyTo (n, 0);
+               n [top] = mb;
+               modules = n;
        }
 
        /// <summary>
@@ -327,6 +346,8 @@ public class TypeManager {
                        return "string";
                else if (t == object_type)
                        return "object";
+               else if (t == void_type)
+                       return "void";
                else
                        return t.FullName;
        }
@@ -390,6 +411,7 @@ public class TypeManager {
                byte_type     = CoreLookupType ("System.Byte");
                sbyte_type    = CoreLookupType ("System.SByte");
                char_type     = CoreLookupType ("System.Char");
+               char_ptr_type = CoreLookupType ("System.Char*");
                short_type    = CoreLookupType ("System.Int16");
                ushort_type   = CoreLookupType ("System.UInt16");
                decimal_type  = CoreLookupType ("System.Decimal");
@@ -419,6 +441,10 @@ public class TypeManager {
                dllimport_type       = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
                methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
                param_array_type     = CoreLookupType ("System.ParamArrayAttribute");
+
+               unverifiable_code_type = CoreLookupType ("System.Security.UnverifiableCodeAttribute");
+
+               void_ptr_type        = CoreLookupType ("System.Void*");
                
                //
                // Now load the default methods that we use.
@@ -456,6 +482,8 @@ public class TypeManager {
                        ienumerator_type, "MoveNext", void_arg);
                void_dispose_void = GetMethod (
                        idisposable_type, "Dispose", void_arg);
+               int_get_offset_to_string_data = GetMethod (
+                       runtime_helpers_type, "get_OffsetToStringData", void_arg);
 
                //
                // object arguments
@@ -626,18 +654,20 @@ public class TypeManager {
                return (Const) builder_to_constant [fb];
        }
        
-       //
-       // Gigantic work around for stupidity in System.Reflection.Emit follows
-       //
-       // Since System.Reflection.Emit can not return MethodBase.GetParameters
-       // for anything which is dynamic, and we need this in a number of places,
-       // we register this information here, and use it afterwards.
-       //
+       /// <summary>
+       ///   Gigantic work around for missing features in System.Reflection.Emit follows.
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   Since System.Reflection.Emit can not return MethodBase.GetParameters
+       ///   for anything which is dynamic, and we need this in a number of places,
+       ///   we register this information here, and use it afterwards.
+       /// </remarks>
        static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
        {
-               if (method_arguments.Contains (mb))
-                       return false;
-               
+               if (args == null)
+                       args = NoTypes;
+                               
                method_arguments.Add (mb, args);
                method_internal_params.Add (mb, ip);
                
@@ -646,8 +676,6 @@ public class TypeManager {
        
        static public InternalParameters LookupParametersByBuilder (MethodBase mb)
        {
-               object o = method_arguments [mb];
-
                if (! (mb is ConstructorBuilder || mb is MethodBuilder))
                        return null;
                
@@ -878,6 +906,28 @@ public class TypeManager {
                }
                throw new Exception ("Unhandled typecode in enum" + tc);
        }
+
+       /// <summary>
+       ///   Utility function that can be used to probe whether a type
+       ///   is managed or not.  
+       /// </summary>
+       public static bool VerifyUnManaged (Type t, Location loc)
+       {
+               if (t.IsValueType){
+                       //
+                       // FIXME: this is more complex, we actually need to
+                       // make sure that the type does not contain any
+                       // classes itself
+                       //
+                       return true;
+               }
+
+               Report.Error (
+                       208, loc,
+                       "Cannot take the address or size of a variable of a managed type ('" +
+                       CSharpName (t) + "')");
+               return false;   
+       }
        
        /// <summary>
        ///   Returns the name of the indexer in a given type.
@@ -907,8 +957,10 @@ public class TypeManager {
                                foreach (Attribute a in asec.Attributes) {
                                        if (a.Name.IndexOf ("DefaultMember") != -1) {
                                                ArrayList pos_args = (ArrayList) a.Arguments [0];
+                                               Expression e = ((Argument) pos_args [0]).expr;
 
-                                               return (string) pos_args [0];
+                                               if (e is StringConstant)
+                                                       return ((StringConstant) e).Value;
                                        }
                                }
                        }
@@ -928,6 +980,13 @@ public class TypeManager {
                return "Item";
        }
 
+       public static void MakePinned (LocalBuilder builder)
+       {
+               //
+               // FIXME: Flag the "LocalBuilder" type as being
+               // pinned.  Figure out API.
+               //
+       }
 }
 
 }