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);
50 if (ArgType == AType.Ref )
51 return TypeManager.LookupType (Expr.Type.ToString () + "&");
57 public Parameter.Modifier GetParameterModifier ()
61 return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
64 return Parameter.Modifier.NONE;
68 public static string FullDesc (Argument a)
70 return (a.ArgType == AType.Ref ? "ref " : "") +
71 TypeManager.MonoBASIC_Name (a.Expr.Type);
74 public bool ResolveMethodGroup (EmitContext ec, Location loc)
76 // FIXME: csc doesn't report any error if you try to use `ref' or
77 // `out' in a delegate creation expression.
78 Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
85 public bool Resolve (EmitContext ec, Location loc)
87 // Optional void arguments - MyCall (1,,2) - are resolved later
88 // in VerifyArgsCompat
89 if (ArgType == AType.NoArg || ArgType == AType.Ref)
95 if (ArgType == AType.Ref) {
96 Expr = Expr.Resolve (ec);
100 Expr = Expr.ResolveLValue (ec, Expr);
103 if (ArgType == AType.AddressOf) {
104 Expression temp_expr = Expr;
106 if (temp_expr is SimpleName) {
107 SimpleName sn = temp_expr as SimpleName;
108 temp_expr = sn.DoResolveAllowStatic(ec);
110 else if (temp_expr is MemberAccess) {
111 MemberAccess ma = temp_expr as MemberAccess;
112 temp_expr = ma.DoResolve(ec);
115 if (temp_expr is MethodGroupExpr)
118 ArgType = AType.Expression;
119 Expr = Expr.Resolve (ec);
122 Expr = Expr.Resolve (ec);
127 if (ArgType == AType.Expression)
130 if (Expr.eclass != ExprClass.Variable){
132 // We just probe to match the CSC output
134 if (Expr.eclass == ExprClass.PropertyAccess ||
135 Expr.eclass == ExprClass.IndexerAccess){
138 "A property or indexer can not be passed as an out or ref " +
143 "An lvalue is required as an argument to out or ref");
151 public void Emit (EmitContext ec)
154 // Ref parameters need to have their addresses taken.
156 // ParameterReferences might already be references, so we want
157 // to pass just the value
159 if (ArgType == AType.Ref ){
160 AddressOp mode = AddressOp.Store;
162 if (ArgType == AType.Ref)
163 mode |= AddressOp.Load;
165 if (Expr is ParameterReference){
166 ParameterReference pr = (ParameterReference) Expr;
172 pr.AddressOf (ec, mode);
175 ((IMemoryLocation)Expr).AddressOf (ec, mode);