Type [] param_types;
Type ret_type;
+
+ static string[] attribute_targets = new string [] { "type", "return" };
Expression instance_expr;
MethodBase delegate_method;
+ ReturnParameter return_attributes;
const int AllowedModifiers =
Modifiers.NEW |
ModFlags = Modifiers.Check (AllowedModifiers, mod_flags,
IsTopLevel ? Modifiers.INTERNAL :
Modifiers.PRIVATE, l);
- Parameters = param_list;\r }
+ Parameters = param_list;
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (InvokeBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
public override TypeBuilder DefineType ()
{
{
MethodAttributes mattr;
int i;
- ParameterBuilder pb;
- Attributes cattr;
EmitContext ec = new EmitContext (this, this, Location, null,
null, ModFlags, false);
for (; i < top; i++) {
p = Parameters.FixedParameters [i];
- pb = InvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);
- cattr = p.OptAttributes;
- if (cattr != null)
- Attribute.ApplyAttributes (ec, pb, pb, cattr);
+ p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location);
if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0)
out_params++;
}
if (Parameters.ArrayParameter != null){
Parameter p = Parameters.ArrayParameter;
-
- pb = InvokeBuilder.DefineParameter (
- i+1, p.Attributes, p.Name);
- cattr = p.OptAttributes;
- if (cattr != null)
- Attribute.ApplyAttributes (ec, pb, pb, cattr);
+ p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location);
}
InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
for (i = 0 ; i < top; i++) {
p = Parameters.FixedParameters [i];
- pb = BeginInvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);
- cattr = p.OptAttributes;
- if (cattr != null)
- Attribute.ApplyAttributes (ec, pb, pb, cattr);
+ p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location);
}
}
if (Parameters.ArrayParameter != null){
Parameter p = Parameters.ArrayParameter;
-
- pb = BeginInvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);
- cattr = p.OptAttributes;
- if (cattr != null)
- Attribute.ApplyAttributes (ec, pb, pb, cattr);
+ p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location);
+
i++;
}
{
if (OptAttributes != null) {
EmitContext ec = new EmitContext (tc, this, Location, null, null, ModFlags, false);
- Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
+ Parameters.LabelParameters (ec, InvokeBuilder, Location);
+ OptAttributes.Emit (ec, this);
}
base.Emit (tc);
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
//TODO: duplicate
protected override bool VerifyClsCompliance (DeclSpace ds)
{
int pd_count = pd.Count;
- bool not_params_method = (pd_count == 0) ||
- (pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS);
+ bool params_method = (pd_count != 0) &&
+ (pd.ParameterModifier (pd_count - 1) == Parameter.Modifier.PARAMS);
- if (not_params_method && pd_count != arg_count) {
+ if (!params_method && pd_count != arg_count) {
Report.Error (1593, loc,
"Delegate '" + delegate_type.ToString ()
+ "' does not take '" + arg_count + "' arguments");
return false;
}
- return Invocation.VerifyArgumentsCompat (ec, args, arg_count, mb, !not_params_method,
- delegate_type, loc);
+ //
+ // Consider the case:
+ // delegate void FOO(param object[] args);
+ // FOO f = new FOO(...);
+ // f(new object[] {1, 2, 3});
+ //
+ // This should be treated like f(1,2,3). This is done by ignoring the
+ // 'param' modifier for that invocation. If that fails, then the
+ // 'param' modifier is considered.
+ //
+ // One issue is that 'VerifyArgumentsCompat' modifies the elements of
+ // the 'args' array. However, the modifications appear idempotent.
+ // Normal 'Invocation's also have the same behaviour, implicitly.
+ //
+
+ bool ans = false;
+ if (arg_count == pd_count)
+ ans = Invocation.VerifyArgumentsCompat (ec, args, arg_count, mb, false, delegate_type, loc);
+ if (!ans && params_method)
+ ans = Invocation.VerifyArgumentsCompat (ec, args, arg_count, mb, true, delegate_type, loc);
+ return ans;
}
/// <summary>
return param_types;
}
}
-
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Delegate | AttributeTargets.ReturnValue;
+ }
+ }
+
+ protected override void VerifyObsoleteAttribute()
+ {
+ CheckUsageOfObsoleteAttribute (ret_type);
+
+ foreach (Type type in param_types) {
+ CheckUsageOfObsoleteAttribute (type);
+ }
+ }
}
//