2 // argument.cs: Arguments representation for the IL tree.
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2001 Ximian, Inc.
12 namespace Mono.CSharp {
14 using System.Collections;
15 using System.Reflection;
16 using System.Reflection.Emit;
21 /// Used for arguments to New(), Invocation()
23 public class Argument {
24 public enum AType : byte {
32 public Expression Expr;
34 public Argument (Expression expr, AType type)
42 if (ArgType == AType.Ref || ArgType == AType.Out)
43 return TypeManager.LookupType (Expr.Type.ToString () + "&");
49 public Parameter.Modifier GetParameterModifier ()
53 return Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF;
56 return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
59 return Parameter.Modifier.NONE;
63 public static string FullDesc (Argument a)
65 return (a.ArgType == AType.Ref ? "ref " :
66 (a.ArgType == AType.Out ? "out " : "")) +
67 TypeManager.CSharpName (a.Expr.Type);
70 public bool ResolveMethodGroup (EmitContext ec, Location loc)
72 // FIXME: csc doesn't report any error if you try to use `ref' or
73 // `out' in a delegate creation expression.
74 Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
81 public bool Resolve (EmitContext ec, Location loc)
83 // Optional void arguments - MyCall (1,,2) - are resolved later
84 // in VerifyArgsCompat
85 if (ArgType == AType.NoArg || ArgType == AType.Ref)
90 if (ArgType == AType.Ref) {
91 Expr = Expr.Resolve (ec);
95 Expr = Expr.ResolveLValue (ec, Expr);
96 } else */if (ArgType == AType.Out)
97 Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
99 Expr = Expr.Resolve (ec);
105 if (ArgType == AType.Expression)
108 if (Expr.eclass != ExprClass.Variable){
110 // We just probe to match the CSC output
112 if (Expr.eclass == ExprClass.PropertyAccess ||
113 Expr.eclass == ExprClass.IndexerAccess){
116 "A property or indexer can not be passed as an out or ref " +
121 "An lvalue is required as an argument to out or ref");
129 public void Emit (EmitContext ec)
132 // Ref and Out parameters need to have their addresses taken.
134 // ParameterReferences might already be references, so we want
135 // to pass just the value
137 if (ArgType == AType.Ref || ArgType == AType.Out){
138 AddressOp mode = AddressOp.Store;
140 if (ArgType == AType.Ref)
141 mode |= AddressOp.Load;
143 if (Expr is ParameterReference){
144 ParameterReference pr = (ParameterReference) Expr;
150 pr.AddressOf (ec, mode);
153 ((IMemoryLocation)Expr).AddressOf (ec, mode);