X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Ftypemanager.cs;h=d5060cbf04d9696e2cb71c1cb88a6af10e57798d;hb=a2f7036e7364141983f41ad7b523450fa0539527;hp=51e7fb9339df7d4a3e4edb58b3052ef176279c67;hpb=67d531a16ee371e6ae1c4ee612828b23b161206a;p=mono.git diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs old mode 100755 new mode 100644 index 51e7fb9339d..d5060cbf04d --- a/mcs/mcs/typemanager.cs +++ b/mcs/mcs/typemanager.cs @@ -55,6 +55,7 @@ public class TypeManager { static public Type delegate_type; static public Type multicast_delegate_type; static public Type void_type; + static public Type null_type; static public Type enumeration_type; static public Type array_type; static public Type runtime_handle_type; @@ -73,12 +74,12 @@ public class TypeManager { static public Type runtime_argument_handle_type; static public Type attribute_type; static public Type attribute_usage_type; + static public Type decimal_constant_attribute_type; static public Type dllimport_type; static public Type unverifiable_code_type; static public Type methodimpl_attr_type; static public Type marshal_as_attr_type; static public Type param_array_type; - static public Type guid_attr_type; static public Type void_ptr_type; static public Type indexer_name_type; static public Type exception_type; @@ -87,12 +88,27 @@ public class TypeManager { static public Type obsolete_attribute_type; static public Type conditional_attribute_type; static public Type in_attribute_type; + static public Type out_attribute_type; + static public Type anonymous_method_type; static public Type cls_compliant_attribute_type; static public Type typed_reference_type; static public Type arg_iterator_type; static public Type mbr_type; static public Type struct_layout_attribute_type; static public Type field_offset_attribute_type; + static public Type security_attr_type; + static public Type required_attr_type; + static public Type guid_attr_type; + static public Type assembly_culture_attribute_type; + + /// + /// .NET 2.0 + /// +#if NET_2_0 + static internal Type compiler_generated_attr_type; + static internal Type fixed_buffer_attr_type; + static internal Type default_charset_type; +#endif // // An empty array of types @@ -116,6 +132,7 @@ public class TypeManager { static public TypeExpr system_asynccallback_expr; static public TypeExpr system_iasyncresult_expr; static public TypeExpr system_valuetype_expr; + static public TypeExpr system_intptr_expr; // // This is only used when compiling corlib @@ -150,7 +167,6 @@ public class TypeManager { static public MethodInfo string_concat_object_dot_dot_dot; static public MethodInfo string_isinterneted_string; static public MethodInfo system_type_get_type_from_handle; - static public MethodInfo object_getcurrent_void; static public MethodInfo bool_movenext_void; static public MethodInfo ienumerable_getenumerator_void; static public MethodInfo void_reset_void; @@ -169,6 +185,7 @@ public class TypeManager { static public MethodInfo int_array_get_lower_bound_int; static public MethodInfo int_array_get_upper_bound_int; static public MethodInfo void_array_copyto_array_int; + static public PropertyInfo ienumerator_getcurrent; // // The attribute constructors. @@ -176,10 +193,21 @@ public class TypeManager { static public ConstructorInfo object_ctor; static public ConstructorInfo cons_param_array_attribute; static public ConstructorInfo void_decimal_ctor_five_args; + static public ConstructorInfo void_decimal_ctor_int_arg; static public ConstructorInfo unverifiable_code_ctor; - static public ConstructorInfo invalid_operation_ctor; static public ConstructorInfo default_member_ctor; + static public ConstructorInfo decimal_constant_attribute_ctor; + static internal ConstructorInfo struct_layout_attribute_ctor; + static public ConstructorInfo field_offset_attribute_ctor; + /// + /// A new in C# 2.0 + /// +#if NET_2_0 + static internal CustomAttributeBuilder compiler_generated_attr; + static internal ConstructorInfo fixed_buffer_attr_ctor; +#endif + // // Holds the Array of Assemblies that have been loaded // (either because it is the default or the user used the @@ -193,26 +221,10 @@ public class TypeManager { // static Module [] modules; - // - // This is the type_cache from the assemblies to avoid - // hitting System.Reflection on every lookup. - // - static Hashtable types; - - // - // This is used to hotld the corresponding TypeContainer objects - // since we need this in FindMembers - // - static Hashtable typecontainers; - - // - // Keeps track of those types that are defined by the - // user's program - // - static ArrayList user_types; - static PtrHashtable builder_to_declspace; + static PtrHashtable builder_to_member_cache; + // // Tracks the interfaces implemented by typebuilders. We only // enter those who do implement or or more interfaces @@ -232,10 +244,14 @@ public class TypeManager { static Hashtable indexer_arguments; // - // Maybe `method_arguments' should be replaced and only - // method_internal_params should be kept? + // Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters) + // + static Hashtable method_params; + + // + // A hash table from override methods to their base virtual method. // - static Hashtable method_internal_params; + static Hashtable method_overrides; // // Keeps track of methods @@ -247,7 +263,10 @@ public class TypeManager { // Contains all public types from referenced assemblies. // This member is used only if CLS Compliance verification is required. // - public static Hashtable all_imported_types; + public static Hashtable AllClsTopLevelTypes; + + static Hashtable fieldbuilders_to_fields; + static Hashtable fields; struct Signature { public string name; @@ -259,24 +278,19 @@ public class TypeManager { // Lets get everything clean so that we can collect before generating code assemblies = null; modules = null; - types = null; - typecontainers = null; - user_types = null; builder_to_declspace = null; + builder_to_member_cache = null; builder_to_ifaces = null; method_arguments = null; indexer_arguments = null; - method_internal_params = null; + method_params = null; builder_to_method = null; fields = null; - references = null; - negative_hits = null; - builder_to_constant = null; fieldbuilders_to_fields = null; events = null; priv_fields_events = null; - properties = null; + type_hash = null; TypeHandle.CleanUp (); } @@ -349,116 +363,52 @@ public class TypeManager { system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback"); system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult"); system_valuetype_expr = new TypeLookupExpression ("System.ValueType"); + system_intptr_expr = new TypeLookupExpression ("System.IntPtr"); } static TypeManager () + { + Reset (); + + signature_filter = new MemberFilter (SignatureFilter); + InitExpressionTypes (); + } + + static public void Reset () { assemblies = new Assembly [0]; modules = null; - user_types = new ArrayList (); - - types = new Hashtable (); - typecontainers = new Hashtable (); builder_to_declspace = new PtrHashtable (); + builder_to_member_cache = new PtrHashtable (); builder_to_method = new PtrHashtable (); method_arguments = new PtrHashtable (); - method_internal_params = new PtrHashtable (); + method_params = new PtrHashtable (); + method_overrides = new PtrHashtable (); indexer_arguments = new PtrHashtable (); builder_to_ifaces = new PtrHashtable (); NoTypes = new Type [0]; NoTypeExprs = new TypeExpr [0]; - signature_filter = new MemberFilter (SignatureFilter); - InitExpressionTypes (); + fieldbuilders_to_fields = new Hashtable (); + fields = new Hashtable (); + type_hash = new DoubleHash (); } - public static void HandleDuplicate (string name, Type t) - { - Type prev = (Type) types [name]; - TypeContainer tc = builder_to_declspace [prev] as TypeContainer; - - if (tc != null){ - // - // This probably never happens, as we catch this before - // - Report.Error (-17, "The type `" + name + "' has already been defined."); - return; - } - - tc = builder_to_declspace [t] as TypeContainer; - if (tc != null){ - Report.Warning ( - 1595, "The type `" + name + "' is defined in an existing assembly;"+ - " Using the new definition from: " + tc.Location); - } else { - Report.Warning ( - 1595, "The type `" + name + "' is defined in an existing assembly;"); - } - - Report.Warning (1595, "Previously defined in: " + prev.Assembly.FullName); - - types.Remove (name); - types.Add (name, t); - } - - public static void AddUserType (string name, TypeBuilder t, TypeExpr[] ifaces) + public static void AddUserType (string name, DeclSpace ds) { - try { - types.Add (name, t); - } catch { - HandleDuplicate (name, t); - } - user_types.Add (t); - - if (ifaces != null) - builder_to_ifaces [t] = ifaces; + builder_to_declspace.Add (ds.TypeBuilder, ds); } // // This entry point is used by types that we define under the covers // - public static void RegisterBuilder (TypeBuilder tb, TypeExpr [] ifaces) + public static void RegisterBuilder (Type tb, Type [] ifaces) { if (ifaces != null) builder_to_ifaces [tb] = ifaces; - } - - public static void AddUserType (string name, TypeBuilder t, TypeContainer tc, TypeExpr [] ifaces) - { - builder_to_declspace.Add (t, tc); - typecontainers.Add (name, tc); - AddUserType (name, t, ifaces); - } - - public static void AddDelegateType (string name, TypeBuilder t, Delegate del) - { - try { - types.Add (name, t); - } catch { - HandleDuplicate (name, t); - } - - builder_to_declspace.Add (t, del); - } - - public static void AddEnumType (string name, TypeBuilder t, Enum en) - { - try { - types.Add (name, t); - } catch { - HandleDuplicate (name, t); - } - builder_to_declspace.Add (t, en); - } - - public static void AddUserInterface (string name, TypeBuilder t, Interface i, TypeExpr [] ifaces) - { - AddUserType (name, t, ifaces); - builder_to_declspace.Add (t, i); - } - + } public static void AddMethod (MethodBase builder, IMethodData method) { @@ -487,16 +437,33 @@ public class TypeManager { { return builder_to_declspace [t] as TypeContainer; } - - public static IMemberContainer LookupMemberContainer (Type t) + + public static MemberCache LookupMemberCache (Type t) { if (t is TypeBuilder) { IMemberContainer container = builder_to_declspace [t] as IMemberContainer; if (container != null) - return container; + return container.MemberCache; } - return TypeHandle.GetTypeHandle (t); + return TypeHandle.GetMemberCache (t); + } + + public static MemberCache LookupBaseInterfacesCache (Type t) + { + Type [] ifaces = t.GetInterfaces (); + + if (ifaces != null && ifaces.Length == 1) + return LookupMemberCache (ifaces [0]); + + // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't' + MemberCache cache = builder_to_member_cache [t] as MemberCache; + if (cache != null) + return cache; + + cache = new MemberCache (ifaces); + builder_to_member_cache.Add (t, cache); + return cache; } public static TypeContainer LookupInterface (Type t) @@ -513,11 +480,6 @@ public class TypeManager { return builder_to_declspace [t] as Delegate; } - public static Enum LookupEnum (Type t) - { - return builder_to_declspace [t] as Enum; - } - public static Class LookupClass (Type t) { return (Class) builder_to_declspace [t]; @@ -567,195 +529,100 @@ public class TypeManager { } } - static Hashtable references = new Hashtable (); - + // + // We use this hash for multiple kinds of constructed types: + // + // (T, "&") Given T, get T & + // (T, "*") Given T, get T * + // (T, "[]") Given T and a array dimension, get T [] + // (T, X) Given a type T and a simple name X, get the type T+X + // + // Accessibility tests, if necessary, should be done by the user + // + static DoubleHash type_hash = new DoubleHash (); + // // Gets the reference to T version of the Type (T&) // public static Type GetReferenceType (Type t) { - string tname = t.FullName + "&"; - - Type ret = t.Assembly.GetType (tname); - - // - // If the type comes from the assembly we are building - // We need the Hashtable, because .NET 1.1 will return different instance types - // every time we call ModuleBuilder.GetType. - // - if (ret == null){ - if (references [t] == null) - references [t] = CodeGen.Module.Builder.GetType (tname); - ret = (Type) references [t]; - } - - return ret; + return GetConstructedType (t, "&"); } - static Hashtable pointers = new Hashtable (); - // // Gets the pointer to T version of the Type (T*) // public static Type GetPointerType (Type t) { - string tname = t.FullName + "*"; - - Type ret = t.Assembly.GetType (tname); - - // - // If the type comes from the assembly we are building - // We need the Hashtable, because .NET 1.1 will return different instance types - // every time we call ModuleBuilder.GetType. - // - if (ret == null){ - if (pointers [t] == null) - pointers [t] = CodeGen.Module.Builder.GetType (tname); - - ret = (Type) pointers [t]; - } - - return ret; + return GetConstructedType (t, "*"); } - - // - // Low-level lookup, cache-less - // - static Type LookupTypeReflection (string name) - { - Type t; - - foreach (Assembly a in assemblies){ - t = a.GetType (name); - if (t == null) - continue; - - do { - TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask; - if (ta == TypeAttributes.NotPublic || - ta == TypeAttributes.NestedPrivate || - ta == TypeAttributes.NestedAssembly || - ta == TypeAttributes.NestedFamANDAssem){ - - // - // In .NET pointers turn out to be private, even if their - // element type is not - // - if (t.IsPointer){ - t = t.GetElementType (); - continue; - } else - t = null; - } else { - return t; - } - } while (t != null); - } - foreach (Module mb in modules) { - t = mb.GetType (name); - if (t != null) - return t; + public static Type GetConstructedType (Type t, string dim) + { + object ret = null; + if (!type_hash.Lookup (t, dim, out ret)) { + ret = t.Module.GetType (t.ToString () + dim); + type_hash.Insert (t, dim, ret); } - - return null; + return (Type) ret; } - static Hashtable negative_hits = new Hashtable (); - - // - // This function is used when you want to avoid the lookups, and want to go - // directly to the source. This will use the cache. - // - // Notice that bypassing the cache is bad, because on Microsoft.NET runtime - // GetType ("DynamicType[]") != GetType ("DynamicType[]"), and there is no - // way to test things other than doing a fullname compare - // - public static Type LookupTypeDirect (string name) + public static Type GetNestedType (Type t, string name) { - Type t = (Type) types [name]; - if (t != null) - return t; - - if (negative_hits.Contains (name)) - return null; - - t = LookupTypeReflection (name); - - if (t == null) - negative_hits [name] = null; - else - types [name] = t; - - return t; + object ret = null; + if (!type_hash.Lookup (t, name, out ret)) { + ret = t.GetNestedType (name, + BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + type_hash.Insert (t, name, ret); + } + return (Type) ret; } - - static readonly char [] dot_array = { '.' }; - /// - /// Returns the Type associated with @name, takes care of the fact that - /// reflection expects nested types to be separated from the main type - /// with a "+" instead of a "." - /// - public static Type LookupType (string name) + public static Type LookupTypeReflection (string name, Location loc) { - Type t; + Type found_type = null; - // - // First lookup in user defined and cached values - // - - t = (Type) types [name]; - if (t != null) - return t; + foreach (Assembly a in assemblies) { + Type t = a.GetType (name); + if (t == null) + continue; - // Two thirds of the failures are caught here. - if (negative_hits.Contains (name)) - return null; + if (t.IsPointer) + throw new InternalErrorException ("Use GetPointerType() to get a pointer"); - // Sadly, split takes a param array, so this ends up allocating *EVERY TIME* - string [] elements = name.Split (dot_array); - int count = elements.Length; + TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask; + if (ta != TypeAttributes.NotPublic && ta != TypeAttributes.NestedPrivate && + ta != TypeAttributes.NestedAssembly && ta != TypeAttributes.NestedFamANDAssem) { + if (found_type == null) { + found_type = t; + continue; + } - for (int n = 1; n <= count; n++){ - string top_level_type = String.Join (".", elements, 0, n); + Report.SymbolRelatedToPreviousError (found_type); + Report.SymbolRelatedToPreviousError (t); + Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name); + return found_type; + } + } - // One third of the failures are caught here. - if (negative_hits.Contains (top_level_type)) + foreach (Module mb in modules) { + Type t = mb.GetType (name); + if (t == null) continue; - t = (Type) types [top_level_type]; - if (t == null){ - t = LookupTypeReflection (top_level_type); - if (t == null){ - negative_hits [top_level_type] = null; - continue; - } + if (found_type == null) { + found_type = t; + continue; } - - if (count == n){ - types [name] = t; - return t; - } - // - // We know that System.Object does not have children, and since its the parent of - // all the objects, it always gets probbed for inner classes. - // - if (top_level_type == "System.Object") - return null; - - string newt = top_level_type + "+" + String.Join ("+", elements, n, count - n); - //Console.WriteLine ("Looking up: " + newt + " " + name); - t = LookupTypeReflection (newt); - if (t == null) - negative_hits [name] = null; - else - types [name] = t; + Report.SymbolRelatedToPreviousError (t); + Report.SymbolRelatedToPreviousError (found_type); + Report.Warning (436, 2, loc, "Ignoring imported type `{0}' since the current assembly already has a declaration with the same name", + TypeManager.CSharpName (t)); return t; } - negative_hits [name] = null; - return null; + + return found_type; } /// @@ -765,6 +632,8 @@ public class TypeManager { { MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic); + Hashtable cache = null; + // // First add the assembly namespaces // @@ -775,13 +644,13 @@ public class TypeManager { Assembly a = assemblies [i]; string [] namespaces = (string []) assembly_get_namespaces.Invoke (a, null); foreach (string ns in namespaces){ - if (ns == "") + if (ns.Length == 0) continue; Namespace.LookupNamespace (ns, true); } } } else { - Hashtable cache = new Hashtable (); + cache = new Hashtable (); cache.Add ("", null); foreach (Assembly a in assemblies) { foreach (Type t in a.GetExportedTypes ()) { @@ -794,6 +663,25 @@ public class TypeManager { } } } + + // + // Then add module namespaces + // + foreach (Module m in modules) { + if (m == CodeGen.Module.Builder) + continue; + if (cache == null) { + cache = new Hashtable (); + cache.Add ("", null); + } + foreach (Type t in m.GetTypes ()) { + string ns = t.Namespace; + if (ns == null || cache.Contains (ns)) + continue; + Namespace.LookupNamespace (ns, true); + cache.Add (ns, null); + } + } } /// @@ -802,10 +690,10 @@ public class TypeManager { /// public static void LoadAllImportedTypes () { - all_imported_types = new Hashtable (); + AllClsTopLevelTypes = new Hashtable (1500); foreach (Assembly a in assemblies) { foreach (Type t in a.GetExportedTypes ()) { - all_imported_types [t.FullName] = t; + AllClsTopLevelTypes [t.FullName.ToLower (System.Globalization.CultureInfo.InvariantCulture)] = null; } } } @@ -830,8 +718,19 @@ public class TypeManager { @"Single|Double|Char|Decimal|Byte|SByte|Object|" + @"Boolean|String|Void|Null)" + @"(\W+|\b)", - new MatchEvaluator (CSharpNameMatch)); + new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.'); } + + static public string CSharpName (Type[] types) + { + StringBuilder sb = new StringBuilder (); + foreach (Type t in types) { + sb.Append (CSharpName (t)); + sb.Append (','); + } + sb.Remove (sb.Length - 1, 1); + return sb.ToString (); + } static String CSharpNameMatch (Match match) { @@ -853,92 +752,94 @@ public class TypeManager { /// static public string GetFullNameSignature (MemberInfo mi) { - return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name; - } - - static public string GetFullNameSignature (MethodBase mb) - { - string name = mb.Name; - if (name == ".ctor") - name = mb.DeclaringType.Name; - - if (mb.IsSpecialName) { - if (name.StartsWith ("get_") || name.StartsWith ("set_")) { - name = name.Remove (0, 4); - } - - if (name == "Item") - name = "this"; - } - - return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name; + return (mi is MethodBase) + ? CSharpSignature (mi as MethodBase) + : CSharpName (mi.DeclaringType) + '.' + mi.Name; } /// - /// Returns the signature of the property and indexer + /// When we need to report accessors as well /// - static public string CSharpSignature (PropertyBuilder pb, bool is_indexer) + static public string CSharpSignature (MethodBase mb) { - if (!is_indexer) { - return GetFullNameSignature (pb); - } - - MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true); - string signature = GetFullNameSignature (mb); - string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0); - return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg); + return CSharpSignature (mb, false); } /// /// Returns the signature of the method /// - static public string CSharpSignature (MethodBase mb) + static public string CSharpSignature (MethodBase mb, bool show_accessor) { - StringBuilder sig = new StringBuilder ("("); - - // - // FIXME: We should really have a single function to do - // everything instead of the following 5 line pattern - // - ParameterData iparams = LookupParametersByBuilder (mb); + StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType)); + sig.Append ('.'); - if (iparams == null) - iparams = new ReflectionParameters (mb); + ParameterData iparams = GetParameterData (mb); + string parameters = iparams.GetSignatureForError (); + string accessor = ""; // Is property - if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor) - return GetFullNameSignature (mb); - - for (int i = 0; i < iparams.Count; i++) { - if (i > 0) { - sig.Append (", "); + if (mb.IsSpecialName) { + Operator.OpType ot = Operator.GetOperatorType (mb.Name); + if (ot != Operator.OpType.TOP) { + sig.Append ("operator "); + sig.Append (Operator.GetName (ot)); + sig.Append (parameters); + return sig.ToString (); + } + + if (mb.Name.StartsWith ("get_") || mb.Name.StartsWith ("set_")) { + accessor = mb.Name.Substring (0, 3); } - sig.Append (iparams.ParameterDesc (i)); } - sig.Append (")"); // Is indexer - if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) { - sig.Replace ('(', '['); - sig.Replace (')', ']'); + if (mb.IsSpecialName && !mb.IsConstructor) { + if (iparams.Count > 1) { + sig.Append ("this["); + if (show_accessor) { + sig.Append (parameters.Substring (1, parameters.Length - 2)); + } + else { + int before_ret_val = parameters.LastIndexOf (','); + sig.Append (parameters.Substring (1, before_ret_val - 1)); + } + sig.Append (']'); + } else { + sig.Append (mb.Name.Substring (4)); + } + } else { + if (mb.Name == ".ctor") + sig.Append (mb.DeclaringType.Name); + else + sig.Append (mb.Name); + + sig.Append (parameters); + } + + if (show_accessor && accessor.Length > 0) { + sig.Append ('.'); + sig.Append (accessor); } - return GetFullNameSignature (mb) + sig.ToString (); + return sig.ToString (); + } + + static public string CSharpSignature (EventInfo ei) + { + return CSharpName (ei.DeclaringType) + '.' + ei.Name; } /// /// Looks up a type, and aborts if it is not found. This is used /// by types required by the compiler /// - static Type CoreLookupType (string name) + static Type CoreLookupType (string ns_name, string name) { - Type t = LookupTypeDirect (name); - - if (t == null){ + Namespace ns = Namespace.LookupNamespace (ns_name, true); + FullNamedExpression fne = ns.Lookup (RootContext.Tree.Types, name, Location.Null); + Type t = fne == null ? null : fne.Type; + if (t == null) Report.Error (518, "The predefined type `" + name + "' is not defined or imported"); - Environment.Exit (1); - } - return t; } @@ -985,11 +886,32 @@ public class TypeManager { return GetMethod (t, name, args, true); } + /// + /// Returns the PropertyInfo for a property named `name' defined + /// in type `t' + /// + static PropertyInfo GetProperty (Type t, string name) + { + MemberList list = FindMembers (t, MemberTypes.Property, BindingFlags.Public | + BindingFlags.Instance, Type.FilterName, name); + if (list.Count == 0) { + Report.Error (-19, "Can not find the core property `" + name + "'"); + return null; + } + + PropertyInfo pi = list [0] as PropertyInfo; + if (pi == null) { + Report.Error (-19, "Can not find the core function `" + name + "'"); + return null; + } + + return pi; + } /// /// Returns the ConstructorInfo for "args" /// - static ConstructorInfo GetConstructor (Type t, Type [] args) + public static ConstructorInfo GetConstructor (Type t, Type [] args) { MemberList list; Signature sig; @@ -1017,14 +939,14 @@ public class TypeManager { public static void InitEnumUnderlyingTypes () { - int32_type = CoreLookupType ("System.Int32"); - int64_type = CoreLookupType ("System.Int64"); - uint32_type = CoreLookupType ("System.UInt32"); - uint64_type = CoreLookupType ("System.UInt64"); - byte_type = CoreLookupType ("System.Byte"); - sbyte_type = CoreLookupType ("System.SByte"); - short_type = CoreLookupType ("System.Int16"); - ushort_type = CoreLookupType ("System.UInt16"); + int32_type = CoreLookupType ("System", "Int32"); + int64_type = CoreLookupType ("System", "Int64"); + uint32_type = CoreLookupType ("System", "UInt32"); + uint64_type = CoreLookupType ("System", "UInt64"); + byte_type = CoreLookupType ("System", "Byte"); + sbyte_type = CoreLookupType ("System", "SByte"); + short_type = CoreLookupType ("System", "Int16"); + ushort_type = CoreLookupType ("System", "UInt16"); } /// @@ -1034,78 +956,86 @@ public class TypeManager { /// public static void InitCoreTypes () { - object_type = CoreLookupType ("System.Object"); - value_type = CoreLookupType ("System.ValueType"); + object_type = CoreLookupType ("System", "Object"); + value_type = CoreLookupType ("System", "ValueType"); InitEnumUnderlyingTypes (); - char_type = CoreLookupType ("System.Char"); - string_type = CoreLookupType ("System.String"); - float_type = CoreLookupType ("System.Single"); - double_type = CoreLookupType ("System.Double"); - char_ptr_type = CoreLookupType ("System.Char*"); - decimal_type = CoreLookupType ("System.Decimal"); - bool_type = CoreLookupType ("System.Boolean"); - enum_type = CoreLookupType ("System.Enum"); - - 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"); - - runtime_field_handle_type = CoreLookupType ("System.RuntimeFieldHandle"); - runtime_argument_handle_type = CoreLookupType ("System.RuntimeArgumentHandle"); - runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices.RuntimeHelpers"); - default_member_type = CoreLookupType ("System.Reflection.DefaultMemberAttribute"); - runtime_handle_type = CoreLookupType ("System.RuntimeTypeHandle"); - asynccallback_type = CoreLookupType ("System.AsyncCallback"); - iasyncresult_type = CoreLookupType ("System.IAsyncResult"); - ienumerator_type = CoreLookupType ("System.Collections.IEnumerator"); - ienumerable_type = CoreLookupType ("System.Collections.IEnumerable"); - idisposable_type = CoreLookupType ("System.IDisposable"); - icloneable_type = CoreLookupType ("System.ICloneable"); - iconvertible_type = CoreLookupType ("System.IConvertible"); - monitor_type = CoreLookupType ("System.Threading.Monitor"); - intptr_type = CoreLookupType ("System.IntPtr"); - - attribute_type = CoreLookupType ("System.Attribute"); - attribute_usage_type = CoreLookupType ("System.AttributeUsageAttribute"); - dllimport_type = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute"); - methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute"); - marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute"); - param_array_type = CoreLookupType ("System.ParamArrayAttribute"); - in_attribute_type = CoreLookupType ("System.Runtime.InteropServices.InAttribute"); - typed_reference_type = CoreLookupType ("System.TypedReference"); - arg_iterator_type = CoreLookupType ("System.ArgIterator"); - mbr_type = CoreLookupType ("System.MarshalByRefObject"); + char_type = CoreLookupType ("System", "Char"); + string_type = CoreLookupType ("System", "String"); + float_type = CoreLookupType ("System", "Single"); + double_type = CoreLookupType ("System", "Double"); + char_ptr_type = GetPointerType (char_type); + decimal_type = CoreLookupType ("System", "Decimal"); + bool_type = CoreLookupType ("System", "Boolean"); + enum_type = CoreLookupType ("System", "Enum"); + + 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"); + + runtime_field_handle_type = CoreLookupType ("System", "RuntimeFieldHandle"); + runtime_argument_handle_type = CoreLookupType ("System", "RuntimeArgumentHandle"); + runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices", "RuntimeHelpers"); + default_member_type = CoreLookupType ("System.Reflection", "DefaultMemberAttribute"); + runtime_handle_type = CoreLookupType ("System", "RuntimeTypeHandle"); + asynccallback_type = CoreLookupType ("System", "AsyncCallback"); + iasyncresult_type = CoreLookupType ("System", "IAsyncResult"); + ienumerator_type = CoreLookupType ("System.Collections", "IEnumerator"); + ienumerable_type = CoreLookupType ("System.Collections", "IEnumerable"); + idisposable_type = CoreLookupType ("System", "IDisposable"); + icloneable_type = CoreLookupType ("System", "ICloneable"); + iconvertible_type = CoreLookupType ("System", "IConvertible"); + monitor_type = CoreLookupType ("System.Threading", "Monitor"); + intptr_type = CoreLookupType ("System", "IntPtr"); + + attribute_type = CoreLookupType ("System", "Attribute"); + attribute_usage_type = CoreLookupType ("System", "AttributeUsageAttribute"); + dllimport_type = CoreLookupType ("System.Runtime.InteropServices", "DllImportAttribute"); + methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "MethodImplAttribute"); + marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices", "MarshalAsAttribute"); + param_array_type = CoreLookupType ("System", "ParamArrayAttribute"); + in_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "InAttribute"); + out_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "OutAttribute"); + typed_reference_type = CoreLookupType ("System", "TypedReference"); + arg_iterator_type = CoreLookupType ("System", "ArgIterator"); + mbr_type = CoreLookupType ("System", "MarshalByRefObject"); + decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices", "DecimalConstantAttribute"); + + unverifiable_code_type= CoreLookupType ("System.Security", "UnverifiableCodeAttribute"); + + void_ptr_type = GetPointerType (void_type); + + indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices", "IndexerNameAttribute"); + + exception_type = CoreLookupType ("System", "Exception"); + invalid_operation_exception_type = CoreLookupType ("System", "InvalidOperationException"); + not_supported_exception_type = CoreLookupType ("System", "NotSupportedException"); // - // Sigh. Remove this before the release. Wonder what versions of Mono - // people are running. + // Attribute types // - guid_attr_type = LookupType ("System.Runtime.InteropServices.GuidAttribute"); - - unverifiable_code_type= CoreLookupType ("System.Security.UnverifiableCodeAttribute"); - - void_ptr_type = CoreLookupType ("System.Void*"); - - indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices.IndexerNameAttribute"); - - exception_type = CoreLookupType ("System.Exception"); - invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException"); - not_supported_exception_type = CoreLookupType ("System.NotSupportedException"); + obsolete_attribute_type = CoreLookupType ("System", "ObsoleteAttribute"); + conditional_attribute_type = CoreLookupType ("System.Diagnostics", "ConditionalAttribute"); + cls_compliant_attribute_type = CoreLookupType ("System", "CLSCompliantAttribute"); + struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "StructLayoutAttribute"); + field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "FieldOffsetAttribute"); + security_attr_type = CoreLookupType ("System.Security.Permissions", "SecurityAttribute"); + required_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "RequiredAttributeAttribute"); + guid_attr_type = CoreLookupType ("System.Runtime.InteropServices", "GuidAttribute"); + assembly_culture_attribute_type = CoreLookupType ("System.Reflection", "AssemblyCultureAttribute"); // - // Attribute types + // .NET 2.0 // - obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute"); - conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute"); - cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute"); - struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute"); - field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute"); - +#if NET_2_0 + compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute"); + fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "FixedBufferAttribute"); + default_charset_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultCharSetAttribute"); +#endif // // When compiling corlib, store the "real" types here. // @@ -1191,6 +1121,12 @@ public class TypeManager { system_asynccallback_expr.Type = asynccallback_type; system_iasyncresult_expr.Type = iasyncresult_type; system_valuetype_expr.Type = value_type; + + // + // These are only used for compare purposes + // + anonymous_method_type = typeof (AnonymousMethod); + null_type = typeof (NullType); } // @@ -1210,7 +1146,7 @@ public class TypeManager { Type [] string_string_string_string = { string_type, string_type, string_type, string_type }; string_concat_string_string_string_string = GetMethod ( string_type, "Concat", string_string_string_string); - Type[] params_string = { TypeManager.LookupType ("System.String[]") }; + Type[] params_string = { GetConstructedType (string_type, "[]") }; string_concat_string_dot_dot_dot = GetMethod ( string_type, "Concat", params_string); @@ -1220,7 +1156,7 @@ public class TypeManager { Type [] object_object_object = { object_type, object_type, object_type }; string_concat_object_object_object = GetMethod ( string_type, "Concat", object_object_object); - Type[] params_object = { TypeManager.LookupType ("System.Object[]") }; + Type[] params_object = { GetConstructedType (object_type, "[]") }; string_concat_object_dot_dot_dot = GetMethod ( string_type, "Concat", params_object); @@ -1243,8 +1179,8 @@ public class TypeManager { // Void arguments // Type [] void_arg = { }; - object_getcurrent_void = GetMethod ( - ienumerator_type, "get_Current", void_arg); + ienumerator_getcurrent = GetProperty ( + ienumerator_type, "Current"); bool_movenext_void = GetMethod ( ienumerator_type, "MoveNext", void_arg); void_reset_void = GetMethod ( @@ -1307,23 +1243,34 @@ public class TypeManager { void_decimal_ctor_five_args = GetConstructor ( decimal_type, dec_arg); + void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg); + // // Attributes // - cons_param_array_attribute = GetConstructor ( - param_array_type, void_arg); + cons_param_array_attribute = GetConstructor (param_array_type, void_arg); + unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg); + default_member_ctor = GetConstructor (default_member_type, string_); - unverifiable_code_ctor = GetConstructor ( - unverifiable_code_type, void_arg); + Type[] short_arg = { short_type }; + struct_layout_attribute_ctor = GetConstructor (struct_layout_attribute_type, short_arg); - default_member_ctor = GetConstructor (default_member_type, string_); + decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type [] + { byte_type, byte_type, uint32_type, uint32_type, uint32_type } ); + + field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type [] + { int32_type }); // - // InvalidOperationException + // .NET 2.0 types // - invalid_operation_ctor = GetConstructor ( - invalid_operation_exception_type, void_arg); +#if NET_2_0 + compiler_generated_attr = new CustomAttributeBuilder ( + GetConstructor (compiler_generated_attr_type, void_arg), new object[0]); + Type[] type_int_arg = { type_type, int32_type }; + fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg); +#endif // Object object_ctor = GetConstructor (object_type, void_arg); @@ -1407,6 +1354,8 @@ public class TypeManager { private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf, string name, out bool used_cache) { + MemberCache cache; + // // We have to take care of arrays specially, because GetType on // a TypeBuilder array will return a Type, not a TypeBuilder, @@ -1424,7 +1373,7 @@ public class TypeManager { // if (t is TypeBuilder) { DeclSpace decl = (DeclSpace) builder_to_declspace [t]; - MemberCache cache = decl.MemberCache; + cache = decl.MemberCache; // // If this DeclSpace has a MemberCache, use it. @@ -1451,13 +1400,13 @@ public class TypeManager { // // This call will always succeed. There is exactly one TypeHandle instance per - // type, TypeHandle.GetTypeHandle() will either return it or create a new one - // if it didn't already exist. + // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return + // the corresponding MemberCache. // - TypeHandle handle = TypeHandle.GetTypeHandle (t); + cache = TypeHandle.GetMemberCache (t); used_cache = true; - return handle.MemberCache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null); + return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null); } public static bool IsBuiltinType (Type t) @@ -1480,15 +1429,12 @@ public class TypeManager { // This is like IsBuiltinType, but lacks decimal_type, we should also clean up // the pieces in the code where we use IsBuiltinType and special case decimal_type. // - public static bool IsCLRType (Type t) + public static bool IsPrimitiveType (Type t) { - if (t == object_type || t == int32_type || t == uint32_type || + return (t == int32_type || t == uint32_type || t == int64_type || t == uint64_type || t == float_type || t == double_type || t == char_type || t == short_type || t == bool_type || - t == sbyte_type || t == byte_type || t == ushort_type) - return true; - else - return false; + t == sbyte_type || t == byte_type || t == ushort_type); } public static bool IsDelegateType (Type t) @@ -1501,11 +1447,12 @@ public class TypeManager { public static bool IsEnumType (Type t) { - if (t.IsSubclassOf (TypeManager.enum_type)) + if (builder_to_declspace [t] is Enum) return true; - else - return false; + + return t.IsEnum; } + public static bool IsBuiltinOrEnum (Type t) { if (IsBuiltinType (t)) @@ -1517,47 +1464,68 @@ public class TypeManager { return false; } + static Stack unmanaged_enclosing_types = new Stack (4); + // // Whether a type is unmanaged. This is used by the unsafe code (25.2) // public static bool IsUnmanagedType (Type t) { - if (IsBuiltinType (t) && t != TypeManager.string_type) + // Avoid infloops in the case of: unsafe struct Foo { Foo *x; } + if (unmanaged_enclosing_types.Contains (t)) return true; - if (IsEnumType (t)) + // builtins that are not unmanaged types + if (t == TypeManager.object_type || t == TypeManager.string_type) + return false; + + if (IsBuiltinOrEnum (t)) return true; + // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it. if (t.IsPointer) return true; - if (IsValueType (t)){ - if (t is TypeBuilder){ - TypeContainer tc = LookupTypeContainer (t); + // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)] + if (t.IsArray) + return false; - if (tc.Fields != null){ - foreach (Field f in tc.Fields){ - if (f.FieldBuilder.IsStatic) - continue; - if (!IsUnmanagedType (f.FieldBuilder.FieldType)) - return false; - } - } else - return true; - } else { - FieldInfo [] fields = t.GetFields (); + if (!IsValueType (t)) + return false; + + unmanaged_enclosing_types.Push (t); - foreach (FieldInfo f in fields){ - if (f.IsStatic) + bool retval = true; + + if (t is TypeBuilder){ + TypeContainer tc = LookupTypeContainer (t); + if (tc.Fields != null){ + foreach (Field f in tc.Fields){ + // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked. + if ((f.ModFlags & Modifiers.STATIC) != 0) continue; - if (!IsUnmanagedType (f.FieldType)) - return false; + if (f.MemberType == null) + continue; + if (!IsUnmanagedType (f.MemberType)){ + Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name); + retval = false; + } + } + } + } else { + FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + foreach (FieldInfo f in fields){ + if (!IsUnmanagedType (f.FieldType)){ + Report.SymbolRelatedToPreviousError (f); + retval = false; } } - return true; } - return false; + unmanaged_enclosing_types.Pop (); + + return retval; } public static bool IsValueType (Type t) @@ -1577,13 +1545,30 @@ public class TypeManager { return tc.Kind == Kind.Interface; } + public static bool IsSubclassOf (Type type, Type base_type) + { + do { + if (type.Equals (base_type)) + return true; + + type = type.BaseType; + } while (type != null); + + return false; + } + + public static bool IsFamilyAccessible (Type type, Type base_type) + { + return IsSubclassOf (type, base_type); + } + // - // Checks whether `type' is a subclass or nested child of `parent'. + // Checks whether `type' is a subclass or nested child of `base_type'. // - public static bool IsSubclassOrNestedChildOf (Type type, Type parent) + public static bool IsNestedFamilyAccessible (Type type, Type base_type) { do { - if ((type == parent) || type.IsSubclassOf (parent)) + if ((type == base_type) || type.IsSubclassOf (base_type)) return true; // Handle nested types. @@ -1625,39 +1610,11 @@ public class TypeManager { } /// - /// Returns the User Defined Types + /// This method is not implemented by MS runtime for dynamic types /// - public static ArrayList UserTypes { - get { - return user_types; - } - } - - public static Hashtable TypeContainers { - get { - return typecontainers; - } - } - - static Hashtable builder_to_constant; - - public static void RegisterConstant (FieldBuilder fb, Const c) - { - if (builder_to_constant == null) - builder_to_constant = new PtrHashtable (); - - if (builder_to_constant.Contains (fb)) - return; - - builder_to_constant.Add (fb, c); - } - - public static Const LookupConstant (FieldBuilder fb) + public static bool HasElementType (Type t) { - if (builder_to_constant == null) - return null; - - return (Const) builder_to_constant [fb]; + return t.IsArray || t.IsPointer || t.IsByRef; } /// @@ -1675,18 +1632,37 @@ public class TypeManager { args = NoTypes; method_arguments.Add (mb, args); - method_internal_params.Add (mb, ip); + method_params.Add (mb, ip); } - static public InternalParameters LookupParametersByBuilder (MethodBase mb) + static public ParameterData GetParameterData (MethodBase mb) { - if (! (mb is ConstructorBuilder || mb is MethodBuilder)) - return null; - - if (method_internal_params.Contains (mb)) - return (InternalParameters) method_internal_params [mb]; - else - throw new Exception ("Argument for Method not registered" + mb); + object pd = method_params [mb]; + if (pd == null) { + if (mb is MethodBuilder || mb is ConstructorBuilder) + throw new InternalErrorException ("Argument for Method not registered" + mb); + + method_params [mb] = pd = new ReflectionParameters (mb); + } + + return (ParameterData) pd; + } + + static public void RegisterOverride (MethodBase override_method, MethodBase base_method) + { + if (method_overrides.Contains (override_method)) { + if (method_overrides [override_method] != base_method) + throw new InternalErrorException ("Override mismatch: " + override_method); + return; + } + method_overrides [override_method] = base_method; + } + + static public bool IsOverride (MethodBase m) + { + return m.IsVirtual && + (m.Attributes & MethodAttributes.NewSlot) == 0 && + (m is MethodBuilder || method_overrides.Contains (m)); } /// @@ -1749,27 +1725,19 @@ public class TypeManager { } } - // - // This is a workaround the fact that GetValue is not - // supported for dynamic types - // - static Hashtable fields = new Hashtable (); - static public bool RegisterFieldValue (FieldBuilder fb, object value) + public static void RegisterConstant (FieldInfo fb, IConstant ic) { - if (fields.Contains (fb)) - return false; - - fields.Add (fb, value); - - return true; + fields.Add (fb, ic); } - static public object GetValue (FieldBuilder fb) + public static IConstant GetConstant (FieldInfo fb) { - return fields [fb]; + if (fb == null) + return null; + + return (IConstant)fields [fb]; } - static Hashtable fieldbuilders_to_fields = new Hashtable (); static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f) { if (fieldbuilders_to_fields.Contains (fb)) @@ -1844,27 +1812,9 @@ public class TypeManager { return (MemberInfo) priv_fields_events [ei]; } - static Hashtable properties; - - static public bool RegisterProperty (PropertyBuilder pb, MethodBase get, MethodBase set) - { - if (properties == null) - properties = new Hashtable (); - - if (properties.Contains (pb)) - return false; - - properties.Add (pb, new Pair (get, set)); - - return true; - } - static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get, MethodBase set, Type[] args) { - if (!RegisterProperty (pb, get,set)) - return false; - indexer_arguments.Add (pb, args); return true; @@ -1892,8 +1842,8 @@ public class TypeManager { if (tc.Fields == null) return true; - foreach (Field field in tc.Fields) { - if (field.FieldBuilder.IsStatic) + foreach (FieldMember field in tc.Fields) { + if (field.FieldBuilder == null || field.FieldBuilder.IsStatic) continue; Type ftype = field.FieldBuilder.FieldType; @@ -1937,22 +1887,26 @@ public class TypeManager { /// This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to /// be IA, IB, IC. /// - public static TypeExpr[] ExpandInterfaces (TypeExpr [] base_interfaces) + public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces) { ArrayList new_ifaces = new ArrayList (); - + foreach (TypeExpr iface in base_interfaces){ - if (!new_ifaces.Contains (iface)) - new_ifaces.Add (iface); + Type itype = iface.ResolveType (ec); + if (itype == null) + return null; + + if (!new_ifaces.Contains (itype)) + new_ifaces.Add (itype); - TypeExpr [] implementing = iface.GetInterfaces (); + Type [] implementing = itype.GetInterfaces (); - foreach (TypeExpr imp in implementing){ + foreach (Type imp in implementing){ if (!new_ifaces.Contains (imp)) new_ifaces.Add (imp); } } - TypeExpr [] ret = new TypeExpr [new_ifaces.Count]; + Type [] ret = new Type [new_ifaces.Count]; new_ifaces.CopyTo (ret, 0); return ret; } @@ -1963,10 +1917,10 @@ public class TypeManager { /// This function returns the interfaces in the type `t'. Works with /// both types and TypeBuilders. /// - public static TypeExpr [] GetInterfaces (Type t) + public static Type [] GetInterfaces (Type t) { - TypeExpr [] cached = iface_cache [t] as TypeExpr []; + Type [] cached = iface_cache [t] as Type []; if (cached != null) return cached; @@ -1984,43 +1938,36 @@ public class TypeManager { t = TypeManager.array_type; if (t is TypeBuilder){ - TypeExpr [] parent_ifaces; + Type [] base_ifaces; if (t.BaseType == null) - parent_ifaces = NoTypeExprs; + base_ifaces = NoTypes; else - parent_ifaces = GetInterfaces (t.BaseType); - TypeExpr [] type_ifaces = (TypeExpr []) builder_to_ifaces [t]; + base_ifaces = GetInterfaces (t.BaseType); + Type [] type_ifaces = (Type []) builder_to_ifaces [t]; if (type_ifaces == null) - type_ifaces = NoTypeExprs; + type_ifaces = NoTypes; - int parent_count = parent_ifaces.Length; - TypeExpr [] result = new TypeExpr [parent_count + type_ifaces.Length]; - parent_ifaces.CopyTo (result, 0); - type_ifaces.CopyTo (result, parent_count); + int base_count = base_ifaces.Length; + Type [] result = new Type [base_count + type_ifaces.Length]; + base_ifaces.CopyTo (result, 0); + type_ifaces.CopyTo (result, base_count); iface_cache [t] = result; return result; } else { - Type [] ifaces = t.GetInterfaces (); - if (ifaces.Length == 0) - return NoTypeExprs; - - TypeExpr [] result = new TypeExpr [ifaces.Length]; - for (int i = 0; i < ifaces.Length; i++) - result [i] = new TypeExpression (ifaces [i], Location.Null); - - iface_cache [t] = result; - return result; + Type[] ifaces = t.GetInterfaces (); + iface_cache [t] = ifaces; + return ifaces; } } // // gets the interfaces that are declared explicitly on t // - public static TypeExpr [] GetExplicitInterfaces (TypeBuilder t) + public static Type [] GetExplicitInterfaces (TypeBuilder t) { - return (TypeExpr []) builder_to_ifaces [t]; + return (Type []) builder_to_ifaces [t]; } /// @@ -2029,21 +1976,21 @@ public class TypeManager { /// public static bool ImplementsInterface (Type t, Type iface) { - TypeExpr [] interfaces; + Type [] interfaces; // // FIXME OPTIMIZATION: // as soon as we hit a non-TypeBuiler in the interface // chain, we could return, as the `Type.GetInterfaces' // will return all the interfaces implement by the type - // or its parents. + // or its bases. // do { interfaces = GetInterfaces (t); if (interfaces != null){ - foreach (TypeExpr i in interfaces){ - if (i.Type == iface) + foreach (Type i in interfaces){ + if (i == iface) return true; } } @@ -2083,7 +2030,7 @@ public class TypeManager { return (object)(convert_value.ToChar (nf_provider)); else if (conversionType.Equals (typeof (DateTime))) return (object)(convert_value.ToDateTime (nf_provider)); - else if (conversionType.Equals (typeof (Decimal))) + else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal))) return (object)(convert_value.ToDecimal (nf_provider)); else if (conversionType.Equals (typeof (Double))) return (object)(convert_value.ToDouble (nf_provider)); @@ -2142,7 +2089,6 @@ public class TypeManager { t == TypeManager.int64_type || t == TypeManager.uint64_type) return t; - throw new Exception ("Unhandled typecode in enum " + " from " + t.AssemblyQualifiedName); } TypeCode tc = Type.GetTypeCode (t); @@ -2203,12 +2149,14 @@ public class TypeManager { return TypeManager.int64_type; case TypeCode.UInt64: return TypeManager.uint64_type; - case TypeCode.Single: - return TypeManager.float_type; - case TypeCode.Double: - return TypeManager.double_type; + case TypeCode.Single: + return TypeManager.float_type; + case TypeCode.Double: + return TypeManager.double_type; case TypeCode.String: return TypeManager.string_type; + case TypeCode.Decimal: + return TypeManager.decimal_type; default: if (t == typeof (void)) return TypeManager.void_type; @@ -2228,24 +2176,12 @@ public class TypeManager { /// public static bool VerifyUnManaged (Type t, Location loc) { - if (t.IsValueType || t.IsPointer){ - // - // FIXME: this is more complex, we actually need to - // make sure that the type does not contain any - // classes itself - // + if (IsUnmanagedType (t)) return true; - } - if (!RootContext.StdLib && (t == TypeManager.decimal_type)) - // We need this explicit check here to make it work when - // compiling corlib. - return true; + Report.Error (208, loc, "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'", + CSharpName (t)); - Report.Error ( - 208, loc, - "Cannot take the address or size of a variable of a managed type ('" + - CSharpName (t) + "')"); return false; } @@ -2286,7 +2222,7 @@ public class TypeManager { new Type [] { typeof (Type), typeof (bool)}, null); if (declare_local_method == null){ - Report.Warning (-24, new Location (-1), + Report.Warning (-30, new Location (-1), "This version of the runtime does not support making pinned local variables. " + "This code may cause errors on a runtime with a moving GC"); return ig.DeclareLocal (t); @@ -2390,29 +2326,28 @@ public class TypeManager { if (invocation_type == null) return false; - Debug.Assert (IsSubclassOrNestedChildOf (invocation_type, m.DeclaringType)); - - if (is_static) + if (is_static && qualifier_type == null) + // It resolved from a simple name, so it should be visible. return true; - + // A nested class has access to all the protected members visible to its parent. - if (qualifier_type != null - && TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) + if (qualifier_type != null && TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) return true; - if (invocation_type == m.DeclaringType - || invocation_type.IsSubclassOf (m.DeclaringType)) { + if (invocation_type == m.DeclaringType || invocation_type.IsSubclassOf (m.DeclaringType)) { // Although a derived class can access protected members of its base class // it cannot do so through an instance of the base class (CS1540). // => Ancestry should be: declaring_type ->* invocation_type ->* qualified_type - if (qualifier_type == null - || qualifier_type == invocation_type - || qualifier_type.IsSubclassOf (invocation_type)) + if (is_static || + qualifier_type == null || + qualifier_type == invocation_type || + qualifier_type.IsSubclassOf (invocation_type)) return true; } if (almost_match != null) almost_match.Add (m); + return false; } @@ -2443,21 +2378,20 @@ public class TypeManager { MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask; if (ma == MethodAttributes.Private) - return private_ok || (invocation_type == m.DeclaringType) || + return private_ok || invocation_type == m.DeclaringType || IsNestedChildOf (invocation_type, m.DeclaringType); - - // Assembly succeeds if we're in the same assembly. - if (ma == MethodAttributes.Assembly) - return (invocation_assembly == mb.DeclaringType.Assembly); - - // FamAndAssem requires that we not only derive, but we are on the same assembly. - if (ma == MethodAttributes.FamANDAssem){ - if (invocation_assembly != mb.DeclaringType.Assembly) + + if (invocation_assembly == mb.DeclaringType.Assembly) { + if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem) + return true; + } else { + if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamANDAssem) return false; } - - // Family and FamANDAssem require that we derive. - if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)) + + if (ma == MethodAttributes.Family || + ma == MethodAttributes.FamANDAssem || + ma == MethodAttributes.FamORAssem) return CheckValidFamilyAccess (mb.IsStatic, m); // Public. @@ -2471,19 +2405,18 @@ public class TypeManager { if (fa == FieldAttributes.Private) return private_ok || (invocation_type == m.DeclaringType) || IsNestedChildOf (invocation_type, m.DeclaringType); - - // Assembly succeeds if we're in the same assembly. - if (fa == FieldAttributes.Assembly) - return (invocation_assembly == fi.DeclaringType.Assembly); - - // FamAndAssem requires that we not only derive, but we are on the same assembly. - if (fa == FieldAttributes.FamANDAssem){ - if (invocation_assembly != fi.DeclaringType.Assembly) + + if (invocation_assembly == fi.DeclaringType.Assembly) { + if (fa == FieldAttributes.Assembly || fa == FieldAttributes.FamORAssem) + return true; + } else { + if (fa == FieldAttributes.Assembly || fa == FieldAttributes.FamANDAssem) return false; } - - // Family and FamANDAssem require that we derive. - if ((fa == FieldAttributes.Family) || (fa == FieldAttributes.FamANDAssem)) + + if (fa == FieldAttributes.Family || + fa == FieldAttributes.FamANDAssem || + fa == FieldAttributes.FamORAssem) return CheckValidFamilyAccess (fi.IsStatic, m); // Public. @@ -2555,31 +2488,12 @@ public class TypeManager { Type current_type = queried_type; bool searching = (original_bf & BindingFlags.DeclaredOnly) == 0; bool skip_iface_check = true, used_cache = false; - bool always_ok_flag = false; + bool always_ok_flag = invocation_type != null && IsNestedChildOf (invocation_type, queried_type); closure.invocation_type = invocation_type; closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null; closure.qualifier_type = qualifier_type; closure.almost_match = almost_match; - - // - // If we are a nested class, we always have access to our container - // type names - // - if (invocation_type != null){ - string invocation_name = invocation_type.FullName; - if (invocation_name.IndexOf ('+') != -1){ - string container = queried_type.FullName + "+"; - int container_length = container.Length; - - if (invocation_name.Length > container_length){ - string shared = invocation_name.Substring (0, container_length); - - if (shared == container) - always_ok_flag = true; - } - } - } // This is from the first time we find a method // in most cases, we do not actually find a method in the base class @@ -2621,7 +2535,7 @@ public class TypeManager { // works if we already used the cache in the first iteration of this loop. // // If we used the cache in any further iteration, we can still terminate the - // loop since the cache always looks in all parent classes. + // loop since the cache always looks in all base classes. // if (used_cache) @@ -2638,8 +2552,10 @@ public class TypeManager { // This happens with interfaces, they have a null // basetype. Look members up in the Object class. // - if (current_type == null) + if (current_type == null) { current_type = TypeManager.object_type; + searching = true; + } } if (list.Length == 0) @@ -2722,14 +2638,14 @@ public class TypeManager { if (queried_type.IsArray) queried_type = TypeManager.array_type; - TypeExpr [] ifaces = GetInterfaces (queried_type); + Type [] ifaces = GetInterfaces (queried_type); if (ifaces == null) return null; - foreach (TypeExpr itype in ifaces){ + foreach (Type itype in ifaces){ MemberInfo [] x; - x = MemberLookup (null, null, itype.Type, mt, bf, name, null); + x = MemberLookup (null, null, itype, mt, bf, name, null); if (x != null) return x; } @@ -2772,17 +2688,22 @@ public class TypeManager { /// There is exactly one instance of this class per type. /// public sealed class TypeHandle : IMemberContainer { - public readonly TypeHandle BaseType; + public readonly IMemberContainer BaseType; readonly int id = ++next_id; static int next_id = 0; + static TypeHandle () + { + Reset (); + } + /// /// Lookup a TypeHandle instance for the given type. If the type doesn't have /// a TypeHandle yet, a new instance of it is created. This static method /// ensures that we'll only have one TypeHandle instance per type. /// - public static TypeHandle GetTypeHandle (Type t) + private static TypeHandle GetTypeHandle (Type t) { TypeHandle handle = (TypeHandle) type_hash [t]; if (handle != null) @@ -2792,12 +2713,22 @@ public sealed class TypeHandle : IMemberContainer { type_hash.Add (t, handle); return handle; } + + public static MemberCache GetMemberCache (Type t) + { + return GetTypeHandle (t).MemberCache; + } public static void CleanUp () { type_hash = null; } + public static void Reset () + { + type_hash = new PtrHashtable (); + } + /// /// Returns the TypeHandle for TypeManager.object_type. /// @@ -2826,7 +2757,7 @@ public sealed class TypeHandle : IMemberContainer { } } - private static PtrHashtable type_hash = new PtrHashtable (); + private static PtrHashtable type_hash; private static TypeHandle object_type = null; private static TypeHandle array_type = null; @@ -2834,12 +2765,16 @@ public sealed class TypeHandle : IMemberContainer { private Type type; private bool is_interface; private MemberCache member_cache; + private MemberCache base_cache; private TypeHandle (Type type) { this.type = type; - if (type.BaseType != null) - BaseType = GetTypeHandle (type.BaseType); + if (type.BaseType != null) { + base_cache = TypeManager.LookupMemberCache (type.BaseType); + BaseType = base_cache.Container; + } else if (type.IsInterface) + base_cache = TypeManager.LookupBaseInterfacesCache (type); this.is_interface = type.IsInterface; this.member_cache = new MemberCache (this); } @@ -2858,9 +2793,9 @@ public sealed class TypeHandle : IMemberContainer { } } - public IMemberContainer ParentContainer { + public MemberCache BaseCache { get { - return BaseType; + return base_cache; } }