X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fargument.cs;h=a5edeb53cf68b8e77b94dcf7a5363131038c423a;hb=e4559812129b62624444ab4ce96ddf2ca7de5e3d;hp=c516ffde5b0f080798142ce2e2d361745c4f6104;hpb=d12330eda7746321b4611865d11e932e53ac55b8;p=mono.git diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs index c516ffde5b0..a5edeb53cf6 100644 --- a/mcs/mcs/argument.cs +++ b/mcs/mcs/argument.cs @@ -34,6 +34,11 @@ namespace Mono.CSharp Default = 3, // argument created from default parameter value DynamicTypeName = 4, // System.Type argument for dynamic binding ExtensionType = 5, // Instance expression inserted as the first argument + + // Conditional instance expression inserted as the first argument + ExtensionTypeConditionalAccess = 5 | ConditionalAccessFlag, + + ConditionalAccessFlag = 1 << 7 } public readonly AType ArgType; @@ -60,6 +65,12 @@ namespace Mono.CSharp get { return ArgType == AType.Default; } } + public bool IsExtensionType { + get { + return (ArgType & AType.ExtensionType) == AType.ExtensionType; + } + } + public Parameter.Modifier Modifier { get { switch (ArgType) { @@ -105,7 +116,13 @@ namespace Mono.CSharp public virtual void Emit (EmitContext ec) { if (!IsByRef) { - Expr.Emit (ec); + if (ArgType == AType.ExtensionTypeConditionalAccess) { + var ie = new InstanceEmitter (Expr, false); + ie.Emit (ec, true); + } else { + Expr.Emit (ec); + } + return; } @@ -276,6 +293,16 @@ namespace Mono.CSharp ordered.Add (arg); } + public override void FlowAnalysis (FlowAnalysisContext fc, List movable = null) + { + foreach (var arg in ordered) { + if (arg.ArgType != Argument.AType.Out) + arg.FlowAnalysis (fc); + } + + base.FlowAnalysis (fc, ordered); + } + public override Arguments Emit (EmitContext ec, bool dup_args, bool prepareAwait) { foreach (var a in ordered) { @@ -497,10 +524,34 @@ namespace Mono.CSharp return null; } - public void FlowAnalysis (FlowAnalysisContext fc) + public virtual void FlowAnalysis (FlowAnalysisContext fc, List movable = null) { - foreach (var arg in args) + bool has_out = false; + foreach (var arg in args) { + if (arg.ArgType == Argument.AType.Out) { + has_out = true; + continue; + } + + if (movable == null) { + arg.FlowAnalysis (fc); + continue; + } + + var ma = arg as MovableArgument; + if (ma != null && !movable.Contains (ma)) + 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 ()