2002-03-06 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / typemanager.cs
index 570f3f2fb34fb01808f65ba3909a37d175502232..6527047fdb87834e5a60acb60304580dbea10f7c 100755 (executable)
@@ -1,5 +1,5 @@
 //
-// typegen.cs: type generation 
+// typemanager.cs: C# type manager
 //
 // Author: Miguel de Icaza (miguel@gnu.org)
 //
@@ -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;
@@ -38,6 +39,7 @@ public class TypeManager {
        static public Type ushort_type;
        static public Type enum_type;
        static public Type delegate_type;
+       static public Type multicast_delegate_type;
        static public Type void_type;
        static public Type enumeration_type;
        static public Type array_type;
@@ -54,7 +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
@@ -75,6 +82,9 @@ public class TypeManager {
        static public MethodInfo void_monitor_exit_object;
        static public MethodInfo void_initializearray_array_fieldhandle;
        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.
@@ -86,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
@@ -115,7 +125,7 @@ public class TypeManager {
        // <remarks>
        //   Keeps a mapping between TypeBuilders and their TypeContainers
        // </remarks>
-       static Hashtable builder_to_container;
+       static PtrHashtable builder_to_container;
 
        // <remarks>
        //   Maps MethodBase.RuntimeTypeHandle to a Type array that contains
@@ -129,7 +139,7 @@ public class TypeManager {
        // <remarks>
        static Hashtable method_internal_params;
 
-       static Hashtable builder_to_interface;
+       static PtrHashtable builder_to_interface;
 
        // <remarks>
        //  Keeps track of delegate types
@@ -151,30 +161,26 @@ 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 ();
-               builder_to_interface = new Hashtable ();
-               builder_to_delegate = new Hashtable ();
-               builder_to_enum  = new Hashtable ();
-               builder_to_attr = new Hashtable ();
+               builder_to_interface = new PtrHashtable ();
+               builder_to_delegate = new PtrHashtable ();
+               builder_to_enum  = new PtrHashtable ();
+               builder_to_attr = new PtrHashtable ();
        }
 
        static TypeManager ()
        {
-               method_arguments = new Hashtable ();
-               method_internal_params = new Hashtable ();
-               builder_to_container = new Hashtable ();
-               type_interface_cache = new Hashtable ();
+               method_arguments = new PtrHashtable ();
+               method_internal_params = new PtrHashtable ();
+               builder_to_container = new PtrHashtable ();
+               type_interface_cache = new PtrHashtable ();
+               NoTypes = new Type [0];
        }
 
-       static string MakeKey (Type t)
-       {
-               return t.FullName + t.GetHashCode ();
-       }
-       
        public void AddUserType (string name, TypeBuilder t)
        {
                types.Add (name, t);
@@ -184,7 +190,7 @@ public class TypeManager {
        public void AddUserType (string name, TypeBuilder t, TypeContainer tc)
        {
                AddUserType (name, t);
-               builder_to_container.Add (MakeKey (t), tc);
+               builder_to_container.Add (t, tc);
                typecontainers.Add (name, tc);
        }
 
@@ -197,18 +203,18 @@ public class TypeManager {
        public void AddEnumType (string name, TypeBuilder t, Enum en)
        {
                types.Add (name, t);
-               builder_to_enum.Add (MakeKey (t), en);
+               builder_to_enum.Add (t, en);
        }
 
        public void AddUserInterface (string name, TypeBuilder t, Interface i)
        {
                AddUserType (name, t);
-               builder_to_interface.Add (MakeKey (t), i);
+               builder_to_interface.Add (t, i);
        }
 
        public void RegisterAttrType (Type t, TypeContainer tc)
        {
-               builder_to_attr.Add (MakeKey (t), tc);
+               builder_to_attr.Add (t, tc);
        }
                
        /// <summary>
@@ -217,12 +223,12 @@ public class TypeManager {
        /// </summary>
        public static TypeContainer LookupTypeContainer (Type t)
        {
-               return (TypeContainer) builder_to_container [MakeKey (t)];
+               return (TypeContainer) builder_to_container [t];
        }
 
        public Interface LookupInterface (Type t)
        {
-               return (Interface) builder_to_interface [MakeKey (t)];
+               return (Interface) builder_to_interface [t];
        }
 
        public static Delegate LookupDelegate (Type t)
@@ -232,12 +238,12 @@ public class TypeManager {
 
        public static Enum LookupEnum (Type t)
        {
-               return (Enum) builder_to_enum [MakeKey (t)];
+               return (Enum) builder_to_enum [t];
        }
        
        public static TypeContainer LookupAttr (Type t)
        {
-               return (TypeContainer) builder_to_attr [MakeKey (t)];
+               return (TypeContainer) builder_to_attr [t];
        }
        
        /// <summary>
@@ -245,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>
@@ -253,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>
@@ -328,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;
        }
@@ -340,8 +360,10 @@ public class TypeManager {
        {
                Type t = LookupType (name);
 
-               if (t == null)
-                       throw new Exception ("Can not find core type " + name);
+               if (t == null){
+                       Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
+                       Environment.Exit (0);
+               }
 
                return t;
        }
@@ -389,12 +411,16 @@ 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");
                bool_type     = CoreLookupType ("System.Boolean");
                enum_type     = CoreLookupType ("System.Enum");
-               delegate_type = CoreLookupType ("System.MulticastDelegate");
+
+               multicast_delegate_type = CoreLookupType ("System.MulticastDelegate");
+               delegate_type           = CoreLookupType ("System.Delegate");
+
                array_type    = CoreLookupType ("System.Array");
                void_type     = CoreLookupType ("System.Void");
                type_type     = CoreLookupType ("System.Type");
@@ -413,7 +439,12 @@ public class TypeManager {
 
                attribute_usage_type = CoreLookupType ("System.AttributeUsageAttribute");
                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.
@@ -434,6 +465,13 @@ public class TypeManager {
                system_type_get_type_from_handle = GetMethod (
                        type_type, "GetTypeFromHandle", runtime_type_handle);
 
+               Type [] delegate_delegate = { delegate_type, delegate_type };
+               delegate_combine_delegate_delegate = GetMethod (
+                               delegate_type, "Combine", delegate_delegate);
+
+               delegate_remove_delegate_delegate = GetMethod (
+                               delegate_type, "Remove", delegate_delegate);
+
                //
                // Void arguments
                //
@@ -444,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
@@ -473,15 +513,52 @@ public class TypeManager {
                        param_array_type, void_arg);
                
        }
+
+       const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
        
-       public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+       public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+                                         MemberFilter filter, object criteria)
        {
-               string key = MakeKey (t);
+               //
+               // We have to take care of arrays specially, because GetType on
+               // a TypeBuilder array will return a Type, not a TypeBuilder,
+               // and we can not call FindMembers on this type.
+               //
+               if (t.IsSubclassOf (TypeManager.array_type))
+                       return TypeManager.array_type.FindMembers (mt, bf, filter, criteria);
                
-               if (!(t is TypeBuilder))
+               if (!(t is TypeBuilder)){
+                       //
+                       // Since FindMembers will not lookup both static and instance
+                       // members, we emulate this behaviour here.
+                       //
+                       if ((bf & instance_and_static) == instance_and_static){
+                               MemberInfo [] i_members = t.FindMembers (
+                                       mt, bf & ~BindingFlags.Static, filter, criteria);
+                               MemberInfo [] s_members = t.FindMembers (
+                                       mt, bf & ~BindingFlags.Instance, filter, criteria);
+
+                               int i_len = i_members.Length;
+                               int s_len = s_members.Length;
+                               if (i_len > 0 || s_len > 0){
+                                       MemberInfo [] both = new MemberInfo [i_len + s_len];
+
+                                       i_members.CopyTo (both, 0);
+                                       s_members.CopyTo (both, i_len);
+
+                                       return both;
+                               } else
+                                       return i_members;
+                       }
                        return t.FindMembers (mt, bf, filter, criteria);
+               }
 
-               Enum e = (Enum) builder_to_enum [key];
+               //
+               // FIXME: We should not have builder_to_blah everywhere,
+               // we should just have a builder_to_findmemberizable
+               // and have them implement a new ICanFindMembers interface
+               //
+               Enum e = (Enum) builder_to_enum [t];
 
                if (e != null)
                        return e.FindMembers (mt, bf, filter, criteria);
@@ -491,15 +568,15 @@ public class TypeManager {
                if (del != null)
                        return del.FindMembers (mt, bf, filter, criteria);
 
-               Interface iface = (Interface) builder_to_interface [key];
+               Interface iface = (Interface) builder_to_interface [t];
 
                if (iface != null) 
                        return iface.FindMembers (mt, bf, filter, criteria);
                
-               TypeContainer tc = (TypeContainer) builder_to_container [key];
+               TypeContainer tc = (TypeContainer) builder_to_container [t];
 
                if (tc != null)
-                       return tc.FindMembers (mt, bf, filter, criteria);
+                       return tc.FindMembers (mt, bf, filter, criteria);
 
                return null;
        }
@@ -556,20 +633,12 @@ public class TypeManager {
                }
        }
 
-       static string GetSig (MethodBase mb)
-       {
-               if (mb is MethodBuilder || mb is ConstructorBuilder)
-                       return mb.ReflectedType.FullName + ":" + ":" + mb;
-               else
-                       return mb.MethodHandle.ToString ();
-       }
-
        static Hashtable builder_to_constant;
 
        public static void RegisterConstant (FieldBuilder fb, Const c)
        {
                if (builder_to_constant == null)
-                       builder_to_constant = new Hashtable ();
+                       builder_to_constant = new PtrHashtable ();
 
                if (builder_to_constant.Contains (fb))
                        return;
@@ -585,55 +654,33 @@ public class TypeManager {
                return (Const) builder_to_constant [fb];
        }
        
-
-       static Hashtable delegate_to_data;
-       
-       public static void RegisterDelegateData (Type del_type, DictionaryEntry de)
-       {
-               if (delegate_to_data == null)
-                       delegate_to_data = new Hashtable ();
-
-               delegate_to_data.Add (del_type, de);
-       }
-       
-       public static DictionaryEntry GetDelegateData (Type t)
-       {
-               return (DictionaryEntry) delegate_to_data [t];
-       }
-
-       
-       //
-       // 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)
        {
-               string s;
-               
-               s = GetSig (mb);
-
-               if (method_arguments.Contains (s))
-                       return false;
-               
-               method_arguments.Add (s, args);
-               method_internal_params.Add (s, ip);
+               if (args == null)
+                       args = NoTypes;
+                               
+               method_arguments.Add (mb, args);
+               method_internal_params.Add (mb, ip);
                
                return true;
        }
        
        static public InternalParameters LookupParametersByBuilder (MethodBase mb)
        {
-               string sig = GetSig (mb);
-               object o = method_arguments [sig];
-
                if (! (mb is ConstructorBuilder || mb is MethodBuilder))
                        return null;
                
-               if (method_arguments.Contains (sig))
-                       return (InternalParameters) method_internal_params [sig];
+               if (method_internal_params.Contains (mb))
+                       return (InternalParameters) method_internal_params [mb];
                else
                        throw new Exception ("Argument for Method not registered" + mb);
        }
@@ -647,11 +694,8 @@ public class TypeManager {
        /// </summary>
        static public Type [] GetArgumentTypes (MethodBase mb)
        {
-               string sig = GetSig (mb);
-               object o = method_arguments [sig];
-
-               if (method_arguments.Contains (sig))
-                       return (Type []) method_arguments [sig];
+               if (method_arguments.Contains (mb))
+                       return (Type []) method_arguments [mb];
                else {
                        ParameterInfo [] pi = mb.GetParameters ();
                        int c = pi.Length;
@@ -660,7 +704,7 @@ public class TypeManager {
                        for (int i = 0; i < c; i++)
                                types [i] = pi [i].ParameterType;
 
-                       method_arguments.Add (sig, types);
+                       method_arguments.Add (mb, types);
                        return types;
                }
        }
@@ -669,13 +713,9 @@ public class TypeManager {
        //  This is a workaround the fact that GetValue is not
        //  supported for dynamic types
        // </remarks>
-       static Hashtable fields;
-
-       static public bool RegisterField (FieldBuilder fb, object value)
+       static Hashtable fields = new Hashtable ();
+       static public bool RegisterFieldValue (FieldBuilder fb, object value)
        {
-               if (fields == null)
-                       fields = new Hashtable ();
-
                if (fields.Contains (fb))
                        return false;
 
@@ -689,6 +729,55 @@ public class TypeManager {
                return fields [fb];
        }
 
+       static Hashtable fieldbuilders_to_fields = new Hashtable ();
+       static public bool RegisterField (FieldBuilder fb, Field f)
+       {
+               if (fieldbuilders_to_fields.Contains (fb))
+                       return false;
+
+               fieldbuilders_to_fields.Add (fb, f);
+               return true;
+       }
+
+       static public Field GetField (FieldInfo fb)
+       {
+               return (Field) fieldbuilders_to_fields [fb];
+       }
+       
+       static Hashtable events;
+
+       static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
+       {
+               if (events == null)
+                       events = new Hashtable ();
+
+               if (events.Contains (eb))
+                       return false;
+
+               events.Add (eb, new Pair (add, remove));
+
+               return true;
+       }
+
+       static public MethodInfo GetAddMethod (EventInfo ei)
+       {
+               if (ei is MyEventBuilder) {
+                       Pair pair = (Pair) events [ei];
+
+                       return (MethodInfo) pair.First;
+               } else
+                       return ei.GetAddMethod ();
+       }
+
+       static public MethodInfo GetRemoveMethod (EventInfo ei)
+       {
+               if (ei is MyEventBuilder) {
+                       Pair pair = (Pair) events [ei];
+
+                       return (MethodInfo) pair.Second;
+               } else
+                       return ei.GetAddMethod ();
+       }
 
        static Hashtable properties;
        
@@ -700,60 +789,146 @@ public class TypeManager {
                if (properties.Contains (pb))
                        return false;
 
-               properties.Add (pb, new DictionaryEntry (get, set));
+               properties.Add (pb, new Pair (get, set));
 
                return true;
        }
        
+       //
+       // FIXME: we need to return the accessors depending on whether
+       // they are visible or not.
+       //
        static public MethodInfo [] GetAccessors (PropertyInfo pi)
        {
                MethodInfo [] ret;
-                       
+
                if (pi is PropertyBuilder){
-                       DictionaryEntry de = (DictionaryEntry) properties [pi];
+                       Pair pair = (Pair) properties [pi];
 
                        ret = new MethodInfo [2];
-                       ret [0] = (MethodInfo) de.Key;
-                       ret [1] = (MethodInfo) de.Value;
+                       ret [0] = (MethodInfo) pair.First;
+                       ret [1] = (MethodInfo) pair.Second;
 
                        return ret;
+               } else {
+                       MethodInfo [] mi = new MethodInfo [2];
+
+                       //
+                       // Why this and not pi.GetAccessors?
+                       // Because sometimes index 0 is the getter
+                       // sometimes it is 1
+                       //
+                       mi [0] = pi.GetGetMethod (true);
+                       mi [1] = pi.GetSetMethod (true);
+
+                       return mi;
+               }
+       }
+
+       static public MethodInfo GetPropertyGetter (PropertyInfo pi)
+       {
+               if (pi is PropertyBuilder){
+                       Pair de = (Pair) properties [pi];
+
+                       return (MethodInfo) de.Second;
                } else
-                       return pi.GetAccessors ();
+                       return pi.GetSetMethod ();
        }
 
+       static public MethodInfo GetPropertySetter (PropertyInfo pi)
+       {
+               if (pi is PropertyBuilder){
+                       Pair de = (Pair) properties [pi];
+
+                       return (MethodInfo) de.First;
+               } else
+                       return pi.GetGetMethod ();
+       }
+                               
        // <remarks>
        //  The following is used to check if a given type implements an interface.
        //  The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
        // </remarks>
 
        static Hashtable type_interface_cache;
-
        public static bool ImplementsInterface (Type t, Type iface)
        {
-               Type [] interfaces = (Type []) type_interface_cache [t];
+               Type [] interfaces;
 
-               if (interfaces == null) {
-                       if (type_interface_cache.Contains (t))
-                               return false;
-                       
+               do {
                        interfaces = t.GetInterfaces ();
 
-                       type_interface_cache [t] = interfaces;
-               }
+                       for (int i = interfaces.Length; i > 0; ){
+                               i--;
+                               if (interfaces [i] == iface)
+                                       return true;
+                       }
+                       t = t.BaseType;
+               } while (t != null);
+               
+               return false;
+       }
 
-               if (interfaces == null)
-                       return false;
+       //
+       // This is needed, because enumerations from assemblies
+       // do not report their underlyingtype, but they report
+       // themselves
+       //
+       public static Type EnumToUnderlying (Type t)
+       {
+               t = t.UnderlyingSystemType;
+               if (!TypeManager.IsEnumType (t))
+                       return t;
+               
+               TypeCode tc = Type.GetTypeCode (t);
+
+               switch (tc){
+               case TypeCode.Boolean:
+                       return TypeManager.bool_type;
+               case TypeCode.Byte:
+                       return TypeManager.byte_type;
+               case TypeCode.SByte:
+                       return TypeManager.sbyte_type;
+               case TypeCode.Char:
+                       return TypeManager.char_type;
+               case TypeCode.Int16:
+                       return TypeManager.short_type;
+               case TypeCode.UInt16:
+                       return TypeManager.ushort_type;
+               case TypeCode.Int32:
+                       return TypeManager.int32_type;
+               case TypeCode.UInt32:
+                       return TypeManager.uint32_type;
+               case TypeCode.Int64:
+                       return TypeManager.int64_type;
+               case TypeCode.UInt64:
+                       return TypeManager.uint64_type;
+               }
+               throw new Exception ("Unhandled typecode in enum" + tc);
+       }
 
-               for (int i = interfaces.Length; i > 0; ) {
-                       i--;
-                       if (interfaces [i] == iface)
-                               return true;
+       /// <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;
                }
 
-               return false;
+               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.
        /// </summary>
@@ -766,24 +941,52 @@ public class TypeManager {
        public static string IndexerPropertyName (Type t)
        {
                
-               //
-               // FIXME: Replace with something that works around S.R.E failure
-               //
-#if FIXME
-               System.Attribute attr;
+               if (t is TypeBuilder) {
+                       TypeContainer tc = (TypeContainer) builder_to_container [t];
+
+                       Attributes attrs = tc.OptAttributes;
+                       
+                       if (attrs == null || attrs.AttributeSections == null)
+                               return "Item";
 
-               attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
+                       foreach (AttributeSection asec in attrs.AttributeSections) {
+
+                               if (asec.Attributes == null)
+                                       continue;
+
+                               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;
+
+                                               if (e is StringConstant)
+                                                       return ((StringConstant) e).Value;
+                                       }
+                               }
+                       }
+
+                       return "Item";
+               }
+               
+               System.Attribute attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
                
                if (attr != null)
-                       {
-                               DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
-                               
-                               return dma.MemberName;
-                       }
-#endif
+               {
+                       DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
+                       
+                       return dma.MemberName;
+               }
+
                return "Item";
        }
 
+       public static void MakePinned (LocalBuilder builder)
+       {
+               //
+               // FIXME: Flag the "LocalBuilder" type as being
+               // pinned.  Figure out API.
+               //
+       }
 }
 
 }