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 {
32 public Expression Expr;
33 public string ParamName;
35 public Argument (Expression expr, AType type)
36 : this ("", expr, type)
40 public Argument (string paramName, Expression expr, AType type)
42 this.ParamName = paramName;
43 expr = Parser.SetValueRequiredFlag (expr);
44 if (type == AType.AddressOf)
45 expr = Parser.SetAddressOf (expr);
52 if (ArgType == AType.Ref )
53 return TypeManager.LookupType (Expr.Type.ToString () + "&");
59 public Parameter.Modifier GetParameterModifier ()
63 return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
66 return Parameter.Modifier.NONE;
70 public static string FullDesc (Argument a)
72 return (a.ArgType == AType.Ref ? "ref " : "") +
73 TypeManager.MonoBASIC_Name (a.Expr.Type);
76 public bool ResolveMethodGroup (EmitContext ec, Location loc)
78 // FIXME: csc doesn't report any error if you try to use `ref' or
79 // `out' in a delegate creation expression.
80 Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
87 public bool Resolve (EmitContext ec, Location loc)
89 // Optional void arguments - MyCall (1,,2) - are resolved later
90 // in VerifyArgsCompat
91 if (ArgType == AType.NoArg || ArgType == AType.Ref)
97 if (ArgType == AType.Ref) {
98 Expr = Expr.Resolve (ec);
102 Expr = Expr.ResolveLValue (ec, Expr);
105 if (ArgType == AType.AddressOf) {
106 Expression temp_expr = Expr;
108 if (temp_expr is SimpleName) {
109 SimpleName sn = temp_expr as SimpleName;
110 temp_expr = sn.DoResolveAllowStatic(ec);
112 else if (temp_expr is MemberAccess) {
113 MemberAccess ma = temp_expr as MemberAccess;
114 temp_expr = ma.DoResolve(ec);
117 if (temp_expr is MethodGroupExpr)
120 ArgType = AType.Expression;
121 Expr = Expr.Resolve (ec);
124 Expr = Expr.Resolve (ec);
129 if (ArgType == AType.Expression)
132 if (Expr.eclass != ExprClass.Variable){
134 // We just probe to match the CSC output
136 if (Expr.eclass == ExprClass.PropertyAccess ||
137 Expr.eclass == ExprClass.IndexerAccess){
140 "A property or indexer can not be passed as an out or ref " +
145 "An lvalue is required as an argument to out or ref");
153 public void Emit (EmitContext ec)
156 // Ref parameters need to have their addresses taken.
158 // ParameterReferences might already be references, so we want
159 // to pass just the value
161 if (ArgType == AType.Ref ){
162 AddressOp mode = AddressOp.Store;
164 if (ArgType == AType.Ref)
165 mode |= AddressOp.Load;
167 if (Expr is ParameterReference){
168 ParameterReference pr = (ParameterReference) Expr;
174 pr.AddressOf (ec, mode);
177 ((IMemoryLocation)Expr).AddressOf (ec, mode);