public abstract class ParameterBase : Attributable {
protected ParameterBuilder builder;
- public readonly Location Location;
- protected ParameterBase (Attributes attrs, Location loc)
+ protected ParameterBase (Attributes attrs)
: base (attrs)
{
- Location = loc;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
builder.SetCustomAttribute (cb);
}
- public override bool IsClsComplianceRequired(DeclSpace ds)
+ public override bool IsClsComplianceRequired()
{
return false;
}
/// </summary>
public class ReturnParameter : ParameterBase {
public ReturnParameter (MethodBuilder mb, Location location):
- base (null, location)
+ base (null)
{
try {
builder = mb.DefineParameter (0, ParameterAttributes.None, "");
}
catch (ArgumentOutOfRangeException) {
- Report.RuntimeMissingSupport (Location, "custom attributes on the return type");
+ Report.RuntimeMissingSupport (location, "custom attributes on the return type");
}
}
}
}
+ public override IResolveContext ResolveContext {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
/// <summary>
/// Is never called
/// </summary>
///
// TODO: should use more code from Parameter.ApplyAttributeBuilder
public class ImplicitParameter : ParameterBase {
- public ImplicitParameter (MethodBuilder mb, Location loc):
- base (null, loc)
+ public ImplicitParameter (MethodBuilder mb):
+ base (null)
{
builder = mb.DefineParameter (1, ParameterAttributes.None, "");
}
}
}
+ public override IResolveContext ResolveContext {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
/// <summary>
/// Is never called
/// </summary>
{
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (IResolveContext ec)
{
if (!base.Resolve (ec))
return false;
return true;
}
- public override void ApplyAttributes (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
+ public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index)
{
- base.ApplyAttributes (ec, mb, cb, index);
+ base.ApplyAttributes (mb, cb, index);
CustomAttributeBuilder a = new CustomAttributeBuilder (
TypeManager.ConsParamArrayAttribute, new object [0]);
{
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (IResolveContext ec)
{
return true;
}
public Expression TypeName;
public readonly Modifier ModFlags;
- public readonly string Name;
+ public string Name;
+ public bool IsCaptured;
protected Type parameter_type;
+ public readonly Location Location;
+
+ IResolveContext resolve_context;
- EmitContext ec; // because ApplyAtrribute doesn't have ec
+ 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, loc)
+ : base (attrs)
{
Name = name;
ModFlags = mod;
TypeName = type;
+ Location = loc;
}
public Parameter (Type type, string name, Modifier mod, Attributes attrs, Location loc)
- : base (attrs, loc)
+ : base (attrs)
{
Name = name;
ModFlags = mod;
parameter_type = type;
+ Location = loc;
}
public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
}
if (a.Type == TypeManager.out_attribute_type && (ModFlags & Modifier.REF) == Modifier.REF &&
- !OptAttributes.Contains (TypeManager.in_attribute_type, ec)) {
+ !OptAttributes.Contains (TypeManager.in_attribute_type)) {
Report.Error (662, a.Location,
"Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
return;
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
+ if (a.Type == TypeManager.default_parameter_value_attribute_type) {
+ object val = a.GetParameterDefaultValue ();
+ if (val != null) {
+ Type t = val.GetType ();
+ if (t.IsArray || TypeManager.IsSubclassOf (t, TypeManager.type_type)) {
+ if (parameter_type == TypeManager.object_type) {
+ if (!t.IsArray)
+ t = TypeManager.type_type;
+
+ Report.Error (1910, a.Location, "Argument of type `{0}' is not applicable for the DefaultValue attribute",
+ TypeManager.CSharpName (t));
+ } else {
+ Report.Error (1909, a.Location, "The DefaultValue attribute is not applicable on parameters of type `{0}'",
+ TypeManager.CSharpName (parameter_type)); ;
+ }
+ return;
+ }
+ }
+
+ if (parameter_type == TypeManager.object_type ||
+ (val == null && !TypeManager.IsValueType (parameter_type)) ||
+ (val != null && TypeManager.TypeToCoreType (val.GetType ()) == parameter_type))
+ builder.SetConstant (val);
+ else
+ Report.Error (1908, a.Location, "The type of the default value should match the type of the parameter");
+ return;
+ }
+
base.ApplyAttributeBuilder (a, cb);
}
+ public override IResolveContext ResolveContext {
+ get {
+ return resolve_context;
+ }
+ }
+
// <summary>
// Resolve is used in method definitions
// </summary>
- public virtual bool Resolve (EmitContext ec)
+ public virtual bool Resolve (IResolveContext ec)
{
if (parameter_type != null)
return true;
- this.ec = ec;
+ this.resolve_context = ec;
TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return false;
- parameter_type = texpr.ResolveType (ec);
+#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) {
Report.Error (721, Location, "`{0}': static types cannot be used as parameters", GetSignatureForError ());
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)
return parameter_type;
}
}
-
+
+#if GMCS_SOURCE
+ public GenericConstraints GenericConstraints {
+ get {
+ return constraints;
+ }
+ }
+#endif
+
public ParameterAttributes Attributes {
get {
switch (ModFlags) {
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 {
Report.Error (3001, Location, "Argument type `{0}' is not CLS-compliant", GetSignatureForError ());
}
- public virtual void ApplyAttributes (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
+ 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 (ec, this);
+ OptAttributes.Emit ();
}
public override string[] ValidAttributeTargets {
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>
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];
types = new Type [0];
}
+
+ public Parameters (Parameter[] parameters, Type[] types)
+ {
+ FixedParameters = parameters;
+ this.types = types;
+ count = types.Length;
+ }
- public Parameters (Parameter [] parameters)
+ public Parameters (Parameter[] parameters)
{
if (parameters == null)
throw new ArgumentException ("Use EmptyReadOnlyPatameters");
HasArglist = has_arglist;
}
+ /// <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);
+
+ 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 bool Empty {
get {
return count == 0;
return GetParameterByName (name, out idx);
}
- public bool Resolve (EmitContext ec)
+ public bool Resolve (IResolveContext ec)
{
if (types != null)
return true;
types = new Type [count];
- if (ec != null && !VerifyArgs ()){
+ if (!VerifyArgs ())
return false;
- }
bool ok = true;
Parameter p;
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 {
// Define each type attribute (in/out/ref) and
// the argument names.
- public void ApplyAttributes (EmitContext ec, MethodBase builder)
+ public void ApplyAttributes (MethodBase builder)
{
if (count == 0)
return;
ConstructorBuilder cb = builder as ConstructorBuilder;
for (int i = 0; i < FixedParameters.Length; i++) {
- FixedParameters [i].ApplyAttributes (ec, mb, cb, i + 1);
+ FixedParameters [i].ApplyAttributes (mb, cb, i + 1);
}
}
}
if (HasArglist) {
- if (HasArglist) {
- if (sb.Length > 1)
- sb.Append (", ");
- sb.Append ("__arglist");
- }
+ if (sb.Length > 1)
+ sb.Append (", ");
+ sb.Append ("__arglist");
}
sb.Append (')');
}
}
- Parameter this [int pos]
+ public Parameter this [int pos]
{
get {
if (pos >= count && (HasArglist || HasParams)) {