2009-06-17 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / parameter.cs
index c8847e10231c2e521464059f459f7954c551ebff..a6c5c63da7c0b41811e27bc1af73a1f09de97f86 100644 (file)
@@ -30,16 +30,17 @@ namespace Mono.CSharp {
                {
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
                {
-                       if (a.Type == TypeManager.marshal_as_attr_type) {
+#if !NET_2_0
+                       if (a.Type == pa.MarshalAs) {
                                UnmanagedMarshal marshal = a.GetMarshal (this);
                                if (marshal != null) {
                                        builder.SetMarshal (marshal);
                                }
                                return;
                        }
-
+#endif
                        if (a.HasSecurityAttribute) {
                                a.Error_InvalidSecurityParent ();
                                return;
@@ -69,9 +70,9 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
                {
-                       if (a.Type == TypeManager.cls_compliant_attribute_type) {
+                       if (a.Type == pa.CLSCompliant) {
                                Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
                        }
 
@@ -79,7 +80,7 @@ namespace Mono.CSharp {
                        if (builder == null)
                                return;
 
-                       base.ApplyAttributeBuilder (a, cb);
+                       base.ApplyAttributeBuilder (a, cb, pa);
                }
 
                public override AttributeTargets AttributeTargets {
@@ -114,7 +115,7 @@ namespace Mono.CSharp {
                public ImplicitParameter (MethodBuilder mb):
                        base (null)
                {
-                       builder = mb.DefineParameter (1, ParameterAttributes.None, "");                 
+                       builder = mb.DefineParameter (1, ParameterAttributes.None, "value");                    
                }
 
                public override AttributeTargets AttributeTargets {
@@ -142,74 +143,70 @@ namespace Mono.CSharp {
        public class ImplicitLambdaParameter : Parameter
        {
                public ImplicitLambdaParameter (string name, Location loc)
-                       : base ((Type)null, name, Modifier.NONE, null, loc)
+                       : base (null, name, Modifier.NONE, null, loc)
                {
                }
 
-               public override bool Resolve (IResolveContext ec)
+               public override Type Resolve (IResolveContext ec)
                {
                        if (parameter_type == null)
                                throw new InternalErrorException ("A type of implicit lambda parameter `{0}' is not set",
                                        Name);
 
-                       return true;
+                       return parameter_type;
+               }
+
+               public Type Type {
+                       set { parameter_type = value; }
                }
        }
 
        public class ParamsParameter : Parameter {
-               public ParamsParameter (Expression type, string name, Attributes attrs, Location loc):
+               public ParamsParameter (FullNamedExpression type, string name, Attributes attrs, Location loc):
                        base (type, name, Parameter.Modifier.PARAMS, attrs, loc)
                {
                }
 
-               public override bool Resolve (IResolveContext ec)
+               public override Type Resolve (IResolveContext ec)
                {
-                       if (!base.Resolve (ec))
-                               return false;
+                       if (base.Resolve (ec) == null)
+                               return null;
 
                        if (!parameter_type.IsArray || parameter_type.GetArrayRank () != 1) {
                                Report.Error (225, Location, "The params parameter must be a single dimensional array");
-                               return false;
+                               return null;
                        }
-                       return true;
+
+                       return parameter_type;
                }
 
                public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
                {
                        base.ApplyAttributes (mb, cb, index);
-
-                       CustomAttributeBuilder ca = TypeManager.param_array_attr;
-                       if (ca == null) {
-                               ConstructorInfo ci = TypeManager.GetPredefinedConstructor (TypeManager.param_array_type, Location, Type.EmptyTypes);
-                               if (ci == null)
-                                       return;
-
-                               ca = new CustomAttributeBuilder (ci, new object [0]);
-                               if (ca == null)
-                                       return;
-
-                               TypeManager.param_array_attr = ca;
-                       }
-                               
-                       builder.SetCustomAttribute (ca);
+                       PredefinedAttributes.Get.ParamArray.EmitAttribute (builder, Location);
                }
        }
 
        public class ArglistParameter : Parameter {
                // Doesn't have proper type because it's never chosen for better conversion
-               public ArglistParameter () :
-                       base (typeof (ArglistParameter), String.Empty, Parameter.Modifier.ARGLIST, null, Location.Null)
+               public ArglistParameter (Location loc) :
+                       base (null, String.Empty, Parameter.Modifier.ARGLIST, null, loc)
                {
                }
 
+               public override void  ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
+               {
+                       // Nothing to do
+               }
+
                public override bool CheckAccessibility (InterfaceMemberBase member)
                {
                        return true;
                }
 
-               public override bool Resolve (IResolveContext ec)
+               public override Type Resolve (IResolveContext ec)
                {
-                       return true;
+                       return typeof (ArglistParameter);
                }
 
                public override string GetSignatureForError ()
@@ -218,10 +215,19 @@ namespace Mono.CSharp {
                }
        }
 
-       /// <summary>
-       ///   Represents a single method parameter
-       /// </summary>
-       public class Parameter : ParameterBase {
+       public interface IParameterData
+       {
+               Expression DefaultValue { get; }
+               bool HasExtensionMethodModifier { get; }
+               bool HasDefaultValue { get; }
+               Parameter.Modifier ModFlags { get; }
+               string Name { get; }
+       }
+
+       //
+       // Parameter information created by parser
+       //
+       public class Parameter : ParameterBase, IParameterData, ILocalVariable {
                [Flags]
                public enum Modifier : byte {
                        NONE    = 0,
@@ -238,79 +244,64 @@ namespace Mono.CSharp {
 
                static string[] attribute_targets = new string [] { "param" };
 
-               Expression TypeName;
+               protected FullNamedExpression TypeName;
                readonly Modifier modFlags;
-               public string Name;
-               public bool IsCaptured;
+               string name;
+               Expression default_expr;
                protected Type parameter_type;
                public readonly Location Location;
+               int idx;
+               public bool HasAddressTaken;
 
                IResolveContext resolve_context;
                LocalVariableReference expr_tree_variable;
                static TypeExpr parameter_expr_tree_type;
 
-               Variable var;
-               public Variable Variable {
-                       get { return var; }
-               }
+               public HoistedVariable HoistedVariableReference;
 
-#if GMCS_SOURCE
-               public bool IsTypeParameter;
-#else
-               public bool IsTypeParameter {
-                       get {
-                               return false;
-                       }
-                       set {
-                               if (value)
-                                       throw new Exception ("You can not se TypeParameter in MCS");
-                       }
-               }
-#endif
-               
-               public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
-                       : this (type.Type, name, mod, attrs, loc)
+               public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
+                       : base (attrs)
                {
                        if (type == TypeManager.system_void_expr)
                                Report.Error (1536, loc, "Invalid parameter type `void'");
-                       
-                       TypeName = type;
-               }
 
-               public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc)
-                       : base (attrs)
-               {
-                       Name = name;
+                       this.name = name;
                        modFlags = mod;
-                       parameter_type = type;
                        Location = loc;
+                       TypeName = type;
                }
 
-               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
                {
-                       if (a.Type == TypeManager.in_attribute_type && ModFlags == Modifier.OUT) {
+                       if (a.Type == pa.In && ModFlags == Modifier.OUT) {
                                Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
                                return;
                        }
 
-                       if (a.Type == TypeManager.param_array_type) {
+                       if (a.Type == pa.ParamArray) {
                                Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
                                return;
                        }
 
-                       if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF &&
-                           TypeManager.in_attribute_type != null && !OptAttributes.Contains (TypeManager.in_attribute_type)) {
+                       if (a.Type == PredefinedAttributes.Get.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
+                           !OptAttributes.Contains (pa.In)) {
                                Report.Error (662, a.Location,
                                        "Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
                                return;
                        }
 
-                       if (a.Type == TypeManager.cls_compliant_attribute_type) {
+                       if (a.Type == pa.CLSCompliant) {
                                Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
                        }
 
-                       // TypeManager.default_parameter_value_attribute_type is null if !NET_2_0, or if System.dll is not referenced
-                       if (a.Type == TypeManager.default_parameter_value_attribute_type) {
+                       if (HasDefaultValue && (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter)) {
+                               Report.Error (1745, a.Location,
+                                       "Cannot specify `{0}' attribute on optional parameter `{1}'",
+                                       TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
+                               return;
+                       }
+
+                       if (a.Type == pa.DefaultParameterValue) {
                                object val = a.GetParameterDefaultValue ();
                                if (val != null) {
                                        Type t = val.GetType ();
@@ -319,10 +310,10 @@ namespace Mono.CSharp {
                                                        if (!t.IsArray)
                                                                t = TypeManager.type_type;
 
-                                                       Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute",
+                                                       Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultParameterValue attribute",
                                                                TypeManager.CSharpName (t));
                                                } else {
-                                                       Report.Error (1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'",
+                                                       Report.Error (1909, a.Location, "The DefaultParameterValue attribute is not applicable on parameters of type `{0}'",
                                                                TypeManager.CSharpName (parameter_type)); ;
                                                }
                                                return;
@@ -330,7 +321,7 @@ namespace Mono.CSharp {
                                }
 
                                if (parameter_type == TypeManager.object_type ||
-                                   (val == null && !TypeManager.IsValueType (parameter_type)) ||
+                                   (val == null && !TypeManager.IsGenericParameter (parameter_type) && TypeManager.IsReferenceType (parameter_type)) ||
                                    (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
                                        builder.SetConstant (val);
                                else
@@ -338,12 +329,12 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       base.ApplyAttributeBuilder (a, cb);
+                       base.ApplyAttributeBuilder (a, cb, pa);
                }
                
                public virtual bool CheckAccessibility (InterfaceMemberBase member)
                {
-                       if (IsTypeParameter)
+                       if (parameter_type == null || TypeManager.IsGenericParameter (parameter_type))
                                return true;
 
                        return member.IsAccessibleAs (parameter_type);
@@ -358,66 +349,89 @@ namespace Mono.CSharp {
                // <summary>
                //   Resolve is used in method definitions
                // </summary>
-               public virtual bool Resolve (IResolveContext ec)
+               public virtual Type Resolve (IResolveContext rc)
                {
                        // HACK: to resolve attributes correctly
-                       this.resolve_context = ec;
+                       this.resolve_context = rc;
 
                        if (parameter_type != null)
-                               return true;
+                               return parameter_type;
 
-                       TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
+                       TypeExpr texpr = TypeName.ResolveAsTypeTerminal (rc, false);
                        if (texpr == null)
-                               return false;
+                               return null;
 
                        parameter_type = texpr.Type;
 
-#if GMCS_SOURCE
-                       TypeParameterExpr tparam = texpr as TypeParameterExpr;
-                       if (tparam != null) {
-                               IsTypeParameter = true;
-                               return true;
+                       // Ignore all checks for dummy members
+                       AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;
+                       if (pem != null && pem.IsDummy)
+                               return parameter_type;
+
+                       if (default_expr != null) {
+                               EmitContext ec = new EmitContext (rc, rc.GenericDeclContainer, Location, null, parameter_type, 0);
+                               default_expr = default_expr.Resolve (ec);
+                               if (default_expr != null) {
+                                       Constant value = default_expr as Constant;
+                                       if (value == null) {
+                                               if (default_expr != null && !(default_expr is DefaultValueExpression)) {
+                                                       Report.Error (1736, default_expr.Location, "The expression being assigned to optional parameter `{0}' must be constant",
+                                                               Name);
+                                                       default_expr = null;
+                                               }
+                                       } else {
+                                               Constant c = value.ConvertImplicitly (parameter_type);
+                                               if (c == null) {
+                                                       if (parameter_type == TypeManager.object_type) {
+                                                               Report.Error (1763, Location,
+                                                                       "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
+                                                                       Name, GetSignatureForError ());
+                                                       } else {
+                                                               Report.Error (1750, Location,
+                                                                       "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
+                                                                       value.GetValue (), GetSignatureForError ());
+                                                       }
+                                                       default_expr = null;
+                                               }
+                                       }
+                               }
                        }
-#endif
 
-                       if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
-                               Report.Error (721, Location, "`{0}': static types cannot be used as parameters", 
-                                       texpr.GetSignatureForError ());
-                               return false;
+                       if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
+                               TypeManager.IsSpecialType (parameter_type)) {
+                               Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
+                                       GetSignatureForError ());
+                               return null;
                        }
 
-                       if ((modFlags & Parameter.Modifier.ISBYREF) != 0){
-                               if (parameter_type == TypeManager.typed_reference_type ||
-                                   parameter_type == TypeManager.arg_iterator_type){
-                                       Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
-                                               GetSignatureForError ());
-                                       return false;
-                               }
+                       TypeManager.CheckTypeVariance (parameter_type,
+                               (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
+                               rc as MemberCore);
+
+                       if (texpr is TypeParameterExpr)
+                               return parameter_type;
+
+                       if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
+                               Report.Error (721, Location, "`{0}': static types cannot be used as parameters",
+                                       texpr.GetSignatureForError ());
+                               return parameter_type;
                        }
 
                        if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer) {
                                Report.Error (1103, Location, "The type of extension method cannot be `{0}'",
                                        TypeManager.CSharpName (parameter_type));
-                               return false;
                        }
-                       
-                       return true;
+
+                       return parameter_type;
                }
 
-               public void ResolveVariable (ToplevelBlock toplevel, int idx)
+               public void ResolveVariable (int idx)
                {
-                       if (toplevel.RootScope != null)
-                               var = toplevel.RootScope.GetCapturedParameter (this);
-                       if (var == null)
-                               var = new ParameterVariable (this, idx);
+                       this.idx = idx;
                }
 
-               public Type ExternalType ()
-               {
-                       if ((modFlags & Parameter.Modifier.ISBYREF) != 0)
-                               return TypeManager.GetReferenceType (parameter_type);
-                       
-                       return parameter_type;
+               public bool HasDefaultValue {
+                       get { return default_expr != null; }
                }
 
                public bool HasExtensionMethodModifier {
@@ -428,41 +442,16 @@ namespace Mono.CSharp {
                        get { return modFlags & ~Modifier.This; }
                }
 
-               public Type ParameterType {
-                       get {
-                               return parameter_type;
-                       }
-                       set {
-                               parameter_type = value;
-                               IsTypeParameter = false;
-                       }
+               public string Name {
+                       get { return name; }
+                       set { name = value; }
                }
 
                ParameterAttributes Attributes {
-                       get {
-                               return (modFlags & Modifier.OUT) == Modifier.OUT ?
-                                       ParameterAttributes.Out : ParameterAttributes.None;
-                       }
+                       get { return ParametersCompiled.GetParameterAttribute (modFlags) |
+                               (HasDefaultValue ? ParameterAttributes.Optional : ParameterAttributes.None); }
                }
 
-               // TODO: should be removed !!!!!!!
-               public static ParameterAttributes GetParameterAttributes (Modifier mod)
-               {
-                       int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF);
-                       switch ((Modifier) flags) {
-                       case Modifier.NONE:
-                               return ParameterAttributes.None;
-                       case Modifier.REF:
-                               return ParameterAttributes.None;
-                       case Modifier.OUT:
-                               return ParameterAttributes.Out;
-                       case Modifier.PARAMS:
-                               return 0;
-                       }
-                               
-                       return ParameterAttributes.None;
-               }
-               
                public override AttributeTargets AttributeTargets {
                        get {
                                return AttributeTargets.Parameter;
@@ -479,7 +468,7 @@ namespace Mono.CSharp {
 
                        string mod = GetModifierSignature (modFlags);
                        if (mod.Length > 0)
-                               return String.Concat (mod, ' ', type_name);
+                               return String.Concat (mod, " ", type_name);
 
                        return type_name;
                }
@@ -487,41 +476,51 @@ namespace Mono.CSharp {
                public static string GetModifierSignature (Modifier mod)
                {
                        switch (mod) {
-                               case Modifier.OUT:
-                                       return "out";
-                               case Modifier.PARAMS:
-                                       return "params";
-                               case Modifier.REF:
-                                       return "ref";
-                               case Modifier.ARGLIST:
-                                       return "__arglist";
-                               case Modifier.This:
-                                       return "this";
-                               default:
-                                       return "";
+                       case Modifier.OUT:
+                               return "out";
+                       case Modifier.PARAMS:
+                               return "params";
+                       case Modifier.REF:
+                               return "ref";
+                       case Modifier.This:
+                               return "this";
+                       default:
+                               return "";
                        }
                }
 
                public void IsClsCompliant ()
                {
-                       if (AttributeTester.IsClsCompliant (ExternalType ()))
+                       if (AttributeTester.IsClsCompliant (parameter_type))
                                return;
 
-                       Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
+                       Report.Warning (3001, 1, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
                }
 
                public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
                {
-#if !GMCS_SOURCE || !MS_COMPATIBLE
-                       // TODO: It should use mb.DefineGenericParameters
                        if (mb == null)
                                builder = cb.DefineParameter (index, Attributes, Name);
-                       else 
+                       else
                                builder = mb.DefineParameter (index, Attributes, Name);
-#endif
 
                        if (OptAttributes != null)
                                OptAttributes.Emit ();
+
+                       if (HasDefaultValue) {
+                               //
+                               // Emit constant values for true constants only, the other
+                               // constant-like expressions will rely on default value expression
+                               //
+                               Constant c = default_expr as Constant;
+                               if (c != null) {
+                                       if (default_expr.Type == TypeManager.decimal_type) {
+                                               builder.SetCustomAttribute (Const.CreateDecimalConstantAttribute (c));
+                                       } else {
+                                               builder.SetConstant (c.GetValue ());
+                                       }
+                               }
+                       }
                }
 
                public override string[] ValidAttributeTargets {
@@ -530,87 +529,24 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected class ParameterVariable : Variable
-               {
-                       public readonly Parameter Parameter;
-                       public readonly int Idx;
-                       public readonly bool IsRef;
-
-                       public ParameterVariable (Parameter par, int idx)
-                       {
-                               this.Parameter = par;
-                               this.Idx = idx;
-                               this.IsRef = (par.ModFlags & Parameter.Modifier.ISBYREF) != 0;
-                       }
-
-                       public override Type Type {
-                               get { return Parameter.ParameterType; }
-                       }
-
-                       public override bool HasInstance {
-                               get { return false; }
-                       }
-
-                       public override bool NeedsTemporary {
-                               get { return false; }
-                       }
-
-                       public override void EmitInstance (EmitContext ec)
-                       {
-                       }
-
-                       public override void Emit (EmitContext ec)
-                       {
-                               int arg_idx = Idx;
-                               if (!ec.MethodIsStatic)
-                                       arg_idx++;
-
-                               ParameterReference.EmitLdArg (ec.ig, arg_idx);
-                       }
-
-                       public override void EmitAssign (EmitContext ec)
-                       {
-                               int arg_idx = Idx;
-                               if (!ec.MethodIsStatic)
-                                       arg_idx++;
-
-                               if (arg_idx <= 255)
-                                       ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
-                               else
-                                       ec.ig.Emit (OpCodes.Starg, arg_idx);
-                       }
-
-                       public override void EmitAddressOf (EmitContext ec)
-                       {
-                               int arg_idx = Idx;
-
-                               if (!ec.MethodIsStatic)
-                                       arg_idx++;
-
-                               if (IsRef) {
-                                       if (arg_idx <= 255)
-                                               ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
-                                       else
-                                               ec.ig.Emit (OpCodes.Ldarg, arg_idx);
-                               } else {
-                                       if (arg_idx <= 255)
-                                               ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
-                                       else
-                                               ec.ig.Emit (OpCodes.Ldarga, arg_idx);
-                               }
-                       }
-               }
-
                public Parameter Clone ()
                {
-                       Parameter p = new Parameter (parameter_type, Name, modFlags, attributes, Location);
-                       p.IsTypeParameter = IsTypeParameter;
+                       Parameter p = (Parameter) MemberwiseClone ();
+                       if (attributes != null) {
+                               p.attributes = attributes.Clone ();
+                               p.attributes.AttachTo (p);
+                       }
 
                        return p;
                }
 
                public ExpressionStatement CreateExpressionTreeVariable (EmitContext ec)
                {
+                       //
+                       // A parameter is not hoisted when used directly as ET
+                       //
+                       HoistedVariableReference = null;
+
                        if ((modFlags & Modifier.ISBYREF) != 0)
                                Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
 
@@ -625,10 +561,54 @@ namespace Mono.CSharp {
                        arguments.Add (new Argument (new TypeOf (
                                new TypeExpression (parameter_type, Location), Location)));
                        arguments.Add (new Argument (new StringConstant (Name, Location)));
-                       return new Assign (ExpressionTreeVariableReference (),
+                       return new SimpleAssign (ExpressionTreeVariableReference (),
                                Expression.CreateExpressionFactoryCall ("Parameter", null, arguments, Location));
                }
 
+               public Expression DefaultValue {
+                       get { return default_expr; }
+                       set { default_expr = value; }
+               }
+
+               public void Emit (EmitContext ec)
+               {
+                       int arg_idx = idx;
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       ParameterReference.EmitLdArg (ec.ig, arg_idx);
+               }
+
+               public void EmitAssign (EmitContext ec)
+               {
+                       int arg_idx = idx;
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       if (arg_idx <= 255)
+                               ec.ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+                       else
+                               ec.ig.Emit (OpCodes.Starg, arg_idx);
+               }
+
+               public void EmitAddressOf (EmitContext ec)
+               {
+                       int arg_idx = idx;
+
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;
+                       if (is_ref) {
+                               ParameterReference.EmitLdArg (ec.ig, arg_idx);
+                       } else {
+                               if (arg_idx <= 255)
+                                       ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+                               else
+                                       ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+                       }
+               }
+
                public Expression ExpressionTreeVariableReference ()
                {
                        return expr_tree_variable;
@@ -653,106 +633,77 @@ namespace Mono.CSharp {
 
                        return parameter_expr_tree_type;
                }
-       }
-
-       /// <summary>
-       ///   Represents the methods parameters
-       /// </summary>
-       public class Parameters : ParameterData {
-               // Null object pattern
-               public Parameter [] FixedParameters;
-               public readonly bool HasArglist;
-               Type [] types;
-               int count;
 
-               public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
-               static readonly Parameter ArgList = new ArglistParameter ();
+               public void Warning_UselessOptionalParameter ()
+               {
+                       Report.Warning (1066, 1, Location,
+                               "The default value specified for optional parameter `{0}' will never be used",
+                               Name);
+               }
+       }
 
-#if GMCS_SOURCE
-//             public readonly TypeParameter[] TypeParameters;
-#endif
+       //
+       // Imported or resolved parameter information
+       //
+       public class ParameterData : IParameterData
+       {
+               readonly string name;
+               readonly Parameter.Modifier modifiers;
+               readonly Expression default_value;
 
-               private Parameters ()
+               public ParameterData (string name, Parameter.Modifier modifiers)
                {
-                       FixedParameters = new Parameter[0];
-                       types = new Type [0];
+                       this.name = name;
+                       this.modifiers = modifiers;
                }
 
-               private Parameters (Parameter[] parameters, Type[] types)
+               public ParameterData (string name, Parameter.Modifier modifiers, Expression defaultValue)
+                       : this (name, modifiers)
                {
-                       FixedParameters = parameters;
-                       this.types = types;
-                       count = types.Length;
+                       this.default_value = defaultValue;
                }
-               
-               public Parameters (params Parameter[] parameters)
-               {
-                       if (parameters == null)
-                               throw new ArgumentException ("Use EmptyReadOnlyPatameters");
 
-                       FixedParameters = parameters;
-                       count = parameters.Length;
-               }
+               #region IParameterData Members
 
-               public Parameters (Parameter[] parameters, bool has_arglist):
-                       this (parameters)
-               {
-                       HasArglist = has_arglist;
+               public Expression DefaultValue {
+                       get { return default_value; }
                }
-               
-               public static Parameters CreateFullyResolved (Parameter p)
-               {
-                       return new Parameters (new Parameter [] { p }, new Type [] { p.ParameterType });
-               }
-               
-               public static Parameters CreateFullyResolved (Parameter[] parameters, Type[] types)
-               {
-                       return new Parameters (parameters, types);
+
+               public bool HasExtensionMethodModifier {
+                       get { return (modifiers & Parameter.Modifier.This) != 0; }
                }
 
-               /// <summary>
-               /// Use this method when you merge compiler generated argument with user arguments
-               /// </summary>
-               public static Parameters MergeGenerated (Parameters userParams, params Parameter[] compilerParams)
-               {
-                       Parameter[] all_params = new Parameter [userParams.count + compilerParams.Length];
-                       Type[] all_types = new Type[all_params.Length];
-                       userParams.FixedParameters.CopyTo(all_params, 0);
-                       userParams.Types.CopyTo (all_types, 0);
+               public bool HasDefaultValue {
+                       get { return default_value != null; }
+               }
 
-                       int last_filled = userParams.Count;
-                       foreach (Parameter p in compilerParams) {
-                               for (int i = 0; i < last_filled; ++i) {
-                                       while (p.Name == all_params [i].Name) {
-                                               p.Name = '_' + p.Name;
-                                       }
-                               }
-                               all_params [last_filled] = p;
-                               all_types [last_filled] = p.ParameterType;
-                               ++last_filled;
-                       }
-                       
-                       return new Parameters (all_params, all_types);
+               public Parameter.Modifier ModFlags {
+                       get { return modifiers & ~Parameter.Modifier.This; }
                }
 
-               public bool Empty {
-                       get {
-                               return count == 0;
-                       }
+               public string Name {
+                       get { return name; }
                }
 
+               #endregion
+       }
+
+       public abstract class AParametersCollection
+       {
+               protected bool has_arglist;
+               protected bool has_params;
+
+               // Null object pattern
+               protected IParameterData [] parameters;
+               protected Type [] types;
+
                public int Count {
-                       get {
-                               return HasArglist ? count + 1 : count;
-                       }
+                       get { return parameters.Length; }
                }
 
-               //
-               // The property can be used after parameter types were resolved.
-               //
                public Type ExtensionMethodType {
                        get {
-                               if (count == 0)
+                               if (Count == 0)
                                        return null;
 
                                return FixedParameters [0].HasExtensionMethodModifier ?
@@ -760,129 +711,107 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool HasExtensionMethodType {
+               public IParameterData [] FixedParameters {
                        get {
-                               if (count == 0)
-                                       return false;
-
-                               return FixedParameters [0].HasExtensionMethodModifier;
+                               return parameters;
                        }
                }
 
-
-               bool VerifyArgs ()
+               public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
                {
-                       if (count < 2)
-                               return true;
+                       return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
+                               ParameterAttributes.Out : ParameterAttributes.None;
+               }
 
-                       for (int i = 0; i < count; i++){
-                               string base_name = FixedParameters [i].Name;
-                               for (int j = i + 1; j < count; j++){
-                                       if (base_name != FixedParameters [j].Name)
-                                               continue;
+               public Type [] GetEmitTypes ()
+               {
+                       Type [] types = null;
+                       if (has_arglist) {
+                               if (Count == 1)
+                                       return Type.EmptyTypes;
 
-                                       Report.Error (100, FixedParameters [i].Location,
-                                               "The parameter name `{0}' is a duplicate", base_name);
-                                       return false;
-                               }
+                               types = new Type [Count - 1];
+                               Array.Copy (Types, types, types.Length);
                        }
-                       return true;
-               }
-               
-               
-               /// <summary>
-               ///    Returns the paramenter information based on the name
-               /// </summary>
-               public Parameter GetParameterByName (string name, out int idx)
-               {
-                       idx = 0;
 
-                       if (count == 0)
-                               return null;
+                       for (int i = 0; i < Count; ++i) {
+                               if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
+                                       continue;
 
-                       int i = 0;
+                               if (types == null)
+                                       types = (Type []) Types.Clone ();
 
-                       foreach (Parameter par in FixedParameters){
-                               if (par.Name == name){
-                                       idx = i;
-                                       return par;
-                               }
-                               i++;
+                               types [i] = TypeManager.GetReferenceType (types [i]);
                        }
-                       return null;
+
+                       if (types == null)
+                               types = Types;
+
+                       return types;
                }
 
-               public Parameter GetParameterByName (string name)
+               public string GetSignatureForError ()
                {
-                       int idx;
+                       StringBuilder sb = new StringBuilder ("(");
+                       for (int i = 0; i < Count; ++i) {
+                               if (i != 0)
+                                       sb.Append (", ");
+                               sb.Append (ParameterDesc (i));
+                       }
+                       sb.Append (')');
+                       return sb.ToString ();
+               }
 
-                       return GetParameterByName (name, out idx);
+               public bool HasArglist {
+                       get { return has_arglist; }
                }
-               
-               public bool Resolve (IResolveContext ec)
-               {
-                       if (types != null)
-                               return true;
 
-                       types = new Type [count];
-                       
-                       if (!VerifyArgs ())
-                               return false;
+               public bool HasExtensionMethodType {
+                       get {
+                               if (Count == 0)
+                                       return false;
 
-                       bool ok = true;
-                       Parameter p;
-                       for (int i = 0; i < FixedParameters.Length; ++i) {
-                               p = FixedParameters [i];
-                               if (!p.Resolve (ec)) {
-                                       ok = false;
-                                       continue;
-                               }
-                               types [i] = p.ExternalType ();
+                               return FixedParameters [0].HasExtensionMethodModifier;
                        }
-
-                       return ok;
                }
 
-               public void ResolveVariable (ToplevelBlock toplevel)
-               {
-                       for (int i = 0; i < FixedParameters.Length; ++i) {
-                               Parameter p = FixedParameters [i];
-                               p.ResolveVariable (toplevel, i);
-                       }
+               public bool HasParams {
+                       get { return has_params; }
                }
 
-               public CallingConventions CallingConvention
-               {
-                       get {
-                               if (HasArglist)
-                                       return CallingConventions.VarArgs;
-                               else
-                                       return CallingConventions.Standard;
-                       }
+               public bool IsEmpty {
+                       get { return parameters.Length == 0; }
                }
 
-               // Define each type attribute (in/out/ref) and
-               // the argument names.
-               public void ApplyAttributes (MethodBase builder)
+               public string ParameterDesc (int pos)
                {
-                       if (count == 0)
-                               return;
+                       if (types == null || types [pos] == null)
+                               return ((Parameter)FixedParameters [pos]).GetSignatureForError ();
 
-                       MethodBuilder mb = builder as MethodBuilder;
-                       ConstructorBuilder cb = builder as ConstructorBuilder;
+                       string type = TypeManager.CSharpName (types [pos]);
+                       if (FixedParameters [pos].HasExtensionMethodModifier)
+                               return "this " + type;
 
-                       for (int i = 0; i < FixedParameters.Length; i++) {
-                               FixedParameters [i].ApplyAttributes (mb, cb, i + 1);
-                       }
+                       Parameter.Modifier mod = FixedParameters [pos].ModFlags & ~Parameter.Modifier.ARGLIST;
+                       if (mod == 0)
+                               return type;
+
+                       return Parameter.GetModifierSignature (mod) + " " + type;
+               }
+
+               public Type[] Types {
+                       get { return types; }
+                       set { types = value; }
                }
 
 #if MS_COMPATIBLE
-               public ParameterData InflateTypes (Type[] genArguments, Type[] argTypes)
+               public AParametersCollection InflateTypes (Type[] genArguments, Type[] argTypes)
                {
-                       Parameters p = Clone ();
-                       for (int i = 0; i < count; ++i) {
+                       AParametersCollection p = (AParametersCollection) MemberwiseClone (); // Clone ();
+
+                       for (int i = 0; i < Count; ++i) {
                                if (types[i].IsGenericType) {
-                                       Type[] gen_arguments_open = new Type [types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
+                                       Type[] gen_arguments_open = new Type[types[i].GetGenericTypeDefinition ().GetGenericArguments ().Length];
                                        Type[] gen_arguments = types[i].GetGenericArguments ();
                                        for (int ii = 0; ii < gen_arguments_open.Length; ++ii) {
                                                if (gen_arguments[ii].IsGenericParameter) {
@@ -892,14 +821,13 @@ namespace Mono.CSharp {
                                                        gen_arguments_open[ii] = gen_arguments[ii];
                                        }
 
-                                       p.FixedParameters [i].ParameterType = p.types[i] =
-                                               types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
+                                       p.types[i] = types[i].GetGenericTypeDefinition ().MakeGenericType (gen_arguments_open);
                                        continue;
                                }
 
                                if (types[i].IsGenericParameter) {
                                        Type gen_argument = argTypes[types[i].GenericParameterPosition];
-                                       p.FixedParameters[i].ParameterType = p.types[i] = gen_argument;
+                                       p.types[i] = gen_argument;
                                        continue;
                                }
                        }
@@ -907,98 +835,336 @@ namespace Mono.CSharp {
                        return p;
                }
 #endif
+       }
 
-               public void VerifyClsCompliance ()
+       //
+       // A collection of imported or resolved parameters
+       //
+       public class ParametersImported : AParametersCollection
+       {
+               ParametersImported (AParametersCollection param, Type[] types)
                {
-                       foreach (Parameter p in FixedParameters)
-                               p.IsClsCompliant ();
+                       this.parameters = param.FixedParameters;
+                       this.types = types;
+                       has_arglist = param.HasArglist;
+                       has_params = param.HasParams;
                }
 
-               public string GetSignatureForError ()
+               ParametersImported (IParameterData [] parameters, Type [] types, MethodBase method, bool hasParams)
                {
-                       StringBuilder sb = new StringBuilder ("(");
-                       if (count > 0) {
-                               for (int i = 0; i < FixedParameters.Length; ++i) {
-                                       sb.Append (FixedParameters[i].GetSignatureForError ());
-                                       if (i < FixedParameters.Length - 1)
-                                               sb.Append (", ");
-                               }
+                       this.parameters = parameters;
+                       this.types = types;
+                       has_arglist = (method.CallingConvention & CallingConventions.VarArgs) != 0;
+                       if (has_arglist) {
+                               this.parameters = new IParameterData [parameters.Length + 1];
+                               parameters.CopyTo (this.parameters, 0);
+                               this.parameters [parameters.Length] = new ArglistParameter (Location.Null);
+                               this.types = new Type [types.Length + 1];
+                               types.CopyTo (this.types, 0);
+                               this.types [types.Length] = TypeManager.arg_iterator_type;
                        }
+                       has_params = hasParams;
+               }
 
-                       if (HasArglist) {
-                               if (sb.Length > 1)
-                                       sb.Append (", ");
-                               sb.Append ("__arglist");
+               public ParametersImported (IParameterData [] param, Type[] types)
+               {
+                       this.parameters = param;
+                       this.types = types;
+               }
+
+               public static AParametersCollection Create (MethodBase method)
+               {
+                       return Create (method.GetParameters (), method);
+               }
+
+               //
+               // Generic method parameters importer, param is shared between all instances
+               //
+               public static AParametersCollection Create (AParametersCollection param, MethodBase method)
+               {
+                       if (param.IsEmpty)
+                               return param;
+
+                       ParameterInfo [] pi = method.GetParameters ();
+                       Type [] types = new Type [pi.Length];
+                       for (int i = 0; i < types.Length; i++) {
+                               Type t = pi [i].ParameterType;
+                               if (t.IsByRef)
+                                       t = TypeManager.GetElementType (t);
+
+                               types [i] = TypeManager.TypeToCoreType (t);
                        }
 
-                       sb.Append (')');
-                       return sb.ToString ();
+                       return new ParametersImported (param, types);
                }
 
-               public Type[] Types {
-                       get {
-                               return types;
+               //
+               // Imports SRE parameters
+               //
+               public static AParametersCollection Create (ParameterInfo [] pi, MethodBase method)
+               {
+                       if (pi.Length == 0) {
+                               if (method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0)
+                                       return new ParametersImported (new IParameterData [0], Type.EmptyTypes, method, false);
+
+                               return ParametersCompiled.EmptyReadOnlyParameters;
                        }
-                       //
-                       // Dangerous, used by implicit lambda parameters
-                       // only to workaround bad design
-                       //
-                       set {
-                               types = value;
+
+                       Type [] types = new Type [pi.Length];
+                       IParameterData [] par = new IParameterData [pi.Length];
+                       bool is_params = false;
+                       PredefinedAttribute extension_attr = PredefinedAttributes.Get.Extension;
+                       PredefinedAttribute param_attr = PredefinedAttributes.Get.ParamArray;
+                       for (int i = 0; i < types.Length; i++) {
+                               types [i] = TypeManager.TypeToCoreType (pi [i].ParameterType);
+
+                               ParameterInfo p = pi [i];
+                               Parameter.Modifier mod = 0;
+                               Expression default_value = null;
+                               if (types [i].IsByRef) {
+                                       if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
+                                               mod = Parameter.Modifier.OUT;
+                                       else
+                                               mod = Parameter.Modifier.REF;
+
+                                       //
+                                       // Strip reference wrapping
+                                       //
+                                       types [i] = TypeManager.GetElementType (types [i]);
+                               } else if (i == 0 && extension_attr.IsDefined && method != null && method.IsStatic &&
+                               (method.DeclaringType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
+                                       method.IsDefined (extension_attr.Type, false)) {
+                                       mod = Parameter.Modifier.This;
+                               } else {
+                                       if (i >= pi.Length - 2) {
+                                               if (types[i].IsArray) {
+                                                       if (p.IsDefined (param_attr.Type, false)) {
+                                                               mod = Parameter.Modifier.PARAMS;
+                                                               is_params = true;
+                                                       }
+                                               } else if (types[i] == TypeManager.runtime_argument_handle_type) {
+                                                       par[i] = new ArglistParameter (Location.Null);
+                                                       continue;
+                                               }
+                                       }
+
+                                       if (!is_params && p.IsOptional) {
+                                               if (p.DefaultValue == Missing.Value)
+                                                       default_value = EmptyExpression.Null;
+                                               else
+                                                       default_value = Constant.CreateConstant (types[i], p.DefaultValue, Location.Null);
+                                       }
+                               }
+
+                               par [i] = new ParameterData (p.Name, mod, default_value);
                        }
+
+                       return method != null ?
+                               new ParametersImported (par, types, method, is_params) :
+                               new ParametersImported (par, types);
                }
+       }
 
-               public Parameter this [int pos]
+       /// <summary>
+       ///   Represents the methods parameters
+       /// </summary>
+       public class ParametersCompiled : AParametersCollection
+       {
+               public static readonly ParametersCompiled EmptyReadOnlyParameters = new ParametersCompiled ();
+               
+               // Used by C# 2.0 delegates
+               public static readonly ParametersCompiled Undefined = new ParametersCompiled ();
+
+               private ParametersCompiled ()
                {
-                       get {
-                               if (pos >= count && (HasArglist || HasParams)) {
-                                       if (HasArglist && (pos == 0 || pos >= count))
-                                               return ArgList;
-                                       pos = count - 1;
-                               }
+                       parameters = new Parameter [0];
+                       types = Type.EmptyTypes;
+               }
+
+               private ParametersCompiled (Parameter [] parameters, Type [] types)
+               {
+                       this.parameters = parameters;
+                   this.types = types;
+               }
+               
+               public ParametersCompiled (params Parameter[] parameters)
+               {
+                       if (parameters == null)
+                               throw new ArgumentException ("Use EmptyReadOnlyParameters");
+
+                       this.parameters = parameters;
+                       int count = parameters.Length;
+
+                       if (count == 0)
+                               return;
+
+                       if (count == 1) {
+                               has_params = (parameters [0].ModFlags & Parameter.Modifier.PARAMS) != 0;
+                               return;
+                       }
 
-                               return FixedParameters [pos];
+                       for (int i = 0; i < count; i++){
+                               string base_name = parameters [i].Name;
+                               has_params |= (parameters [i].ModFlags & Parameter.Modifier.PARAMS) != 0;
+
+                               for (int j = i + 1; j < count; j++){
+                                       if (base_name != parameters [j].Name)
+                                               continue;
+
+                                       ErrorDuplicateName (parameters [i]);
+                                       i = j;
+                               }
                        }
                }
 
-               #region ParameterData Members
+               public ParametersCompiled (Parameter [] parameters, bool has_arglist) :
+                       this (parameters)
+               {
+                       this.has_arglist = has_arglist;
+               }
+               
+               public static ParametersCompiled CreateFullyResolved (Parameter p, Type type)
+               {
+                       return new ParametersCompiled (new Parameter [] { p }, new Type [] { type });
+               }
+               
+               public static ParametersCompiled CreateFullyResolved (Parameter[] parameters, Type[] types)
+               {
+                       return new ParametersCompiled (parameters, types);
+               }
 
-               public Type ParameterType (int pos)
+               public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter compilerParams, Type compilerTypes)
                {
-                       return this [pos].ExternalType ();
+                       return MergeGenerated (userParams, checkConflicts,
+                               new Parameter [] { compilerParams },
+                               new Type [] { compilerTypes });
                }
 
-               public bool HasParams {
-                       get {
-                               if (count == 0)
-                                       return false;
+               //
+               // Use this method when you merge compiler generated parameters with user parameters
+               //
+               public static ParametersCompiled MergeGenerated (ParametersCompiled userParams, bool checkConflicts, Parameter[] compilerParams, Type[] compilerTypes)
+               {
+                       Parameter[] all_params = new Parameter [userParams.Count + compilerParams.Length];
+                       userParams.FixedParameters.CopyTo(all_params, 0);
+
+                       Type [] all_types;
+                       if (userParams.types != null) {
+                               all_types = new Type [all_params.Length];
+                               userParams.Types.CopyTo (all_types, 0);
+                       } else {
+                               all_types = null;
+                       }
 
-                               for (int i = count; i != 0; --i) {
-                                       if ((FixedParameters [i - 1].ModFlags & Parameter.Modifier.PARAMS) != 0)
-                                               return true;
+                       int last_filled = userParams.Count;
+                       int index = 0;
+                       foreach (Parameter p in compilerParams) {
+                               for (int i = 0; i < last_filled; ++i) {
+                                       while (p.Name == all_params [i].Name) {
+                                               if (checkConflicts && i < userParams.Count) {
+                                                       Report.Error (316, userParams [i].Location,
+                                                               "The parameter name `{0}' conflicts with a compiler generated name", p.Name);
+                                               }
+                                               p.Name = '_' + p.Name;
+                                       }
                                }
-                               return false;
+                               all_params [last_filled] = p;
+                               if (all_types != null)
+                                       all_types [last_filled] = compilerTypes [index++];
+                               ++last_filled;
                        }
+                       
+                       ParametersCompiled parameters = new ParametersCompiled (all_params, all_types);
+                       parameters.has_params = userParams.has_params;
+                       return parameters;
                }
 
-               public string ParameterName (int pos)
+               protected virtual void ErrorDuplicateName (Parameter p)
                {
-                       return this [pos].Name;
+                       Report.Error (100, p.Location, "The parameter name `{0}' is a duplicate", p.Name);
                }
 
-               public string ParameterDesc (int pos)
+               /// <summary>
+               ///    Returns the parameter information based on the name
+               /// </summary>
+               public int GetParameterIndexByName (string name)
+               {
+                       for (int idx = 0; idx < Count; ++idx) {
+                               if (parameters [idx].Name == name)
+                                       return idx;
+                       }
+
+                       return -1;
+               }
+
+               public bool Resolve (IResolveContext ec)
+               {
+                       if (types != null)
+                               return true;
+                       
+                       types = new Type [Count];
+                       
+                       bool ok = true;
+                       Parameter p;
+                       for (int i = 0; i < FixedParameters.Length; ++i) {
+                               p = this [i];
+                               Type t = p.Resolve (ec);
+                               if (t == null) {
+                                       ok = false;
+                                       continue;
+                               }
+
+                               types [i] = t;
+                       }
+
+                       return ok;
+               }
+
+               public void ResolveVariable ()
                {
-                       return this [pos].GetSignatureForError ();
+                       for (int i = 0; i < FixedParameters.Length; ++i) {
+                               this [i].ResolveVariable (i);
+                       }
                }
 
-               public Parameter.Modifier ParameterModifier (int pos)
+               public CallingConventions CallingConvention
                {
-                       return this [pos].ModFlags;
+                       get {
+                               if (HasArglist)
+                                       return CallingConventions.VarArgs;
+                               else
+                                       return CallingConventions.Standard;
+                       }
+               }
+
+               // Define each type attribute (in/out/ref) and
+               // the argument names.
+               public void ApplyAttributes (MethodBase builder)
+               {
+                       if (Count == 0)
+                               return;
+
+                       MethodBuilder mb = builder as MethodBuilder;
+                       ConstructorBuilder cb = builder as ConstructorBuilder;
+
+                       for (int i = 0; i < Count; i++) {
+                               this [i].ApplyAttributes (mb, cb, i + 1);
+                       }
+               }
+
+               public void VerifyClsCompliance ()
+               {
+                       foreach (Parameter p in FixedParameters)
+                               p.IsClsCompliant ();
+               }
+
+               public Parameter this [int pos] {
+                       get { return (Parameter) parameters [pos]; }
                }
 
                public Expression CreateExpressionTree (EmitContext ec, Location loc)
                {
-                       ArrayList initializers = new ArrayList (count);
+                       ArrayList initializers = new ArrayList (Count);
                        foreach (Parameter p in FixedParameters) {
                                //
                                // Each parameter expression is stored to local variable
@@ -1016,18 +1182,15 @@ namespace Mono.CSharp {
                                "[]", initializers, loc);
                }
 
-               public Parameters Clone ()
+               public ParametersCompiled Clone ()
                {
-                       Parameter [] parameters_copy = new Parameter [FixedParameters.Length];
-                       int i = 0;
-                       foreach (Parameter p in FixedParameters)
-                               parameters_copy [i++] = p.Clone ();
-                       Parameters ps = new Parameters (parameters_copy, HasArglist);
-                       if (types != null)
-                               ps.types = (Type[])types.Clone ();
-                       return ps;
+                       ParametersCompiled p = (ParametersCompiled) MemberwiseClone ();
+
+                       p.parameters = new IParameterData [parameters.Length];
+                       for (int i = 0; i < Count; ++i)
+                               p.parameters [i] = this [i].Clone ();
+
+                       return p;
                }
-               
-               #endregion
        }
 }