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;
}
}