public abstract class ParameterBase : Attributable {
protected ParameterBuilder builder;
+ public readonly Location Location;
- public ParameterBase (Attributes attrs)
+ public ParameterBase (Attributes attrs, Location loc)
: base (attrs)
{
+ Location = loc;
}
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;
}
/// </summary>
public class ReturnParameter: ParameterBase {
public ReturnParameter (MethodBuilder mb, Location location):
- base (null)
+ base (null, location)
{
try {
builder = mb.DefineParameter (0, ParameterAttributes.None, "");
}
catch (ArgumentOutOfRangeException) {
- Report.Warning_T (-28, location);
+ Report.Warning (-24, 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;
}
/// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
/// </summary>
public class ImplicitParameter: ParameterBase {
- public ImplicitParameter (MethodBuilder mb):
- base (null)
+ public ImplicitParameter (MethodBuilder mb, Location loc):
+ base (null, loc)
{
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>
-
- //TODO: Add location member to this or base class for better error location and all methods simplification.
public class Parameter : ParameterBase {
[Flags]
public enum Modifier : byte {
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)
+ public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Location loc)
+ : base (attrs, loc)
{
Name = name;
ModFlags = mod;
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)
{
- 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, Location, "'{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, Location, "Invalid parameter type 'void'");
return false;
}
if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
if (parameter_type == TypeManager.typed_reference_type ||
parameter_type == TypeManager.arg_iterator_type){
- Report.Error (1601, l,
+ Report.Error (1601, Location,
"out or ref parameter can not be of type TypedReference or ArgIterator");
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)
{
if (parameter_type == null){
- if (!Resolve (ds, loc))
+ if (!Resolve (ec))
return null;
}
public string GetSignatureForError ()
{
- string typeName = TypeManager.CSharpName (parameter_type);
- switch (ModFlags & ~Modifier.ISBYREF) {
+ string type_name;
+ if (parameter_type != null)
+ type_name = TypeManager.CSharpName (parameter_type);
+ else if (TypeName.Type != null)
+ type_name = TypeManager.CSharpName (TypeName.Type);
+ else
+ type_name = TypeName.ToString ();
+
+ string mod = GetModifierSignature (ModFlags);
+ if (mod.Length > 0)
+ return String.Concat (mod, " ", type_name);
+
+ return type_name;
+ }
+
+ public static string GetModifierSignature (Modifier mod)
+ {
+ switch (mod & unchecked (~Modifier.ISBYREF)) {
case Modifier.OUT:
- return "out " + typeName;
+ return "out";
case Modifier.PARAMS:
- return "params " + typeName;
+ return "params";
case Modifier.REF:
- return "ref " + typeName;
+ return "ref";
+ case Modifier.ARGLIST:
+ return "__arglist";
+ default:
+ return "";
}
- return typeName;
}
- public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index, Location loc)
+ public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index)
{
ParameterAttributes par_attr = Attributes;
if (OptAttributes != null) {
OptAttributes.Emit (ec, this);
-
- if (par_attr == ParameterAttributes.Out){
- if (OptAttributes.Contains (TypeManager.in_attribute_type, ec))
- 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 readonly bool HasArglist;
string signature;
Type [] types;
- Location loc;
static Parameters empty_parameters;
- public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l)
+ public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
{
FixedParameters = fixed_parameters;
ArrayParameter = array_parameter;
- loc = l;
}
- public Parameters (Parameter [] fixed_parameters, bool has_arglist, Location l)
+ public Parameters (Parameter [] fixed_parameters, bool has_arglist)
{
FixedParameters = fixed_parameters;
HasArglist = has_arglist;
- loc = l;
}
/// <summary>
public static Parameters EmptyReadOnlyParameters {
get {
if (empty_parameters == null)
- empty_parameters = new Parameters (null, null, Location.Null);
+ empty_parameters = new Parameters (null, null);
return empty_parameters;
}
return (FixedParameters == null) && (ArrayParameter == null);
}
}
-
- 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);
}
}
//
//
}
- void Error_DuplicateParameterName (string name)
+ void Error_DuplicateParameterName (string name, Location loc)
{
Report.Error (
100, loc, "The parameter name `" + name + "' is a duplicate");
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;
- Error_DuplicateParameterName (base_name);
+ Error_DuplicateParameterName (base_name,
+ FixedParameters [i].Location);
return false;
}
if (base_name == array_par_name){
- Error_DuplicateParameterName (base_name);
+ Error_DuplicateParameterName (base_name,
+ FixedParameters [i].Location);
return false;
}
}
/// <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))
t = p.ExternalType ();
else
failed = true;
}
if (extra > 0){
- if (ArrayParameter.Resolve (ds, loc))
+ if (ArrayParameter.Resolve (ec))
types [i] = ArrayParameter.ExternalType ();
else
failed = true;
return true;
}
-
- //
- // This variant is used by Delegates, because they need to
- // resolve/define names, instead of the plain LookupType
- //
- public bool ComputeAndDefineParameterTypes (DeclSpace ds)
- {
- 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;
- }
/// <summary>
/// Returns the argument types as an array
/// </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;
//
// The method's attributes are passed in because we need to extract
// the "return:" attribute from there to apply on the return type
//
- public void LabelParameters (EmitContext ec,
- MethodBase builder,
- Location loc) {
+ public void LabelParameters (EmitContext ec, MethodBase builder)
+ {
//
// Define each type attribute (in/out/ref) and
// the argument names.
if (FixedParameters != null) {
for (i = 0; i < FixedParameters.Length; i++) {
- FixedParameters [i].DefineParameter (ec, mb, cb, i + 1, loc);
+ FixedParameters [i].DefineParameter (ec, mb, cb, i + 1);
}
}