Nothing to see here
[mono.git] / mcs / mcs / typemanager.cs
index 385bcd463a9e2b0296c9b98326eecb7a7e0007a2..4ee2508abedac106cabb08e1ba73a8e4b8246767 100644 (file)
@@ -5,10 +5,10 @@
 //         Ravi Pratap     (ravi@ximian.com)
 //         Marek Safar     (marek.safar@seznam.cz)
 //
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// Dual licensed under the terms of the MIT X11 or GNU GPL
 //
+// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2003-2008 Novell, Inc.
 //
 
 //
@@ -25,7 +25,6 @@ using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Text;
-using System.Text.RegularExpressions;
 using System.Runtime.CompilerServices;
 using System.Diagnostics;
 
@@ -78,7 +77,9 @@ namespace Mono.CSharp {
        static public Type decimal_constant_attribute_type;
        static public Type dllimport_type;
        static public Type methodimpl_attr_type;
+#if !NET_2_0
        static public Type marshal_as_attr_type;
+#endif
        static public Type param_array_type;
        static public Type void_ptr_type;
        static public Type indexer_name_type;
@@ -113,7 +114,7 @@ namespace Mono.CSharp {
        static internal Type fixed_buffer_attr_type;
        static internal Type default_charset_type;
        static internal Type type_forwarder_attr_type;
-       static public Type activator_type;
+       static internal Type isvolatile_type;
        static public Type generic_ilist_type;
        static public Type generic_icollection_type;
        static public Type generic_ienumerator_type;
@@ -146,20 +147,21 @@ namespace Mono.CSharp {
        //
        // These methods are called by code generated by the compiler
        //
-       static public MethodInfo string_isinterned_string;
+       static public FieldInfo string_empty;
        static public MethodInfo system_type_get_type_from_handle;
        static public MethodInfo bool_movenext_void;
        static public MethodInfo void_dispose_void;
        static public MethodInfo void_monitor_enter_object;
        static public MethodInfo void_monitor_exit_object;
        static public MethodInfo void_initializearray_array_fieldhandle;
-       static public MethodInfo int_getlength_int;
        static public MethodInfo delegate_combine_delegate_delegate;
        static public MethodInfo delegate_remove_delegate_delegate;
        static public MethodInfo int_get_offset_to_string_data;
        static public MethodInfo int_interlocked_compare_exchange;
        static public PropertyInfo ienumerator_getcurrent;
        public static MethodInfo methodbase_get_type_from_handle;
+       public static MethodInfo methodbase_get_type_from_handle_generic;
+       public static MethodInfo fieldinfo_get_field_from_handle;
        static public MethodInfo activator_create_instance;
        
        //
@@ -175,9 +177,11 @@ namespace Mono.CSharp {
 
        static public CustomAttributeBuilder param_array_attr;
        static CustomAttributeBuilder compiler_generated_attr;
+       static CustomAttributeBuilder debugger_hidden_attr;
 
        // C# 2.0
        static internal ConstructorInfo fixed_buffer_attr_ctor;
+       static internal CustomAttributeBuilder unsafe_value_type_attr;
 
        // C# 3.0
        static internal CustomAttributeBuilder extension_attribute_attr;
@@ -192,12 +196,6 @@ namespace Mono.CSharp {
        // </remarks>
        static PtrHashtable builder_to_ifaces;
 
-       // <remarks>
-       //   Maps PropertyBuilder to a Type array that contains
-       //   the arguments to the indexer
-       // </remarks>
-       static Hashtable indexer_arguments;
-
        // <remarks>
        //   Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
        // <remarks>
@@ -224,10 +222,7 @@ namespace Mono.CSharp {
        static Hashtable propertybuilder_to_property;
        static Hashtable fields;
        static Hashtable events;
-
-#if GMCS_SOURCE
        static PtrHashtable assembly_internals_vis_attrs;
-#endif
 
        public static void CleanUp ()
        {
@@ -236,7 +231,6 @@ namespace Mono.CSharp {
                builder_to_member_cache = null;
                builder_to_ifaces = null;
                builder_to_type_param = null;
-               indexer_arguments = null;
                method_params = null;
                builder_to_method = null;
                
@@ -244,10 +238,7 @@ namespace Mono.CSharp {
                events = null;
                type_hash = null;
                propertybuilder_to_property = null;
-
-#if GMCS_SOURCE
                assembly_internals_vis_attrs = null;
-#endif
 
                TypeHandle.CleanUp ();
        }
@@ -293,32 +284,28 @@ namespace Mono.CSharp {
                builder_to_type_param = new PtrHashtable ();
                method_params = new PtrHashtable ();
                method_overrides = new PtrHashtable ();
-               indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
                
                fieldbuilders_to_fields = new Hashtable ();
                propertybuilder_to_property = new Hashtable ();
                fields = new Hashtable ();
                type_hash = new DoubleHash ();
-
-#if GMCS_SOURCE
                assembly_internals_vis_attrs = new PtrHashtable ();
-#endif
 
                // TODO: I am really bored by all this static stuff
-               string_isinterned_string =
                system_type_get_type_from_handle =
                bool_movenext_void =
                void_dispose_void =
                void_monitor_enter_object =
                void_monitor_exit_object =
                void_initializearray_array_fieldhandle =
-               int_getlength_int =
                delegate_combine_delegate_delegate =
                delegate_remove_delegate_delegate =
                int_get_offset_to_string_data =
                int_interlocked_compare_exchange =
                methodbase_get_type_from_handle =
+               methodbase_get_type_from_handle_generic =
+               fieldinfo_get_field_from_handle =
                activator_create_instance = null;
 
                ienumerator_getcurrent = null;
@@ -334,7 +321,10 @@ namespace Mono.CSharp {
 
                param_array_attr =
                compiler_generated_attr =
+               unsafe_value_type_attr =
                extension_attribute_attr = null;
+
+               isvolatile_type = null;
                        
                // to uncover regressions
                AllClsTopLevelTypes = null;
@@ -544,6 +534,24 @@ namespace Mono.CSharp {
                return compiler_generated_attr;
        }
 
+       public static CustomAttributeBuilder GetDebuggerHiddenAttribute (Location loc)
+       {
+               if (debugger_hidden_attr != null)
+                       return debugger_hidden_attr;
+
+               Type t = TypeManager.CoreLookupType (
+                       "System.Diagnostics", "DebuggerHiddenAttribute", Kind.Class, true);
+
+               // TODO: it cannot be null
+               if (t == null)
+                       return null;
+
+               debugger_hidden_attr = new CustomAttributeBuilder (
+                       GetPredefinedConstructor (t, loc, Type.EmptyTypes), new object[0]);
+
+               return debugger_hidden_attr;
+       }
+
        public static Type GetNestedType (Type t, string name)
        {
                object ret = null;
@@ -589,24 +597,48 @@ namespace Mono.CSharp {
                if (t == typeof (ArglistParameter))
                        return "__arglist";
                        
-               if (t == typeof (AnonymousMethod))
+               if (t == typeof (AnonymousMethodBody))
                        return "anonymous method";
 
+               if (t == null)
+                       return "internal error";
+
                return CSharpName (GetFullName (t));
-    }
+       }
+
+       static readonly char [] elements = new char [] { '*', '[' };
 
        public static string CSharpName (string name)
        {
-               if (name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
-                               return AnonymousTypeClass.SignatureForError;
-                       
-               return Regex.Replace (name,
-                       @"^System\." +
-                       @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
-                       @"Single|Double|Char|Decimal|Byte|SByte|Object|" +
-                       @"Boolean|String|Void|Null)" +
-                       @"(\W+|\b)",
-                       new MatchEvaluator (CSharpNameMatch)).Replace ('+', '.');
+               if (name.Length > 10) {
+                       switch (name) {
+                       case "System.Int32": return "int";
+                       case "System.Int64": return "long";
+                       case "System.String": return "string";
+                       case "System.Boolean": return "bool";
+                       case "System.Void": return "void";
+                       case "System.Object": return "object";
+                       case "System.UInt32": return "uint";
+                       case "System.Int16": return "short";
+                       case "System.UInt16": return "ushort";
+                       case "System.UInt64": return "ulong";
+                       case "System.Single": return "float";
+                       case "System.Double": return "double";
+                       case "System.Decimal": return "decimal";
+                       case "System.Char": return "char";
+                       case "System.Byte": return "byte";
+                       case "System.SByte": return "sbyte";
+                       }
+
+                       int idx = name.IndexOfAny (elements, 10);
+                       if (idx > 0)
+                               return CSharpName (name.Substring (0, idx)) + name.Substring (idx);
+               }
+
+               if (name [0] == AnonymousTypeClass.ClassNamePrefix [0] && name.StartsWith (AnonymousTypeClass.ClassNamePrefix))
+                       return AnonymousTypeClass.SignatureForError;
+
+               return name.Replace ('+', '.');
        }
 
        static public string CSharpName (Type[] types)
@@ -623,34 +655,8 @@ namespace Mono.CSharp {
                }
                return sb.ToString ();
        }
-       
-       static String CSharpNameMatch (Match match) 
-       {
-               string s = match.Groups [1].Captures [0].Value;
-               return s.ToLower ().
-               Replace ("int32", "int").
-               Replace ("uint32", "uint").
-               Replace ("int16", "short").
-               Replace ("uint16", "ushort").
-               Replace ("int64", "long").
-               Replace ("uint64", "ulong").
-               Replace ("single", "float").
-               Replace ("boolean", "bool")
-               + match.Groups [2].Captures [0].Value;
-       }
 
-       // Used for error reporting to show symbolic name instead of underlying value
-       public static string CSharpEnumValue (Type t, object value)
-       {
-               t = DropGenericTypeArguments (t);
-               Enum e = LookupDeclSpace (t) as Enum;
-               if (e == null)
-                       return System.Enum.GetName (t, value);
-
-               return e.GetDefinition (value).GetSignatureForError ();
-       }
-
-        /// <summary>
+       /// <summary>
        ///  Returns the signature of the method with full namespace classification
        /// </summary>
        static public string GetFullNameSignature (MemberInfo mi)
@@ -760,15 +766,21 @@ namespace Mono.CSharp {
                StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType));
                sig.Append ('.');
 
-               ParameterData iparams = GetParameterData (mb);
+               AParametersCollection iparams = GetParameterData (mb);
                string parameters = iparams.GetSignatureForError ();
                int accessor_end = 0;
 
                if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
-                       Operator.OpType ot = Operator.GetOperatorType (mb.Name);
-                       if (ot != Operator.OpType.TOP) {
-                               sig.Append ("operator ");
-                               sig.Append (Operator.GetName (ot));
+                       string op_name = Operator.GetName (mb.Name);
+                       if (op_name != null) {
+                               if (op_name == "explicit" || op_name == "implicit") {
+                                       sig.Append (op_name);
+                                       sig.Append (" operator ");
+                                       sig.Append (CSharpName (((MethodInfo)mb).ReturnType));
+                               } else {
+                                       sig.Append ("operator ");
+                                       sig.Append (op_name);
+                               }
                                sig.Append (parameters);
                                return sig.ToString ();
                        }
@@ -873,12 +885,11 @@ namespace Mono.CSharp {
                if (RootContext.StdLib || t == null || !required)
                        return t;
 
-               DeclSpace ds = (DeclSpace)RootContext.ToplevelTypes.GetDefinition (t.FullName);
-               if (ds == null) {
-                       // TODO: implement
-                       throw new NotImplementedException ("Predefined type is imported");
-               }
+               // TODO: All predefined imported types have to have correct signature
+               if (t.Module != CodeGen.Module.Builder)
+                       return t;
 
+               DeclSpace ds = (DeclSpace)RootContext.ToplevelTypes.GetDefinition (t.FullName);
                if (ds is Delegate) {
                        if (type_kind == Kind.Delegate)
                                return t;
@@ -893,32 +904,53 @@ namespace Mono.CSharp {
                return null;
        }
 
-       static MethodBase GetPredefinedMethodBase (Type t, string name, Location loc, params Type [] args)
+       static MemberInfo GetPredefinedMember (Type t, string name, MemberTypes mt, Location loc, params Type [] args)
        {
                const BindingFlags flags = instance_and_static | BindingFlags.Public | BindingFlags.DeclaredOnly;
 
-               MemberInfo [] methods = MemberLookup (null, null, t, MemberTypes.Method | MemberTypes.Constructor, flags, name, null);
-               if (methods != null) {
-                       for (int i = 0; i < methods.Length; ++i) {
-                               MethodBase method = (MethodBase) methods [i];
-                               ParameterData pd = TypeManager.GetParameterData (method);
-                               if (pd.Count != args.Length)
-                                       continue;
+               MemberInfo [] members = MemberLookup (null, null, t, mt, flags, name, null);
+               if (members != null) {
+                       for (int i = 0; i < members.Length; ++i) {
+                               MemberInfo member = members [i];
+                               if (mt == MemberTypes.Method || mt == MemberTypes.Constructor) {
+                                       MethodBase mb = member as MethodBase;
+                                       if (mb == null)
+                                               continue;
 
-                               for (int ii = 0; ii < args.Length; ++ii) {
-                                       if (!IsEqual (pd.Types [ii], args [ii])) {
-                                               method = null;
-                                               break;
-                                       }
+                                       AParametersCollection pd = TypeManager.GetParameterData (mb);
+                                       if (IsEqual (pd.Types, args))
+                                               return member;
+                               }
+                               if (mt == MemberTypes.Field) {
+                                       FieldInfo fi = member as FieldInfo;
+                                       if (fi == null)
+                                               continue;
+
+                                       if (args.Length >= 1 && !IsEqual (TypeToCoreType (fi.FieldType), args [0]))
+                                               continue;
+
+                                       return member;
                                }
 
-                               if (method != null)
-                                       return (MethodBase) method;
+                               if (mt == MemberTypes.Property) {
+                                       PropertyInfo pi = member as PropertyInfo;
+                                       if (pi == null)
+                                               continue;
+
+                                       if (args.Length >= 1 && !IsEqual (TypeToCoreType (pi.PropertyType), args [0]))
+                                               continue;
+
+                                       return member;
+                               }
                        }
                }
 
-               Report.Error (656, loc, "The compiler required member `{0}.{1}({2})' could not be found",
-                       TypeManager.CSharpName (t), name, TypeManager.CSharpName (args));
+               string method_args = null;
+               if (mt == MemberTypes.Method || mt == MemberTypes.Constructor)
+                       method_args = "(" + TypeManager.CSharpName (args) + ")";
+
+               Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
+                       TypeManager.CSharpName (t), name, method_args);
 
                return null;
        }
@@ -928,7 +960,7 @@ namespace Mono.CSharp {
        //
        public static ConstructorInfo GetPredefinedConstructor (Type t, Location loc, params Type [] args)
        {
-               return (ConstructorInfo) GetPredefinedMethodBase (t, ConstructorInfo.ConstructorName, loc, args);
+               return (ConstructorInfo) GetPredefinedMember (t, ConstructorInfo.ConstructorName, MemberTypes.Constructor, loc, args);
        }
 
        //
@@ -937,24 +969,17 @@ namespace Mono.CSharp {
        //
        public static MethodInfo GetPredefinedMethod (Type t, string name, Location loc, params Type [] args)
        {
-               return (MethodInfo)GetPredefinedMethodBase (t, name, loc, args);
+               return (MethodInfo)GetPredefinedMember (t, name, MemberTypes.Method, loc, args);
        }
 
-       /// <summary>
-       ///   Returns the PropertyInfo for a property named `name' defined
-       ///   in type `t'
-       /// </summary>
-       public static PropertyInfo GetCoreProperty (Type t, string name)
+       public static FieldInfo GetPredefinedField (Type t, string name, Location loc, params Type [] args)
        {
-               MemberInfo [] properties = MemberLookup (null, null, t, MemberTypes.Property,
-                       BindingFlags.Public | BindingFlags.Instance, name, null);
-
-               if (properties == null || properties.Length != 1) {
-                       Report.Error (-19, "Can not find the core property `" + name + "'");
-                       return null;
-               }
+               return (FieldInfo) GetPredefinedMember (t, name, MemberTypes.Field, loc, args);
+       }
 
-               return (PropertyInfo) properties [0];
+       public static PropertyInfo GetPredefinedProperty (Type t, string name, Location loc, params Type [] args)
+       {
+               return (PropertyInfo) GetPredefinedMember (t, name, MemberTypes.Property, loc, args);
        }
 
        /// <remarks>
@@ -1018,9 +1043,37 @@ namespace Mono.CSharp {
        //
        public static void InitOptionalCoreTypes ()
        {
+               system_string_expr.Type = string_type;
+               system_boolean_expr.Type = bool_type;
+               system_decimal_expr.Type = decimal_type;
+               system_single_expr.Type = float_type;
+               system_double_expr.Type = double_type;
+               system_sbyte_expr.Type = sbyte_type;
+               system_byte_expr.Type = byte_type;
+               system_int16_expr.Type = short_type;
+               system_uint16_expr.Type = ushort_type;
+               system_int32_expr.Type = int32_type;
+               system_uint32_expr.Type = uint32_type;
+               system_int64_expr.Type = int64_type;
+               system_uint64_expr.Type = uint64_type;
+               system_char_expr.Type = char_type;
+               system_void_expr.Type = void_type;
+
+               //
+               // These are only used for compare purposes
+               //
+               anonymous_method_type = typeof (AnonymousMethodBody);
+               null_type = typeof (NullLiteral);
+               
                void_ptr_type = GetPointerType (void_type);
                char_ptr_type = GetPointerType (char_type);
 
+               //
+               // Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
+               // types cache with incorrect accessiblity when any of optional types is internal.
+               //
+               internals_visible_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", Kind.Class, false);
+
                runtime_argument_handle_type = CoreLookupType ("System", "RuntimeArgumentHandle", Kind.Struct, false);
                asynccallback_type = CoreLookupType ("System", "AsyncCallback", Kind.Delegate, false);
                iasyncresult_type = CoreLookupType ("System", "IAsyncResult", Kind.Interface, false);
@@ -1035,12 +1088,14 @@ namespace Mono.CSharp {
                if (obsolete_attribute_type != null) {
                        Class c = TypeManager.LookupClass (obsolete_attribute_type);
                        if (c != null)
-                               c.DefineMembers ();
+                               c.Define ();
                }
 
                dllimport_type = CoreLookupType ("System.Runtime.InteropServices", "DllImportAttribute", Kind.Class, false);
                methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "MethodImplAttribute", Kind.Class, false);
+#if !NET_2_0
                marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices", "MarshalAsAttribute", Kind.Class, false);
+#endif
                in_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "InAttribute", Kind.Class, false);
                indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices", "IndexerNameAttribute", Kind.Class, false);
                conditional_attribute_type = CoreLookupType ("System.Diagnostics", "ConditionalAttribute", Kind.Class, false);
@@ -1053,7 +1108,6 @@ namespace Mono.CSharp {
                comimport_attr_type = CoreLookupType ("System.Runtime.InteropServices", "ComImportAttribute", Kind.Class, false);
                coclass_attr_type = CoreLookupType ("System.Runtime.InteropServices", "CoClassAttribute", Kind.Class, false);
                attribute_usage_type = CoreLookupType ("System", "AttributeUsageAttribute", Kind.Class, false);
-               internals_visible_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", Kind.Class, false);
                default_parameter_value_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultParameterValueAttribute", Kind.Class, false);
 
                // New in .NET 2.0
@@ -1109,28 +1163,6 @@ namespace Mono.CSharp {
                                        TypeManager.CSharpName (system_4_type_arg));
                        }
                }
-
-               system_string_expr.Type = string_type;
-               system_boolean_expr.Type = bool_type;
-               system_decimal_expr.Type = decimal_type;
-               system_single_expr.Type = float_type;
-               system_double_expr.Type = double_type;
-               system_sbyte_expr.Type = sbyte_type;
-               system_byte_expr.Type = byte_type;
-               system_int16_expr.Type = short_type;
-               system_uint16_expr.Type = ushort_type;
-               system_int32_expr.Type = int32_type;
-               system_uint32_expr.Type = uint32_type;
-               system_int64_expr.Type = int64_type;
-               system_uint64_expr.Type = uint64_type;
-               system_char_expr.Type = char_type;
-               system_void_expr.Type = void_type;
-
-               //
-               // These are only used for compare purposes
-               //
-               anonymous_method_type = typeof (AnonymousMethod);
-               null_type = typeof (NullLiteral);
        }
 
        const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
@@ -1339,11 +1371,6 @@ namespace Mono.CSharp {
                        return false;
        }
 
-       public static bool IsBuiltinType (TypeContainer tc)
-       {
-               return IsBuiltinType (tc.TypeBuilder);
-       }
-
        //
        // 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.
@@ -1363,7 +1390,7 @@ namespace Mono.CSharp {
                        return false;
 #endif
 
-               if (t == TypeManager.delegate_type)
+               if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
                        return false;
 
                t = DropGenericTypeArguments (t);
@@ -1373,14 +1400,7 @@ namespace Mono.CSharp {
        public static bool IsEnumType (Type t)
        {
                t = DropGenericTypeArguments (t);
-               if (builder_to_declspace [t] is Enum)
-                       return true;
-
-#if MS_COMPATIBLE && GMCS_SOURCE
-               if (t.IsGenericParameter || t.IsGenericType)
-                       return false;
-#endif
-               return t.IsEnum;
+               return t.BaseType == TypeManager.enum_type;
        }
 
        public static bool IsBuiltinOrEnum (Type t)
@@ -1472,7 +1492,10 @@ namespace Mono.CSharp {
 
                return retval;
        }
-                       
+
+       //
+       // Null is considered to be a reference type
+       //                      
        public static bool IsReferenceType (Type t)
        {
                if (TypeManager.IsGenericParameter (t)) {
@@ -1483,9 +1506,6 @@ namespace Mono.CSharp {
                        return constraints.IsReferenceType;
                }
 
-               if (t == TypeManager.null_type)
-                       return false;
-
                return !t.IsValueType;
        }                       
                
@@ -1607,15 +1627,18 @@ namespace Mono.CSharp {
                return false;
        }
 
-#if GMCS_SOURCE
+       public static bool IsSpecialType (Type t)
+       {
+               return t == arg_iterator_type || t == typed_reference_type;
+       }
+
        //
        // Checks whether `extern_type' is friend of the output assembly
        //
-       public static bool IsFriendAssembly (Assembly assembly)
+       public static bool IsThisOrFriendAssembly (Assembly assembly)
        {
-               // FIXME: This should not be reached
                if (assembly == CodeGen.Assembly.Builder)
-                       return false;
+                       return true;
 
                if (assembly_internals_vis_attrs.Contains (assembly))
                        return (bool)(assembly_internals_vis_attrs [assembly]);
@@ -1629,9 +1652,10 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               bool is_friend = false;
+#if GMCS_SOURCE
                AssemblyName this_name = CodeGen.Assembly.Name;
                byte [] this_token = this_name.GetPublicKeyToken ();
-               bool is_friend = false;
                foreach (InternalsVisibleToAttribute attr in attrs) {
                        if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
                                continue;
@@ -1661,11 +1685,12 @@ namespace Mono.CSharp {
                        is_friend = true;
                        break;
                }
-
+#endif
                assembly_internals_vis_attrs.Add (assembly, is_friend);
                return is_friend;
        }
 
+#if GMCS_SOURCE
        static bool CompareKeyTokens (byte [] token1, byte [] token2)
        {
                for (int i = 0; i < token1.Length; i++)
@@ -1677,18 +1702,12 @@ namespace Mono.CSharp {
 
        static void Error_FriendAccessNameNotMatching (string other_name)
        {
-               Report.Error (281, "Friend access was granted to `" + other_name + 
-                               "', but the output assembly is named `" + CodeGen.Assembly.Name.FullName +
-                               "'. Try adding a reference to `" + other_name + 
-                               "' or change the output assembly name to match it");
-       }
-#else
-       public static bool IsFriendAssembly (Assembly assembly)
-       {
-               return false;
+               Report.Error (281,
+                       "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
+                       other_name, CodeGen.Assembly.Name.FullName);
        }
 #endif
-       
+
         //
         // Do the right thing when returning the element type of an
         // array type based on whether we are compiling corlib or not
@@ -1708,6 +1727,21 @@ namespace Mono.CSharp {
        {
                return t.IsArray || t.IsPointer || t.IsByRef;
        }
+
+       public static Type GetEnumUnderlyingType (Type t)
+       {
+               t = DropGenericTypeArguments (t);
+               Enum e = LookupTypeContainer (t) as Enum;
+               if (e != null)
+                       return e.UnderlyingType;
+
+               // TODO: cache it ?
+               FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null, Type.EmptyTypes);
+               if (fi == null)
+                       return TypeManager.int32_type;
+
+               return TypeToCoreType (fi.FieldType);
+       }
        
        /// <summary>
        ///   Gigantic work around for missing features in System.Reflection.Emit follows.
@@ -1718,23 +1752,30 @@ namespace Mono.CSharp {
        ///   for anything which is dynamic, and we need this in a number of places,
        ///   we register this information here, and use it afterwards.
        /// </remarks>
-       static public void RegisterMethod (MethodBase mb, Parameters ip)
+       static public void RegisterMethod (MethodBase mb, AParametersCollection ip)
        {
                method_params.Add (mb, ip);
        }
+
+       static public void RegisterIndexer (PropertyBuilder pb, AParametersCollection p)
+       {
+               method_params.Add (pb, p);
+       }
        
-       static public ParameterData GetParameterData (MethodBase mb)
+       static public AParametersCollection GetParameterData (MethodBase mb)
        {
-               ParameterData pd = (ParameterData)method_params [mb];
+               AParametersCollection pd = (AParametersCollection) method_params [mb];
                if (pd == null) {
 #if MS_COMPATIBLE
                        if (mb.IsGenericMethod && !mb.IsGenericMethodDefinition) {
                                MethodInfo mi = ((MethodInfo) mb).GetGenericMethodDefinition ();
                                pd = GetParameterData (mi);
+                               /*
                                if (mi.IsGenericMethod)
                                        pd = pd.InflateTypes (mi.GetGenericArguments (), mb.GetGenericArguments ());
                                else
                                        pd = pd.InflateTypes (mi.DeclaringType.GetGenericArguments (), mb.GetGenericArguments ());
+                               */
                                method_params.Add (mb, pd);
                                return pd;
                        }
@@ -1743,14 +1784,41 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("Parameters are not registered for method `{0}'",
                                        TypeManager.CSharpName (mb.DeclaringType) + "." + mb.Name);
                        }
+
+                       pd = ParametersCollection.Create (mb);
+#else
+                       MethodBase generic = TypeManager.DropGenericMethodArguments (mb);
+                       if (generic != mb) {
+                               pd = TypeManager.GetParameterData (generic);
+                               pd = ParametersCollection.Create (pd, mb);
+                       } else {
+                               pd = ParametersCollection.Create (mb);
+                       }
 #endif
-                       pd = new ReflectionParameters (mb);
                        method_params.Add (mb, pd);
                }
                return pd;
        }
 
-       public static ParameterData GetDelegateParameters (Type t)
+       public static AParametersCollection GetParameterData (PropertyInfo pi)
+       {
+               AParametersCollection pd = (AParametersCollection)method_params [pi];
+               if (pd == null) {
+                       if (pi is PropertyBuilder)
+                               return Parameters.EmptyReadOnlyParameters;
+
+                       ParameterInfo [] p = pi.GetIndexParameters ();
+                       if (p == null)
+                               return Parameters.EmptyReadOnlyParameters;
+
+                       pd = ParametersCollection.Create (p, null);
+                       method_params.Add (pi, pd);
+               }
+
+               return pd;
+       }
+
+       public static AParametersCollection GetDelegateParameters (Type t)
        {
                Delegate d = builder_to_declspace [t] as Delegate;
                if (d != null)
@@ -1784,38 +1852,6 @@ namespace Mono.CSharp {
                return (MethodBase) method_overrides [m];
        }
 
-       /// <summary>
-       ///    Returns the argument types for an indexer based on its PropertyInfo
-       ///
-       ///    For dynamic indexers, we use the compiler provided types, for
-       ///    indexers from existing assemblies we load them from GetParameters,
-       ///    and insert them into the cache
-       /// </summary>
-       static public Type [] GetArgumentTypes (PropertyInfo indexer)
-       {
-               if (indexer_arguments.Contains (indexer))
-                       return (Type []) indexer_arguments [indexer];
-               else if (indexer is PropertyBuilder)
-                       // If we're a PropertyBuilder and not in the
-                       // `indexer_arguments' hash, then we're a property and
-                       // not an indexer.
-                       return Type.EmptyTypes;
-               else {
-                       ParameterInfo [] pi = indexer.GetIndexParameters ();
-                       // Property, not an indexer.
-                       if (pi == null)
-                               return Type.EmptyTypes;
-                       int c = pi.Length;
-                       Type [] types = new Type [c];
-                       
-                       for (int i = 0; i < c; i++)
-                               types [i] = pi [i].ParameterType;
-
-                       indexer_arguments.Add (indexer, types);
-                       return types;
-               }
-       }
-       
        public static void RegisterConstant (FieldInfo fb, IConstant ic)
        {
                fields.Add (fb, ic);
@@ -1889,14 +1925,6 @@ namespace Mono.CSharp {
                return (EventField) events [ei];
        }
 
-       static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
-                                            MethodBase set, Type[] args)
-       {
-               indexer_arguments.Add (pb, args);
-
-               return true;
-       }
-
        public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
        {
                Hashtable hash = new Hashtable ();
@@ -1906,7 +1934,7 @@ namespace Mono.CSharp {
        public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
                                              Hashtable hash)
        {
-               if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc))
+               if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc.TypeBuilder))
                        return true;
 
                //
@@ -2153,7 +2181,7 @@ namespace Mono.CSharp {
                        if (conversionType.Equals (typeof (DateTime)))
                                return (object)(convert_value.ToDateTime (nf_provider));
 
-                       if (conversionType.Equals (TypeManager.decimal_type)) {
+                       if (conversionType.Equals (decimal_type)) {
                                if (convert_value.GetType () == TypeManager.char_type)
                                        return (decimal)convert_value.ToInt32 (nf_provider);
                                return convert_value.ToDecimal (nf_provider);
@@ -2167,9 +2195,9 @@ namespace Mono.CSharp {
 
                        if (conversionType.Equals (typeof (Int16)))
                                return (object)(convert_value.ToInt16 (nf_provider));
-                       if (conversionType.Equals (typeof (Int32)))
+                       if (conversionType.Equals (int32_type))
                                return (object)(convert_value.ToInt32 (nf_provider));
-                       if (conversionType.Equals (typeof (Int64)))
+                       if (conversionType.Equals (int64_type))
                                return (object)(convert_value.ToInt64 (nf_provider));
                        if (conversionType.Equals (typeof (SByte)))
                                return (object)(convert_value.ToSByte (nf_provider));
@@ -2199,68 +2227,12 @@ namespace Mono.CSharp {
        }
 
        //
-       // This is needed, because enumerations from assemblies
-       // do not report their underlyingtype, but they report
-       // themselves
-       //
-       public static Type EnumToUnderlying (Type t)
-       {
-               t = DropGenericTypeArguments (t);
-               if (t == TypeManager.enum_type)
-                       return t;
-
-               t = t.UnderlyingSystemType;
-               if (!TypeManager.IsEnumType (t))
-                       return t;
-       
-               if (t is TypeBuilder) {
-                       // slow path needed to compile corlib
-                       if (t == TypeManager.bool_type ||
-                           t == TypeManager.byte_type ||
-                           t == TypeManager.sbyte_type ||
-                           t == TypeManager.char_type ||
-                           t == TypeManager.short_type ||
-                           t == TypeManager.ushort_type ||
-                           t == TypeManager.int32_type ||
-                           t == TypeManager.uint32_type ||
-                           t == TypeManager.int64_type ||
-                           t == TypeManager.uint64_type)
-                               return t;
-               }
-               TypeCode tc = Type.GetTypeCode (t);
-
-               switch (tc){
-               case TypeCode.Boolean:
-                       return TypeManager.bool_type;
-               case TypeCode.Byte:
-                       return TypeManager.byte_type;
-               case TypeCode.SByte:
-                       return TypeManager.sbyte_type;
-               case TypeCode.Char:
-                       return TypeManager.char_type;
-               case TypeCode.Int16:
-                       return TypeManager.short_type;
-               case TypeCode.UInt16:
-                       return TypeManager.ushort_type;
-               case TypeCode.Int32:
-                       return TypeManager.int32_type;
-               case TypeCode.UInt32:
-                       return TypeManager.uint32_type;
-               case TypeCode.Int64:
-                       return TypeManager.int64_type;
-               case TypeCode.UInt64:
-                       return TypeManager.uint64_type;
-               }
-               throw new Exception ("Unhandled typecode in enum " + tc + " from " + t.AssemblyQualifiedName);
-       }
-
-       //
-       // When compiling corlib and called with one of the core types, return
-       // the corresponding typebuilder for that type.
+       // When compiling with -nostdlib and the type is imported from an external assembly
+       // SRE uses "wrong" type and we have to convert it to the right compiler instance.
        //
        public static Type TypeToCoreType (Type t)
        {
-               if (RootContext.StdLib || (t is TypeBuilder))
+               if (RootContext.StdLib || t.Module != typeof (object).Module)
                        return t;
 
                TypeCode tc = Type.GetTypeCode (t);
@@ -2294,17 +2266,34 @@ namespace Mono.CSharp {
                        return TypeManager.string_type;
                case TypeCode.Decimal:
                        return TypeManager.decimal_type;
-               default:
-                       if (t == typeof (void))
-                               return TypeManager.void_type;
-                       if (t == typeof (object))
-                               return TypeManager.object_type;
-                       if (t == typeof (System.Type))
-                               return TypeManager.type_type;
-                       if (t == typeof (System.IntPtr))
-                               return TypeManager.intptr_type;
-                       return t;
                }
+
+               if (t == typeof (void))
+                       return TypeManager.void_type;
+               if (t == typeof (object))
+                       return TypeManager.object_type;
+               if (t == typeof (System.Type))
+                       return TypeManager.type_type;
+               if (t == typeof (System.IntPtr))
+                       return TypeManager.intptr_type;
+               if (t == typeof (System.UIntPtr))
+                       return TypeManager.uintptr_type;
+#if GMCS_SOURCE
+               if (t.IsArray) {
+                       int dim = t.GetArrayRank ();
+                       t = GetElementType (t);
+                       return t.MakeArrayType (dim);
+               }
+               if (t.IsByRef) {
+                       t = GetElementType (t);
+                       return t.MakeByRefType ();
+               }
+               if (t.IsPointer) {
+                       t = GetElementType (t);
+                       return t.MakePointerType ();
+               }
+#endif
+               return t;
        }
 
        /// <summary>
@@ -2435,19 +2424,22 @@ namespace Mono.CSharp {
        //
        // Returns whether the array of memberinfos contains the given method
        //
-       public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)
+       public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method, bool ignoreDeclType)
        {
                Type [] new_args = TypeManager.GetParameterData (new_method).Types;
                
                foreach (MethodBase method in array) {
+                       if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
+                               continue;
+               
                        if (method.Name != new_method.Name)
                                continue;
 
-                        if (method is MethodInfo && new_method is MethodInfo)
-                                if (!IsSignatureEqual (((MethodInfo) method).ReturnType,
-                                                      ((MethodInfo) new_method).ReturnType))
-                                        continue;
-
+                       if (method is MethodInfo && new_method is MethodInfo &&
+                               !IsSignatureEqual (
+                                       TypeToCoreType (((MethodInfo) method).ReturnType),
+                                       TypeToCoreType (((MethodInfo) new_method).ReturnType)))
+                               continue;
                         
                        Type [] old_args = TypeManager.GetParameterData (method).Types;
                        int old_count = old_args.Length;
@@ -2493,7 +2485,7 @@ namespace Mono.CSharp {
                foreach (MemberInfo mi in new_members){
                        MethodBase new_method = (MethodBase) mi;
                        
-                       if (!ArrayContainsMethod (target_array, new_method))
+                       if (!ArrayContainsMethod (target_array, new_method, true))
                                target_list.Add (new_method);
                }
                return target_list;
@@ -2590,6 +2582,10 @@ namespace Mono.CSharp {
                        if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
                                return a.FullName == b.FullName;
 
+                       // Some types are never equal
+                       if (a == TypeManager.null_type || a == TypeManager.anonymous_method_type)
+                               return false;
+
                        return true;
                }
 
@@ -2641,10 +2637,17 @@ namespace Mono.CSharp {
 
        public static bool IsEqual (Type[] a, Type[] b)
        {
-               if (a.Length != b.Length)
+               if (a == null || b == null || a.Length != b.Length)
                        return false;
 
                for (int i = 0; i < a.Length; ++i) {
+                       if (a [i] == null || b [i] == null) {
+                               if (a [i] == b [i])
+                                       continue;
+
+                               return false;
+                       }
+               
                        if (!IsEqual (a [i], b [i]))
                                return false;
                }
@@ -2939,8 +2942,7 @@ namespace Mono.CSharp {
                                                IsPrivateAccessible (invocation_type, m.DeclaringType) ||
                                                IsNestedChildOf (invocation_type, m.DeclaringType);
 
-                               if (invocation_assembly == mb.DeclaringType.Assembly ||
-                                   TypeManager.IsFriendAssembly (mb.DeclaringType.Assembly)) {
+                               if (TypeManager.IsThisOrFriendAssembly (mb.DeclaringType.Assembly)) {
                                        if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
                                                return true;
                                } else {
@@ -2967,9 +2969,7 @@ namespace Mono.CSharp {
                                                IsPrivateAccessible (invocation_type, m.DeclaringType) ||
                                                IsNestedChildOf (invocation_type, m.DeclaringType);
 
-                               if ((invocation_assembly == fi.DeclaringType.Assembly) ||
-                                   (invocation_assembly == null) ||
-                                   TypeManager.IsFriendAssembly (fi.DeclaringType.Assembly)) {
+                               if (TypeManager.IsThisOrFriendAssembly (fi.DeclaringType.Assembly)) {
                                        if ((fa == FieldAttributes.Assembly) ||
                                            (fa == FieldAttributes.FamORAssem))
                                                return true;
@@ -3278,17 +3278,9 @@ namespace Mono.CSharp {
                        return true;
 
                string name = mb.Name;
-               if (name.StartsWith ("op_")){
-                       foreach (string oname in Unary.oper_names) {
-                               if (oname == name)
-                                       return true;
-                       }
+               if (name.StartsWith ("op_"))
+                       return Operator.GetName (name) != null;
 
-                       foreach (string oname in Binary.oper_names) {
-                               if (oname == name)
-                                       return true;
-                       }
-               }
                return false;
        }
 
@@ -3299,12 +3291,36 @@ namespace Mono.CSharp {
        {
                MethodInfo get_method = pi.GetGetMethod (true);
                MethodInfo set_method = pi.GetSetMethod (true);
+               int g_count = 0;
+               int s_count = 0;
                if (get_method != null && set_method != null) {
-                       int g_count = get_method.GetParameters ().Length;
-                       int s_count = set_method.GetParameters ().Length;
+                       g_count = get_method.GetParameters ().Length;
+                       s_count = set_method.GetParameters ().Length;
                        if (g_count + 1 != s_count)
                                return false;
+               } else if (get_method != null) {
+                       g_count = get_method.GetParameters ().Length;
+               } else if (set_method != null) {
+                       s_count = set_method.GetParameters ().Length;
+               }
+
+               //
+               // DefaultMemberName and indexer name has to match to identify valid C# indexer
+               //
+               if ((s_count > 1 || g_count > 0) && TypeManager.default_member_type != null) {
+                       object[] o = pi.DeclaringType.GetCustomAttributes (TypeManager.default_member_type, false);
+                       if (o.Length == 0)
+                               return false;
+                       
+                       DefaultMemberAttribute dma = (DefaultMemberAttribute) o [0];
+                       if (dma.MemberName != pi.Name)
+                               return false;
+                       if (get_method != null && "get_" + dma.MemberName != get_method.Name)
+                               return false;
+                       if (set_method != null && "set_" + dma.MemberName != set_method.Name)
+                               return false;
                }
+
                return true;
        }