X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fargument.cs;h=13d0526cc2cd9c5a47e422bbdc2b9c763c2de9b4;hb=bff1c7a08cc189211e458561de52e76b403912f5;hp=2192b9c9e6808fa95db188eca5fcbde869b5adae;hpb=f838f226d171590dd3c98387257b4f7b5bfd5ee3;p=mono.git diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs index 2192b9c9e68..13d0526cc2c 100644 --- a/mcs/mcs/argument.cs +++ b/mcs/mcs/argument.cs @@ -6,7 +6,8 @@ // Marek Safar (marek.safar@gmail.com) // // Dual licensed under the terms of the MIT X11 or GNU GPL -// Copyright 2003-2008 Novell, Inc. +// Copyright 2003-2011 Novell, Inc. +// Copyright 2011 Xamarin Inc // using System; @@ -46,9 +47,6 @@ namespace Mono.CSharp public Argument (Expression expr) { - if (expr == null) - throw new ArgumentNullException (); - this.Expr = expr; } @@ -119,10 +117,37 @@ namespace Mono.CSharp 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 () @@ -130,7 +155,7 @@ namespace Mono.CSharp if (Expr.eclass == ExprClass.MethodGroup) return Expr.ExprClassName; - return TypeManager.CSharpName (Expr.Type); + return Expr.Type.GetSignatureForError (); } public bool ResolveMethodGroup (ResolveContext ec) @@ -150,18 +175,16 @@ namespace Mono.CSharp 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; } } @@ -257,7 +280,7 @@ namespace Mono.CSharp { foreach (var a in ordered) { if (prepareAwait) - a.EmitToField (ec); + a.EmitToField (ec, false); else a.EmitToVariable (ec); } @@ -315,20 +338,20 @@ namespace Mono.CSharp 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; @@ -345,18 +368,18 @@ namespace Mono.CSharp } 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 { @@ -439,7 +462,7 @@ namespace Mono.CSharp LocalTemporary lt; foreach (Argument a in args) { if (prepareAwait) { - dups.Add (a.EmitToField (ec)); + dups.Add (a.EmitToField (ec, true)); continue; } @@ -474,6 +497,29 @@ namespace Mono.CSharp 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.Enumerator GetEnumerator () { return args.GetEnumerator ();