2004-01-04 David Sheldon <dave-mono@earth.li>
[mono.git] / mcs / gmcs / class.cs
index c5ae658639e19755e01276565a125148f35f4600..5aaa2aa3da4b9d355cea256cde26a9bee0e9342f 100755 (executable)
@@ -123,7 +123,7 @@ namespace Mono.CSharp {
                public bool Inherited;
 
                // The interfaces we implement.
-               Type [] ifaces;
+               TypeExpr [] ifaces;
 
                // The parent member container and our member cache
                IMemberContainer parent_container;
@@ -573,7 +573,7 @@ namespace Mono.CSharp {
                        Constructor c;
                        int mods = 0;
 
-                       c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
+                       c = new Constructor (this, Basename, Parameters.EmptyReadOnlyParameters,
                                             new ConstructorBaseInitializer (
                                                     null, Parameters.EmptyReadOnlyParameters,
                                                     Location),
@@ -605,7 +605,7 @@ namespace Mono.CSharp {
                void Error_TypeParameterAsBase (TypeParameterExpr e)
                {
                        Report.Error (
-                             -213, e.Location,
+                             -216, e.Location,
                              String.Format ("Type parameter `{0}' can not be used t as a base class or interface", e.Name));
                }
                
@@ -624,7 +624,7 @@ namespace Mono.CSharp {
                ///   The @parent argument is set to the parent object or null
                ///   if this is `System.Object'. 
                /// </summary>
-               Type [] GetClassBases (bool is_class, out Type parent, out bool error)
+               TypeExpr [] GetClassBases (bool is_class, out TypeExpr parent, out bool error)
                {
                        ArrayList bases = Bases;
                        int count;
@@ -635,14 +635,14 @@ namespace Mono.CSharp {
                        if (is_class)
                                parent = null;
                        else
-                               parent = TypeManager.value_type;
+                               parent = TypeManager.system_valuetype_expr;
 
                        if (bases == null){
                                if (is_class){
                                        if (RootContext.StdLib)
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                        else if (Name != "System.Object")
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                } else {
                                        //
                                        // If we are compiling our runtime,
@@ -650,7 +650,7 @@ namespace Mono.CSharp {
                                        // parent is `System.Object'.
                                        //
                                        if (!RootContext.StdLib && Name == "System.ValueType")
-                                               parent = TypeManager.object_type;
+                                               parent = TypeManager.system_object_expr;
                                }
 
                                return null;
@@ -662,8 +662,7 @@ namespace Mono.CSharp {
                        count = bases.Count;
 
                        if (is_class){
-                               Expression name = (Expression) bases [0];
-                               name = ResolveTypeExpr (name, false, Location);
+                               TypeExpr name = ResolveTypeExpr ((Expression) bases [0], false, Location);
 
                                if (name == null){
                                        error = true;
@@ -676,33 +675,38 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               Type first = name.Type;
-
-                               if (first.IsClass){
-                                       parent = first;
+                               if (name.IsClass){
+                                       parent = name;
                                        start = 1;
                                } else {
-                                       parent = TypeManager.object_type;
+                                       parent = TypeManager.system_object_expr;
                                        start = 0;
                                }
-                               if (first.IsSealed){
+                               if (name.IsSealed){
                                        string detail = "";
                                        
-                                       if (first.IsValueType)
+                                       if (name.IsValueType)
                                                detail = " (a class can not inherit from a struct/enum)";
                                        
                                        Report.Error (509, "class `"+ Name +
                                                      "': Cannot inherit from sealed class `"+
-                                                     first + "'" + detail);
+                                                     name.Name + "'" + detail);
                                        error = true;
                                        return null;
                                }
 
-                               if (!AsAccessible (parent, ModFlags))
+                               if (!parent.CanInheritFrom ()){
+                                       Report.Error (644, Location,
+                                                     "`{0}' cannot inherit from special class `{1}'",
+                                                     Name, parent.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (!parent.AsAccessible (this, ModFlags))
                                        Report.Error (60, Location,
                                                      "Inconsistent accessibility: base class `" +
-                                                     TypeManager.CSharpName (parent) + "' is less " +
-                                                     "accessible than class `" +
+                                                     name.Name + "' is less accessible than class `" +
                                                      Name + "'");
 
                        } else {
@@ -712,30 +716,24 @@ namespace Mono.CSharp {
                        if (parent != null)
                                base_class_name = parent.Name;
 
-                       Type [] ifaces = new Type [count-start];
+                       TypeExpr [] ifaces = new TypeExpr [count-start];
                        
                        for (i = start, j = 0; i < count; i++, j++){
                                Expression name = (Expression) bases [i];
-                               Expression resolved = ResolveTypeExpr (name, false, Location);
+                               TypeExpr resolved = ResolveTypeExpr (name, false, Location);
                                if (resolved == null)
                                        return null;
                                
                                bases [i] = resolved;
-                               Type t = resolved.Type;
-
-                               if (t == null){
-                                       error = true;
-                                       return null;
-                               }
 
-                               if (is_class == false && !t.IsInterface){
+                               if (is_class == false && !resolved.IsInterface){
                                        Report.Error (527, "In Struct `" + Name + "', type `"+
                                                      name +"' is not an interface");
                                        error = true;
                                        return null;
                                }
                                
-                               if (t.IsClass) {
+                               if (resolved.IsClass) {
                                        if (parent != null){
                                                Report.Error (527, "In Class `" + Name + "', type `"+
                                                              name+"' is not an interface");
@@ -745,33 +743,40 @@ namespace Mono.CSharp {
                                }
 
                                for (int x = 0; x < j; x++) {
-                                       if (t == ifaces [x]) {
+                                       if (resolved == ifaces [x]) {
                                                Report.Error (528, "`" + name + "' is already listed in interface list");
                                                error = true;
                                                return null;
                                        }
                                }
 
-                               ifaces [j] = t;
+                               ifaces [j] = resolved;
                        }
 
                        return TypeManager.ExpandInterfaces (ifaces);
                }
+
+               bool error = false;
                
                //
                // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
                //
                public override TypeBuilder DefineType ()
                {
-                       Type parent;
-                       bool error;
+                       TypeExpr parent;
                        bool is_class;
 
                        if (TypeBuilder != null)
                                return TypeBuilder;
+
+                       if (error)
+                               return null;
                        
-                       if (InTransit)
+                       if (InTransit) {
+                               Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
+                               error = true;
                                return null;
+                       }
                        
                        InTransit = true;
 
@@ -787,22 +792,12 @@ namespace Mono.CSharp {
                        if (error)
                                return null;
 
-                       if (is_class && parent != null){
-                               if (parent == TypeManager.enum_type ||
-                                   (parent == TypeManager.value_type && RootContext.StdLib) ||
-                                   parent == TypeManager.delegate_type ||
-                                   parent == TypeManager.array_type){
-                                       Report.Error (
-                                               644, Location, "`" + Name + "' cannot inherit from " +
-                                               "special class `" + TypeManager.CSharpName (parent) + "'");
-                                       return null;
-                               }
-                       }
-
-                       if (IsGeneric && (parent == TypeManager.attribute_type ||
-                                         parent.IsSubclassOf (TypeManager.attribute_type))){
-                               Report.Error (-214, Location, "Generic type can not derive from Attribute");
-                               return null;
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       if (!type_param.Resolve (this)) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
                        
                        if (!is_class && TypeManager.value_type == null)
@@ -810,18 +805,30 @@ namespace Mono.CSharp {
 
                        TypeAttributes type_attributes = TypeAttr;
 
+                       Type ptype;
+                       ConstructedType constructed = parent as ConstructedType;
+                       if ((constructed == null) && (parent != null))
+                               ptype = parent.ResolveType (ec);
+                       else
+                               ptype = null;
+
                        if (IsTopLevel){
-                               if (TypeManager.NamespaceClash (Name, Location))
+                               if (TypeManager.NamespaceClash (Name, Location)) {
+                                       error = true;
                                        return null;
-                               
+                               }
+
                                ModuleBuilder builder = CodeGen.ModuleBuilder;
                                TypeBuilder = builder.DefineType (
-                                       Name, type_attributes, parent, ifaces);
+                                       Name, type_attributes, ptype, null);
                                
                        } else {
                                TypeBuilder builder = Parent.DefineType ();
+                               if (builder == null)
+                                       return null;
+                               
                                TypeBuilder = builder.DefineNestedType (
-                                       Basename, type_attributes, parent, ifaces);
+                                       Basename, type_attributes, ptype, null);
                        }
 
                        if (IsGeneric) {
@@ -829,6 +836,19 @@ namespace Mono.CSharp {
                                        type_param.Define (TypeBuilder);
                        }
 
+                       if (constructed != null) {
+                               ptype = constructed.ResolveType (ec);
+                               if (ptype == null)
+                                       return null;
+
+                               TypeBuilder.SetParent (ptype);
+                       }
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       type_param.DefineType (ec, TypeBuilder);
+                       }
+
                        //
                        // Structs with no fields need to have at least one byte.
                        // The right thing would be to set the PackingSize in a DefineType
@@ -839,10 +859,13 @@ namespace Mono.CSharp {
                        if (!is_class && !have_nonstatic_fields){
                                TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
                                                         FieldAttributes.Private);
-                               // add interfaces that were not added at type creation
-                               if (ifaces != null) {
-                                       foreach (Type i in ifaces)
-                                               TypeBuilder.AddInterfaceImplementation (i);
+                       }
+
+                       // add interfaces that were not added at type creation
+                       if (ifaces != null) {
+                               foreach (TypeExpr iface in ifaces) {
+                                       Type itype = iface.ResolveType (ec);
+                                       TypeBuilder.AddInterfaceImplementation (itype);
                                }
                        }
 
@@ -853,9 +876,7 @@ namespace Mono.CSharp {
 
                        TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
 
-                       if ((parent != null) &&
-                           (parent == TypeManager.attribute_type ||
-                            parent.IsSubclassOf (TypeManager.attribute_type))) {
+                       if ((parent != null) && parent.IsAttribute) {
                                RootContext.RegisterAttribute (this);
                                TypeManager.RegisterAttrType (TypeBuilder, this);
                        } else
@@ -863,22 +884,34 @@ namespace Mono.CSharp {
                                
                        if (Interfaces != null) {
                                foreach (Interface iface in Interfaces)
-                                       iface.DefineType ();
+                                       if (iface.DefineType () == null) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
                        
                        if (Types != null) {
                                foreach (TypeContainer tc in Types)
-                                       tc.DefineType ();
+                                       if (tc.DefineType () == null) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
 
                        if (Delegates != null) {
                                foreach (Delegate d in Delegates)
-                                       d.DefineType ();
+                                       if (d.DefineType () == null) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
 
                        if (Enums != null) {
                                foreach (Enum en in Enums)
-                                       en.DefineType ();
+                                       if (en.DefineType () == null) {
+                                               error = true;
+                                               return null;
+                                       }
                        }
 
                        InTransit = false;
@@ -1751,108 +1784,6 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               // Access level of a type.
-               enum AccessLevel {
-                       Public                  = 0,
-                       ProtectedInternal       = 1,
-                       Internal                = 2,
-                       Protected               = 3,
-                       Private                 = 4
-               }
-
-               // Check whether `flags' denotes a more restricted access than `level'
-               // and return the new level.
-               static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
-               {
-                       AccessLevel old_level = level;
-
-                       if ((flags & Modifiers.INTERNAL) != 0) {
-                               if ((flags & Modifiers.PROTECTED) != 0) {
-                                       if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                               level = AccessLevel.ProtectedInternal;
-                               } else {
-                                       if ((int) level < (int) AccessLevel.Internal)
-                                               level = AccessLevel.Internal;
-                               }
-                       } else if ((flags & Modifiers.PROTECTED) != 0) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       } else if ((flags & Modifiers.PRIVATE) != 0)
-                               level = AccessLevel.Private;
-
-                       return level;
-               }
-
-               // Return the access level for a new member which is defined in the current
-               // TypeContainer with access modifiers `flags'.
-               AccessLevel GetAccessLevel (int flags)
-               {
-                       if ((flags & Modifiers.PRIVATE) != 0)
-                               return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (!IsTopLevel && (Parent != null))
-                               level = Parent.GetAccessLevel (flags);
-                       else
-                               level = AccessLevel.Public;
-
-                       return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
-               }
-
-               // Return the access level for type `t', but don't give more access than `flags'.
-               static AccessLevel GetAccessLevel (Type t, int flags)
-               {
-                       if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
-                               return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (TypeManager.IsBuiltinType (t))
-                               return AccessLevel.Public;
-                       else if ((t.DeclaringType != null) && (t != t.DeclaringType))
-                               level = GetAccessLevel (t.DeclaringType, flags);
-                       else {
-                               level = CheckAccessLevel (AccessLevel.Public, flags);
-                       }
-
-                       if (t.IsNestedPublic)
-                               return level;
-
-                       if (t.IsNestedAssembly || t.IsNotPublic) {
-                               if ((int) level < (int) AccessLevel.Internal)
-                                       level = AccessLevel.Internal;
-                       }
-
-                       if (t.IsNestedFamily) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       }
-
-                       if (t.IsNestedFamORAssem) {
-                               if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                       level = AccessLevel.ProtectedInternal;
-                       }
-
-                       return level;
-               }
-
-               //
-               // Returns true if `parent' is as accessible as the flags `flags'
-               // given for this member.
-               //
-               public bool AsAccessible (Type parent, int flags)
-               {
-                       if (parent.IsUnboundGenericParameter)
-                               return true; // FIXME
-
-                       while (parent.IsArray || parent.IsPointer || parent.IsByRef)
-                               parent = TypeManager.GetElementType (parent);
-
-                       AccessLevel level = GetAccessLevel (flags);
-                       AccessLevel level2 = GetAccessLevel (parent, flags);
-
-                       return (int) level >= (int) level2;
-               }
-
                Hashtable builder_and_args;
                
                public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
@@ -1872,8 +1803,8 @@ namespace Mono.CSharp {
                        bool found = false;
 
                        if (ifaces != null){
-                               foreach (Type t in ifaces){
-                                       if (t == interface_type){
+                               foreach (TypeExpr t in ifaces){
+                                       if (t.Type == interface_type){
                                                found = true;
                                                break;
                                        }
@@ -2192,6 +2123,7 @@ namespace Mono.CSharp {
        public abstract class MethodCore : MemberBase {
                public readonly Parameters Parameters;
                protected Block block;
+               protected DeclSpace ds;
                
                //
                // Parameters, cached for semantic analysis.
@@ -2204,11 +2136,12 @@ namespace Mono.CSharp {
                // </summary>
                public bool OverridesSomething;
 
-               public MethodCore (Expression type, int mod, int allowed_mod, string name,
-                                  Attributes attrs, Parameters parameters, Location loc)
+               public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
+                                  string name, Attributes attrs, Parameters parameters, Location loc)
                        : base (type, mod, allowed_mod, Modifiers.PRIVATE, name, attrs, loc)
                {
                        Parameters = parameters;
+                       this.ds = ds;
                }
                
                //
@@ -2237,14 +2170,14 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected virtual bool DoDefineParameters (TypeContainer container)
+               protected virtual bool DoDefineParameters ()
                {
                        // Check if arguments were correct
-                       parameter_types = Parameters.GetParameterInfo (container);
-                       if ((parameter_types == null) || !CheckParameters (container, parameter_types))
+                       parameter_types = Parameters.GetParameterInfo (ds);
+                       if ((parameter_types == null) || !CheckParameters (ds, parameter_types))
                                return false;
 
-                       parameter_info = new InternalParameters (container, Parameters);
+                       parameter_info = new InternalParameters (ds, Parameters);
 
                        Parameter array_param = Parameters.ArrayParameter;
                        if ((array_param != null) &&
@@ -2276,13 +2209,17 @@ namespace Mono.CSharp {
                // The method's attributes are passed in because we need to extract
                // the "return:" attribute from there to apply on the return type
                //
-               public void LabelParameters (EmitContext ec, MethodBase builder, Attributes method_attrs)
+               static public void LabelParameters (EmitContext ec,
+                                                    MethodBase builder,
+                                                    Parameters parameters,
+                                                    Attributes method_attrs,
+                                                    Location loc)
                {
                        //
                        // Define each type attribute (in/out/ref) and
                        // the argument names.
                        //
-                       Parameter [] p = Parameters.FixedParameters;
+                       Parameter [] p = parameters.FixedParameters;
                        int i = 0;
                        
                        MethodBuilder mb = null;
@@ -2311,16 +2248,16 @@ namespace Mono.CSharp {
 
                                                if (par_attr == ParameterAttributes.Out){
                                                        if (attr.Contains (TypeManager.in_attribute_type))
-                                                               Report.Error (36, Location,
+                                                               Report.Error (36, loc,
                                                                     "Can not use [In] attribute on out parameter");
                                                }
                                        }
                                }
                        }
 
-                       if (Parameters.ArrayParameter != null){
+                       if (parameters.ArrayParameter != null){
                                ParameterBuilder pb;
-                               Parameter array_param = Parameters.ArrayParameter;
+                               Parameter array_param = parameters.ArrayParameter;
 
                                if (mb == null)
                                        pb = cb.DefineParameter (
@@ -2361,9 +2298,10 @@ namespace Mono.CSharp {
                                try {
                                        ret_pb = mb.DefineParameter (0, ParameterAttributes.None, "");
                                        Attribute.ApplyAttributes (ec, ret_pb, ret_pb, ret_attrs);
-                               } catch (ArgumentOutOfRangeException) {
+
+                                } catch (ArgumentOutOfRangeException) {
                                        Report.Warning (
-                                               -24, Location,
+                                               -24, loc,
                                                ".NET SDK 1.0 does not permit setting custom attributes" +
                                                 " on the return type of a method");
                                }
@@ -2374,6 +2312,7 @@ namespace Mono.CSharp {
        public class Method : MethodCore, IIteratorContainer {
                public MethodBuilder MethodBuilder;
                public MethodData MethodData;
+               public readonly GenericMethod GenericMethod;
 
                /// <summary>
                ///   Modifiers allowed in a class declaration
@@ -2395,11 +2334,18 @@ namespace Mono.CSharp {
                //
                // return_type can be "null" for VOID values.
                //
-               public Method (Expression return_type, int mod, string name, Parameters parameters,
-                              Attributes attrs, Location l)
-                       : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+               public Method (DeclSpace ds, Expression return_type, int mod, string name,
+                              Parameters parameters, Attributes attrs, Location l)
+                       : base (ds, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
                { }
 
+               public Method (GenericMethod generic, Expression return_type, int mod, string name,
+                              Parameters parameters, Attributes attrs, Location l)
+                       : base (generic, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
+               {
+                       GenericMethod = generic;
+               }
+
                //
                // Returns the `System.Type' for the ReturnType of this
                // function.  Provides a nice cache.  (used between semantic analysis
@@ -2460,7 +2406,7 @@ namespace Mono.CSharp {
                        base.CheckBase (container);
                        
                        // Check whether arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
@@ -2558,14 +2504,21 @@ namespace Mono.CSharp {
                        if (!DoDefine (container))
                                return false;
 
+                       MethodBuilder mb = null;
+                       if (GenericMethod != null) {
+                               mb = container.TypeBuilder.DefineGenericMethod (Name, flags);
+                               if (!GenericMethod.Define (mb))
+                                       return false;
+                       }
+
                        if (!CheckBase (container))
                                return false;
 
                        CallingConventions cc = GetCallingConvention (container is Class);
 
-                       MethodData = new MethodData (this, null, MemberType, ParameterTypes,
-                                                    ParameterInfo, cc, OptAttributes,
-                                                    ModFlags, flags, true);
+                       MethodData = new MethodData (ds, this, null, MemberType,
+                                                    ParameterTypes, ParameterInfo, cc,
+                                                    OptAttributes, ModFlags, flags, true, mb);
 
                        if (!MethodData.Define (container))
                                return false;
@@ -2586,7 +2539,7 @@ namespace Mono.CSharp {
                        }
 
                        MethodBuilder = MethodData.MethodBuilder;
-                       
+
                        //
                        // This is used to track the Entry Point,
                        //
@@ -2748,8 +2701,9 @@ namespace Mono.CSharp {
                // The spec claims that static is not permitted, but
                // my very own code has static constructors.
                //
-               public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
-                       : base (null, 0, AllowedModifiers, name, null, args, l)
+               public Constructor (DeclSpace ds, string name, Parameters args,
+                                   ConstructorInitializer init, Location l)
+                       : base (ds, null, 0, AllowedModifiers, name, null, args, l)
                {
                        Initializer = init;
                }
@@ -2779,7 +2733,7 @@ namespace Mono.CSharp {
                                               MethodAttributes.SpecialName);
 
                        // Check if arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        if ((ModFlags & Modifiers.STATIC) != 0){
@@ -2873,7 +2827,8 @@ namespace Mono.CSharp {
                                ec.IsStatic = false;
                        }
 
-                       LabelParameters (ec, ConstructorBuilder, OptAttributes);
+                       MethodCore.LabelParameters (ec, ConstructorBuilder,
+                                                    Parameters, OptAttributes, Location);
                        
                        SymbolWriter sw = CodeGen.SymbolWriter;
                        bool generate_debugging = false;
@@ -2945,6 +2900,7 @@ namespace Mono.CSharp {
                //
                // Protected data.
                //
+               protected DeclSpace ds;
                protected MemberBase member;
                protected int modifiers;
                protected MethodAttributes flags;
@@ -2962,11 +2918,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public MethodData (MemberBase member, string name, Type return_type,
+               public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
                                   Type [] parameter_types, InternalParameters parameters,
                                   CallingConventions cc, Attributes opt_attrs,
                                   int modifiers, MethodAttributes flags, bool is_method)
                {
+                       this.ds = ds;
                        this.member = member;
                        this.accessor_name = name;
                        this.ReturnType = return_type;
@@ -2981,6 +2938,17 @@ namespace Mono.CSharp {
                        this.conditionals = null;
                }
 
+               public MethodData (DeclSpace ds, MemberBase member, string name, Type return_type,
+                                  Type [] parameter_types, InternalParameters parameters,
+                                  CallingConventions cc, Attributes opt_attrs,
+                                  int modifiers, MethodAttributes flags, bool is_method,
+                                  MethodBuilder builder)
+                       : this (ds, member, name, return_type, parameter_types, parameters,
+                               cc, opt_attrs, modifiers, flags, is_method)
+               {
+                       this.builder = builder;
+               }
+
                //
                // Attributes.
                //
@@ -3285,15 +3253,17 @@ namespace Mono.CSharp {
                                }
                                
                                EmitContext ec = new EmitContext (
-                                       container, Location, null, ReturnType, modifiers);
+                                       container, ds, Location, null, ReturnType, modifiers, false);
                                
                                builder = dllimport_attribute.DefinePInvokeMethod (
                                        ec, container.TypeBuilder, method_name, flags,
                                        ReturnType, ParameterTypes);
-                       } else
+                       } else if (builder == null)
                                builder = container.TypeBuilder.DefineMethod (
                                        method_name, flags, CallingConventions,
                                        ReturnType, ParameterTypes);
+                       else
+                               builder.SetGenericMethodSignature (ReturnType, ParameterTypes);
 
                        if (builder == null)
                                return false;
@@ -3347,14 +3317,17 @@ namespace Mono.CSharp {
                        else
                                ig = null;
 
-                       ec = new EmitContext (container, Location, ig, ReturnType, modifiers);
+                       ec = new EmitContext (container, ds, Location, ig, ReturnType, modifiers, false);
 
                        if (OptAttributes != null)
                                Attribute.ApplyAttributes (ec, builder, kind, OptAttributes);
 
                        if (member is MethodCore)
-                               ((MethodCore) member).LabelParameters (ec, MethodBuilder, OptAttributes);
-
+                               MethodCore.LabelParameters (ec, MethodBuilder,
+                                                            ((MethodCore) member).Parameters,
+                                                            OptAttributes,
+                                                            Location);
+                        
                        //
                        // abstract or extern methods have no bodies
                        //
@@ -3676,19 +3649,19 @@ namespace Mono.CSharp {
                        return ok;
                }
 
-               protected virtual bool CheckParameters (TypeContainer container, Type [] parameters)
+               protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
                {
                        bool error = false;
 
                        foreach (Type partype in parameters){
                                if (partype.IsPointer){
-                                       if (!UnsafeOK (container))
+                                       if (!UnsafeOK (ds))
                                                error = true;
                                        if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
                                                error = true;
                                }
 
-                               if (container.AsAccessible (partype, ModFlags))
+                               if (ds.AsAccessible (partype, ModFlags))
                                        continue;
 
                                if (this is Indexer)
@@ -4006,10 +3979,11 @@ namespace Mono.CSharp {
 
                protected EmitContext ec;
 
-               public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
-                                    Parameters parameters, Accessor get_block, Accessor set_block,
+               public PropertyBase (DeclSpace ds, Expression type, string name, int mod_flags,
+                                    int allowed_mod, Parameters parameters,
+                                    Accessor get_block, Accessor set_block,
                                     Attributes attrs, Location loc)
-                       : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
+                       : base (ds, type, mod_flags, allowed_mod, name, attrs, parameters, loc)
                {
                        Get = get_block;
                        Set = set_block;
@@ -4033,7 +4007,7 @@ namespace Mono.CSharp {
                        base.CheckBase (container);
                        
                        // Check whether arguments were correct.
-                       if (!DoDefineParameters (container))
+                       if (!DoDefineParameters ())
                                return false;
 
                        if (IsExplicitImpl)
@@ -4179,10 +4153,10 @@ namespace Mono.CSharp {
                        Modifiers.EXTERN |
                        Modifiers.VIRTUAL;
 
-               public Property (Expression type, string name, int mod_flags,
+               public Property (DeclSpace ds, Expression type, string name, int mod_flags,
                                 Accessor get_block, Accessor set_block,
                                 Attributes attrs, Location loc)
-                       : base (type, name, mod_flags, AllowedModifiers,
+                       : base (ds, type, name, mod_flags, AllowedModifiers,
                                Parameters.EmptyReadOnlyParameters,
                                get_block, set_block, attrs, loc)
                {
@@ -4204,7 +4178,7 @@ namespace Mono.CSharp {
                                InternalParameters ip = new InternalParameters (
                                        container, Parameters.EmptyReadOnlyParameters);
 
-                               GetData = new MethodData (this, "get", MemberType,
+                               GetData = new MethodData (container, this, "get", MemberType,
                                                          parameters, ip, CallingConventions.Standard,
                                                          Get.OptAttributes, ModFlags, flags, false);
 
@@ -4223,7 +4197,7 @@ namespace Mono.CSharp {
                                InternalParameters ip = new InternalParameters (
                                        container, new Parameters (parms, null, Location));
 
-                               SetData = new MethodData (this, "set", TypeManager.void_type,
+                               SetData = new MethodData (container, this, "set", TypeManager.void_type,
                                                          parameters, ip, CallingConventions.Standard,
                                                          Set.OptAttributes, ModFlags, flags, false);
 
@@ -4473,7 +4447,7 @@ namespace Mono.CSharp {
                        //
                        // Now define the accessors
                        //
-                       AddData = new MethodData (this, "add", TypeManager.void_type,
+                       AddData = new MethodData (container, this, "add", TypeManager.void_type,
                                                  parameter_types, ip, CallingConventions.Standard,
                                                  (Add != null) ? Add.OptAttributes : null,
                                                  ModFlags, flags | m_attr, false);
@@ -4484,7 +4458,7 @@ namespace Mono.CSharp {
                        AddBuilder = AddData.MethodBuilder;
                        AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
 
-                       RemoveData = new MethodData (this, "remove", TypeManager.void_type,
+                       RemoveData = new MethodData (container, this, "remove", TypeManager.void_type,
                                                     parameter_types, ip, CallingConventions.Standard,
                                                     (Remove != null) ? Remove.OptAttributes : null,
                                                     ModFlags, flags | m_attr, false);
@@ -4612,9 +4586,10 @@ namespace Mono.CSharp {
                //
                bool IsImplementing = false;
                
-               public Indexer (Expression type, string int_type, int flags, Parameters parameters,
-                               Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
-                       : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
+               public Indexer (DeclSpace ds, Expression type, string int_type, int flags,
+                               Parameters parameters, Accessor get_block, Accessor set_block,
+                               Attributes attrs, Location loc)
+                       : base (ds, type, "", flags, AllowedModifiers, parameters, get_block, set_block,
                                attrs, loc)
                {
                        ExplicitInterfaceName = int_type;
@@ -4653,7 +4628,7 @@ namespace Mono.CSharp {
                        if (Get != null){
                                 InternalParameters ip = new InternalParameters (container, Parameters);
 
-                               GetData = new MethodData (this, "get", MemberType,
+                               GetData = new MethodData (container, this, "get", MemberType,
                                                          ParameterTypes, ip, CallingConventions.Standard,
                                                          Get.OptAttributes, ModFlags, flags, false);
 
@@ -4698,7 +4673,7 @@ namespace Mono.CSharp {
                                
                                InternalParameters ip = new InternalParameters (container, set_formal_params);
 
-                               SetData = new MethodData (this, "set", TypeManager.void_type,
+                               SetData = new MethodData (container, this, "set", TypeManager.void_type,
                                                          set_pars, ip, CallingConventions.Standard,
                                                          Set.OptAttributes, ModFlags, flags, false);
 
@@ -4872,7 +4847,7 @@ namespace Mono.CSharp {
                                param_list[1] = new Parameter (SecondArgType, SecondArgName,
                                                               Parameter.Modifier.NONE, null);
                        
-                       OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
+                       OperatorMethod = new Method (container, ReturnType, ModFlags, MethodName,
                                                     new Parameters (param_list, null, Location),
                                                     OptAttributes, Location);