提交 c4362ba1 编写于 作者: N Neal Gafter 提交者: GitHub

Add a hidden sequence point around the code that assigns pattern variables in switch (#14789)

Fixes #14740
上级 9acf656e
......@@ -208,6 +208,11 @@ public override BoundExpression InstrumentSwitchStatementExpression(BoundStateme
return Previous.InstrumentSwitchStatementExpression(original, rewrittenExpression, factory);
}
public override BoundStatement InstrumentPatternSwitchBindCasePatternVariables(BoundStatement bindings)
{
return Previous.InstrumentPatternSwitchBindCasePatternVariables(bindings);
}
public override BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
{
return Previous.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl);
......
......@@ -431,5 +431,11 @@ public override BoundExpression InstrumentSwitchStatementExpression(BoundStateme
return AddConditionSequencePoint(base.InstrumentSwitchStatementExpression(original, rewrittenExpression, factory), original.Syntax, factory);
}
public override BoundStatement InstrumentPatternSwitchBindCasePatternVariables(BoundStatement bindings)
{
// Mark the code that binds pattern variables to their values as hidden.
// We do it to tell that this is not a part of previous statement.
return new BoundSequencePoint(null, base.InstrumentPatternSwitchBindCasePatternVariables(bindings));
}
}
}
\ No newline at end of file
......@@ -298,5 +298,10 @@ public virtual BoundExpression InstrumentSwitchStatementExpression(BoundStatemen
Debug.Assert(factory != null);
return rewrittenExpression;
}
public virtual BoundStatement InstrumentPatternSwitchBindCasePatternVariables(BoundStatement bindings)
{
return bindings;
}
}
}
\ No newline at end of file
......@@ -278,6 +278,43 @@ private void LowerConstantValueDecision(DecisionTree.ByValue byValue)
LowerDecisionTree(byValue.Expression, byValue.Default);
}
/// <summary>
/// Add a branch in the lowered decision tree to a label for a matched
/// pattern, and then produce a statement for the target of that branch
/// that binds the pattern variables.
/// </summary>
/// <param name="bindings">The source/destination pairs for the assignments</param>
private BoundStatement BindingsForCase(
ImmutableArray<KeyValuePair<BoundExpression, BoundExpression>> bindings)
{
var patternMatched = _factory.GenerateLabel("patternMatched");
_loweredDecisionTree.Add(_factory.Goto(patternMatched));
var addBindings = ArrayBuilder<BoundStatement>.GetInstance();
addBindings.Add(_factory.Label(patternMatched));
if (!bindings.IsDefaultOrEmpty)
{
foreach (var kv in bindings)
{
var source = kv.Key;
var dest = kv.Value;
var rewriter = this.LocalRewriter;
addBindings.Add(_factory.ExpressionStatement(
rewriter.MakeStaticAssignmentOperator(
_factory.Syntax, rewriter.VisitExpression(dest), rewriter.VisitExpression(source), RefKind.None, dest.Type, false)));
}
}
BoundStatement result = _factory.Block(addBindings.ToImmutableAndFree());
if (this.LocalRewriter.Instrument)
{
// Hide the code that binds pattern variables in a hidden sequence point
result = this.LocalRewriter._instrumenter.InstrumentPatternSwitchBindCasePatternVariables(result);
}
return result;
}
private void LowerDecisionTree(DecisionTree.Guarded guarded)
{
var sectionBuilder = this.SwitchSections[guarded.Section];
......@@ -294,20 +331,13 @@ private void LowerDecisionTree(DecisionTree.Guarded guarded)
else
{
// with bindings
var matched = _factory.GenerateLabel("matched");
_loweredDecisionTree.Add(_factory.Goto(matched));
sectionBuilder.Add(_factory.Label(matched));
AddBindings(sectionBuilder, guarded.Bindings);
sectionBuilder.Add(BindingsForCase(guarded.Bindings));
sectionBuilder.Add(_factory.Goto(targetLabel));
}
}
else
{
var checkGuard = _factory.GenerateLabel("checkGuard");
_loweredDecisionTree.Add(_factory.Goto(checkGuard));
sectionBuilder.Add(_factory.Label(checkGuard));
AddBindings(sectionBuilder, guarded.Bindings);
sectionBuilder.Add(BindingsForCase(guarded.Bindings));
var guardTest = _factory.ConditionalGoto(LocalRewriter.VisitExpression(guarded.Guard), targetLabel, true);
// Only add instrumentation (such as a sequence point) if the node is not compiler-generated.
......@@ -326,22 +356,6 @@ private void LowerDecisionTree(DecisionTree.Guarded guarded)
}
}
private void AddBindings(ArrayBuilder<BoundStatement> sectionBuilder, ImmutableArray<KeyValuePair<BoundExpression, BoundExpression>> bindings)
{
if (!bindings.IsDefaultOrEmpty)
{
foreach (var kv in bindings)
{
var source = kv.Key;
var dest = kv.Value;
var rewriter = this.LocalRewriter;
sectionBuilder.Add(_factory.ExpressionStatement(
rewriter.MakeStaticAssignmentOperator(
_factory.Syntax, rewriter.VisitExpression(dest), rewriter.VisitExpression(source), RefKind.None, dest.Type, false)));
}
}
}
// For switch statements, we have an option of completely rewriting the switch header
// and switch sections into simpler constructs, i.e. we can rewrite the switch header
// using bound conditional goto statements and the rewrite the switch sections into
......
......@@ -2305,9 +2305,12 @@ class Student : Person { public double GPA; }
<entry offset=""0x0"" startLine=""19"" startColumn=""5"" endLine=""19"" endColumn=""6"" />
<entry offset=""0x1"" startLine=""20"" startColumn=""9"" endLine=""20"" endColumn=""19"" />
<entry offset=""0x4"" hidden=""true"" />
<entry offset=""0x32"" hidden=""true"" />
<entry offset=""0x35"" startLine=""22"" startColumn=""28"" endLine=""22"" endColumn=""44"" />
<entry offset=""0x49"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""57"" />
<entry offset=""0x6a"" hidden=""true"" />
<entry offset=""0x6f"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""57"" />
<entry offset=""0x90"" hidden=""true"" />
<entry offset=""0x95"" startLine=""27"" startColumn=""17"" endLine=""27"" endColumn=""59"" />
<entry offset=""0xb1"" startLine=""29"" startColumn=""17"" endLine=""29"" endColumn=""43"" />
<entry offset=""0xc5"" startLine=""31"" startColumn=""5"" endLine=""31"" endColumn=""6"" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册