merge r67228-r67235, r67237, r67251 and r67256-67259 to trunk (they are
[mono.git] / mcs / mcs / parameter.cs
index c579d9edd576ab24fa8f3e9f0c4fd6735e705092..ef0d3f7a20f98c0553555f6ec95bd67aa86a586f 100644 (file)
@@ -208,10 +208,20 @@ namespace Mono.CSharp {
                public Expression TypeName;
                public readonly Modifier ModFlags;
                public string Name;
+               public bool IsCaptured;
                protected Type parameter_type;
                public readonly Location Location;
 
                IResolveContext resolve_context;
+
+               Variable var;
+               public Variable Variable {
+                       get { return var; }
+               }
+
+#if GMCS_SOURCE
+               GenericConstraints constraints;
+#endif
                
                public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
                        : base (attrs)
@@ -306,6 +316,12 @@ namespace Mono.CSharp {
                        if (texpr == null)
                                return false;
 
+#if GMCS_SOURCE
+                       TypeParameterExpr tparam = texpr as TypeParameterExpr;
+                       if (tparam != null)
+                               constraints = tparam.TypeParameter.Constraints;
+#endif
+
                        parameter_type = texpr.Type;
                        
                        if (parameter_type.IsAbstract && parameter_type.IsSealed) {
@@ -330,6 +346,14 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public void ResolveVariable (ToplevelBlock toplevel, int idx)
+               {
+                       if (toplevel.AnonymousMethodHost != null)
+                               var = toplevel.AnonymousMethodHost.GetCapturedParameter (this);
+                       if (var == null)
+                               var = new ParameterVariable (this, idx);
+               }
+
                public Type ExternalType ()
                {
                        if ((ModFlags & Parameter.Modifier.ISBYREF) != 0)
@@ -343,7 +367,15 @@ namespace Mono.CSharp {
                                return parameter_type;
                        }
                }
-               
+
+#if GMCS_SOURCE
+               public GenericConstraints GenericConstraints {
+                       get {
+                               return constraints;
+                       }
+               }
+#endif
+
                public ParameterAttributes Attributes {
                        get {
                                switch (ModFlags) {
@@ -360,6 +392,23 @@ namespace Mono.CSharp {
                                return ParameterAttributes.None;
                        }
                }
+
+               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 {
@@ -408,11 +457,14 @@ namespace Mono.CSharp {
 
                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 
                                builder = mb.DefineParameter (index, Attributes, Name);
-               
+#endif
+
                        if (OptAttributes != null)
                                OptAttributes.Emit ();
                }
@@ -422,6 +474,78 @@ namespace Mono.CSharp {
                                return attribute_targets;
                        }
                }
+
+               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);
+                               }
+                       }
+               }
+
        }
 
        /// <summary>
@@ -437,6 +561,10 @@ namespace Mono.CSharp {
                public static readonly Parameters EmptyReadOnlyParameters = new Parameters ();
                static readonly Parameter ArgList = new ArglistParameter ();
 
+#if GMCS_SOURCE
+               public readonly TypeParameter[] TypeParameters;
+#endif
+
                private Parameters ()
                {
                        FixedParameters = new Parameter[0];
@@ -575,6 +703,14 @@ namespace Mono.CSharp {
                        return ok;
                }
 
+               public void ResolveVariable (ToplevelBlock toplevel)
+               {
+                       for (int i = 0; i < FixedParameters.Length; ++i) {
+                               Parameter p = FixedParameters [i];
+                               p.ResolveVariable (toplevel, i);
+                       }
+               }
+
                public CallingConventions CallingConvention
                {
                        get {
@@ -633,7 +769,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               Parameter this [int pos]
+               public Parameter this [int pos]
                {
                        get {
                                if (pos >= count && (HasArglist || HasParams)) {