public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
{
if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = a.GetMarshal ();
+ UnmanagedMarshal marshal = a.GetMarshal (this);
if (marshal != null) {
builder.SetMarshal (marshal);
- return;
}
- Report.Warning_T (-24, a.Location);
+ return;
+ }
+
+ if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+ a.Error_InvalidSecurityParent ();
return;
}
builder = mb.DefineParameter (0, ParameterAttributes.None, "");
}
catch (ArgumentOutOfRangeException) {
- Report.Warning_T (-28, location);
+ Report.Warning (-28, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
}
}
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
+ if (a.Type == TypeManager.cls_compliant_attribute_type) {
+ Report.Warning (3023, 1, a.Location, "CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
+ }
+
// This occurs after Warning -28
if (builder == null)
return;
/// <summary>
/// Is never called
/// </summary>
- protected override string[] ValidAttributeTargets {
+ public override string[] ValidAttributeTargets {
get {
return null;
}
}
/// <summary>
- /// Class for applying custom attributes on the parameter type.
- /// ! Now it works only with 1st parameter (for properties and events)
+ /// Class for applying custom attributes on the implicit parameter type
+ /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
/// </summary>
- public class ParameterAtribute: ParameterBase {
- public ParameterAtribute (MethodBuilder mb):
+ public class ImplicitParameter: ParameterBase {
+ public ImplicitParameter (MethodBuilder mb):
base (null)
{
builder = mb.DefineParameter (1, ParameterAttributes.None, "");
/// <summary>
/// Is never called
/// </summary>
- protected override string[] ValidAttributeTargets {
+ public override string[] ValidAttributeTargets {
get {
return null;
}
}
}
-
/// <summary>
/// Represents a single method parameter
/// </summary>
OUT = 2,
PARAMS = 4,
// This is a flag which says that it's either REF or OUT.
- ISBYREF = 8
+ ISBYREF = 8,
+ ARGLIST = 16
}
static string[] attribute_targets = new string [] { "param" };
- public readonly Expression TypeName;
+ public Expression TypeName;
public readonly Modifier ModFlags;
public readonly string Name;
Type parameter_type;
+
+ EmitContext ec; // because ApplyAtrribute doesn't have ec
public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
: base (attrs)
TypeName = type;
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.in_attribute_type && Attributes == ParameterAttributes.Out) {
+ Report.Error (36, a.Location, "Can not use [In] attribute on out parameter");
+ return;
+ }
+
+ if (a.Type == TypeManager.param_array_type) {
+ 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) != 0 &&
+ !OptAttributes.Contains (TypeManager.in_attribute_type, ec)) {
+ Report.Error (662, a.Location,
+ "'{0}' cannot specify only Out attribute on a ref parameter. Use both In and Out attributes, or neither", GetSignatureForError ());
+ return;
+ }
+
+ if (a.Type == TypeManager.cls_compliant_attribute_type) {
+ Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
// <summary>
// Resolve is used in method definitions
// </summary>
- public bool Resolve (DeclSpace ds, Location l)
+ public bool Resolve (EmitContext ec, Location l)
{
- parameter_type = ds.ResolveType (TypeName, false, l);
+ this.ec = ec;
+
+ TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec, false);
+ if (texpr == null)
+ return false;
+
+ parameter_type = texpr.ResolveType (ec);
+
+ if (parameter_type.IsAbstract && parameter_type.IsSealed) {
+ Report.Error (721, l, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
+ return false;
+ }
if (parameter_type == TypeManager.void_type){
- Report.Error (1536, l, "`void' parameter is not permitted");
+ Report.Error (1536, l, "Invalid parameter type 'void'");
return false;
}
/// Returns the signature for this parameter evaluating it on the
/// @tc context
/// </summary>
- public string GetSignature (DeclSpace ds, Location loc)
+ public string GetSignature (EmitContext ec, Location loc)
{
if (parameter_type == null){
- if (!Resolve (ds, loc))
+ if (!Resolve (ec, loc))
return null;
}
public string GetSignatureForError ()
{
- string typeName = TypeManager.CSharpName (parameter_type);
- switch (ModFlags & ~Modifier.ISBYREF) {
+ string typeName;
+ if (parameter_type != null)
+ typeName = TypeManager.CSharpName (parameter_type);
+ else if (TypeName.Type != null)
+ typeName = TypeManager.CSharpName (TypeName.Type);
+ else
+ typeName = TypeName.ToString ();
+
+ switch (ModFlags & unchecked (~Modifier.ISBYREF)) {
case Modifier.OUT:
return "out " + typeName;
case Modifier.PARAMS:
if (OptAttributes != null) {
OptAttributes.Emit (ec, this);
-
- if (par_attr == ParameterAttributes.Out){
- if (OptAttributes.Contains (TypeManager.in_attribute_type, ec.DeclSpace))
- Report.Error (36, loc, "Can not use [In] attribute on out parameter");
- }
}
}
- protected override string[] ValidAttributeTargets {
+ public override string[] ValidAttributeTargets {
get {
return attribute_targets;
}
public class Parameters {
public Parameter [] FixedParameters;
public readonly Parameter ArrayParameter;
+ public readonly bool HasArglist;
string signature;
Type [] types;
Location loc;
loc = l;
}
+ public Parameters (Parameter [] fixed_parameters, bool has_arglist, Location l)
+ {
+ FixedParameters = fixed_parameters;
+ HasArglist = has_arglist;
+ loc = l;
+ }
+
/// <summary>
/// This is used to reuse a set of empty parameters, because they
/// are common
}
}
- public void ComputeSignature (DeclSpace ds)
+ public void ComputeSignature (EmitContext ec)
{
signature = "";
if (FixedParameters != null){
for (int i = 0; i < FixedParameters.Length; i++){
Parameter par = FixedParameters [i];
- signature += par.GetSignature (ds, loc);
+ signature += par.GetSignature (ec, loc);
}
}
//
count = FixedParameters.Length;
string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null;
+
for (i = 0; i < count; i++){
string base_name = FixedParameters [i].Name;
-
for (j = i + 1; j < count; j++){
if (base_name != FixedParameters [j].Name)
continue;
/// <summary>
/// Returns the signature of the Parameters evaluated in
- /// the @tc environment
+ /// the @ec EmitContext
/// </summary>
- public string GetSignature (DeclSpace ds)
+ public string GetSignature (EmitContext ec)
{
if (signature == null){
VerifyArgs ();
- ComputeSignature (ds);
+ ComputeSignature (ec);
}
return signature;
return null;
}
- bool ComputeParameterTypes (DeclSpace ds)
+ public Parameter GetParameterByName (string name)
+ {
+ int idx;
+
+ return GetParameterByName (name, out idx);
+ }
+
+ bool ComputeParameterTypes (EmitContext ec)
{
int extra = (ArrayParameter != null) ? 1 : 0;
int i = 0;
foreach (Parameter p in FixedParameters){
Type t = null;
- if (p.Resolve (ds, loc))
+ if (p.Resolve (ec, loc))
t = p.ExternalType ();
else
failed = true;
}
if (extra > 0){
- if (ArrayParameter.Resolve (ds, loc))
+ if (ArrayParameter.Resolve (ec, loc))
types [i] = ArrayParameter.ExternalType ();
else
failed = true;
// This variant is used by Delegates, because they need to
// resolve/define names, instead of the plain LookupType
//
- public bool ComputeAndDefineParameterTypes (DeclSpace ds)
+ public bool ComputeAndDefineParameterTypes (EmitContext ec)
{
- int extra = (ArrayParameter != null) ? 1 : 0;
- int i = 0;
- int pc;
-
- if (FixedParameters == null)
- pc = extra;
- else
- pc = extra + FixedParameters.Length;
-
- types = new Type [pc];
-
- if (!VerifyArgs ()){
- FixedParameters = null;
- return false;
- }
-
- bool ok_flag = true;
-
- if (FixedParameters != null){
- foreach (Parameter p in FixedParameters){
- Type t = null;
-
- if (p.Resolve (ds, loc))
- t = p.ExternalType ();
- else
- ok_flag = false;
-
- types [i] = t;
- i++;
- }
- }
-
- if (extra > 0){
- if (ArrayParameter.Resolve (ds, loc))
- types [i] = ArrayParameter.ExternalType ();
- else
- ok_flag = false;
- }
-
- //
- // invalidate the cached types
- //
- if (!ok_flag){
- types = null;
- }
-
- return ok_flag;
+ bool old_type_resolving = ec.ResolvingTypeTree;
+ ec.ResolvingTypeTree = true;
+ bool retval = ComputeParameterTypes (ec);
+ ec.ResolvingTypeTree = old_type_resolving;
+ return retval;
}
/// <summary>
/// </summary>
static Type [] no_types = new Type [0];
- public Type [] GetParameterInfo (DeclSpace ds)
+ public Type [] GetParameterInfo (EmitContext ec)
{
if (types != null)
return types;
if (FixedParameters == null && ArrayParameter == null)
return no_types;
- if (ComputeParameterTypes (ds) == false){
+ if (ComputeParameterTypes (ec) == false){
types = null;
return null;
}
/// Note that the returned type will not contain any dereference in this
/// case (ie, you get "int" for a ref int instead of "int&"
/// </summary>
- public Type GetParameterInfo (DeclSpace ds, int idx, out Parameter.Modifier mod)
+ public Type GetParameterInfo (EmitContext ec, int idx, out Parameter.Modifier mod)
{
mod = Parameter.Modifier.NONE;
return null;
if (types == null)
- if (ComputeParameterTypes (ds) == false)
+ if (ComputeParameterTypes (ec) == false)
return null;
//
public CallingConventions GetCallingConvention ()
{
- // For now this is the only correc thing to do
- return CallingConventions.Standard;
+ if (HasArglist)
+ return CallingConventions.VarArgs;
+ else
+ return CallingConventions.Standard;
}
//