public Argument (Expression expr)
{
- if (expr == null)
- throw new ArgumentNullException ();
-
this.Expr = expr;
}
ml.AddressOf (ec, mode);
}
- public Argument EmitToField (EmitContext ec)
+ public Argument EmitToField (EmitContext ec, bool cloneResult)
{
var res = Expr.EmitToField (ec);
- return res == Expr ? this : new Argument (res, ArgType);
+ if (cloneResult && res != Expr)
+ return new Argument (res, ArgType);
+
+ Expr = res;
+ return this;
+ }
+
+ public void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ if (ArgType == AType.Out) {
+ var vr = Expr as VariableReference;
+ if (vr != null) {
+ if (vr.VariableInfo != null)
+ fc.SetVariableAssigned (vr.VariableInfo);
+
+ return;
+ }
+
+ var fe = Expr as FieldExpr;
+ if (fe != null) {
+ fe.SetFieldAssigned (fc);
+ return;
+ }
+
+ return;
+ }
+
+ Expr.FlowAnalysis (fc);
}
public string GetSignatureForError ()
if (Expr.eclass == ExprClass.MethodGroup)
return Expr.ExprClassName;
- return TypeManager.CSharpName (Expr.Type);
+ return Expr.Type.GetSignatureForError ();
}
public bool ResolveMethodGroup (ResolveContext ec)
public void Resolve (ResolveContext ec)
{
-// using (ec.With (ResolveContext.Options.DoFlowAnalysis, true)) {
- // Verify that the argument is readable
- if (ArgType != AType.Out)
- Expr = Expr.Resolve (ec);
+ // Verify that the argument is readable
+ if (ArgType != AType.Out)
+ Expr = Expr.Resolve (ec);
- // Verify that the argument is writeable
- if (Expr != null && IsByRef)
- Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess);
+ // Verify that the argument is writeable
+ if (Expr != null && IsByRef)
+ Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess);
- if (Expr == null)
- Expr = ErrorExpression.Instance;
-// }
+ if (Expr == null)
+ Expr = ErrorExpression.Instance;
}
}
{
foreach (var a in ordered) {
if (prepareAwait)
- a.EmitToField (ec);
+ a.EmitToField (ec, false);
else
a.EmitToVariable (ec);
}
if (a.Expr is Constant) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc));
} else if (a.ArgType == Argument.AType.Ref) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.Out) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.DynamicTypeName) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc));
}
var arg_type = a.Expr.Type;
} else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) {
rc.Report.Error (1978, a.Expr.Location,
"An expression of type `{0}' cannot be used as an argument of dynamic operation",
- TypeManager.CSharpName (arg_type));
+ arg_type.GetSignatureForError ());
}
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
}
string named_value;
NamedArgument na = a as NamedArgument;
if (na != null) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc));
named_value = na.Name;
} else {
LocalTemporary lt;
foreach (Argument a in args) {
if (prepareAwait) {
- dups.Add (a.EmitToField (ec));
+ dups.Add (a.EmitToField (ec, true));
continue;
}
return null;
}
+ public void FlowAnalysis (FlowAnalysisContext fc)
+ {
+ bool has_out = false;
+ foreach (var arg in args) {
+ if (arg.ArgType == Argument.AType.Out) {
+ has_out = true;
+ continue;
+ }
+
+ arg.FlowAnalysis (fc);
+ }
+
+ if (!has_out)
+ return;
+
+ foreach (var arg in args) {
+ if (arg.ArgType != Argument.AType.Out)
+ continue;
+
+ arg.FlowAnalysis (fc);
+ }
+ }
+
public List<Argument>.Enumerator GetEnumerator ()
{
return args.GetEnumerator ();