2 // argument.cs: Arguments representation for the IL tree.
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2001 Ximian, Inc.
12 namespace Mono.MonoBASIC {
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 {
33 public Expression Expr;
35 public Argument (Expression expr, AType type)
43 if (ArgType == AType.Ref || ArgType == AType.Out)
44 return TypeManager.LookupType (Expr.Type.ToString () + "&");
50 public Parameter.Modifier GetParameterModifier ()
54 return Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF;
57 return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
60 return Parameter.Modifier.NONE;
64 public static string FullDesc (Argument a)
66 return (a.ArgType == AType.Ref ? "ref " :
67 (a.ArgType == AType.Out ? "out " : "")) +
68 TypeManager.MonoBASIC_Name (a.Expr.Type);
71 public bool ResolveMethodGroup (EmitContext ec, Location loc)
73 // FIXME: csc doesn't report any error if you try to use `ref' or
74 // `out' in a delegate creation expression.
75 Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
82 public bool Resolve (EmitContext ec, Location loc)
84 // Optional void arguments - MyCall (1,,2) - are resolved later
85 // in VerifyArgsCompat
86 if (ArgType == AType.NoArg || ArgType == AType.Ref)
92 if (ArgType == AType.Ref) {
93 Expr = Expr.Resolve (ec);
97 Expr = Expr.ResolveLValue (ec, Expr);
100 if (ArgType == AType.Out)
101 Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
102 else if (ArgType == AType.AddressOf) {
103 Expression temp_expr = Expr;
105 if (temp_expr is SimpleName) {
106 SimpleName sn = temp_expr as SimpleName;
107 temp_expr = sn.DoResolveAllowStatic(ec);
109 else if (temp_expr is MemberAccess) {
110 MemberAccess ma = temp_expr as MemberAccess;
111 temp_expr = ma.DoResolve(ec);
114 if (temp_expr is MethodGroupExpr)
117 ArgType = AType.Expression;
118 Expr = Expr.Resolve (ec);
121 Expr = Expr.Resolve (ec);
126 if (ArgType == AType.Expression)
129 if (Expr.eclass != ExprClass.Variable){
131 // We just probe to match the CSC output
133 if (Expr.eclass == ExprClass.PropertyAccess ||
134 Expr.eclass == ExprClass.IndexerAccess){
137 "A property or indexer can not be passed as an out or ref " +
142 "An lvalue is required as an argument to out or ref");
150 public void Emit (EmitContext ec)
153 // Ref and Out parameters need to have their addresses taken.
155 // ParameterReferences might already be references, so we want
156 // to pass just the value
158 if (ArgType == AType.Ref || ArgType == AType.Out){
159 AddressOp mode = AddressOp.Store;
161 if (ArgType == AType.Ref)
162 mode |= AddressOp.Load;
164 if (Expr is ParameterReference){
165 ParameterReference pr = (ParameterReference) Expr;
171 pr.AddressOf (ec, mode);
174 ((IMemoryLocation)Expr).AddressOf (ec, mode);