diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
index eaf3367b7..a361005b5 100644
--- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
@@ -32,8 +32,19 @@ namespace ICSharpCode.Decompiler.CSharp
{
struct StatePerSequencePoint
{
+ ///
+ /// Main AST node associated with this sequence point.
+ ///
internal readonly AstNode PrimaryNode;
+
+ ///
+ /// List of IL intervals that are associated with this sequence point.
+ ///
internal readonly List Intervals;
+
+ ///
+ /// The function containing this sequence point.
+ ///
internal ILFunction Function;
public StatePerSequencePoint(AstNode primaryNode)
@@ -46,7 +57,11 @@ namespace ICSharpCode.Decompiler.CSharp
readonly List<(ILFunction, SequencePoint)> sequencePoints = new List<(ILFunction, SequencePoint)>();
readonly HashSet mappedInstructions = new HashSet();
+
+ // Stack holding information for outer statements.
readonly Stack outerStates = new Stack();
+
+ // Collects information for the current sequence point.
StatePerSequencePoint current = new StatePerSequencePoint();
void VisitAsSequencePoint(AstNode node)
@@ -71,6 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp
public override void VisitForStatement(ForStatement forStatement)
{
+ // Every element of a for-statement is it's own sequence point.
foreach (var init in forStatement.Initializers) {
VisitAsSequencePoint(init);
}
@@ -80,6 +96,28 @@ namespace ICSharpCode.Decompiler.CSharp
}
VisitAsSequencePoint(forStatement.EmbeddedStatement);
}
+
+ public override void VisitSwitchStatement(SwitchStatement switchStatement)
+ {
+ StartSequencePoint(switchStatement);
+ switchStatement.Expression.AcceptVisitor(this);
+ foreach (var section in switchStatement.SwitchSections) {
+ // note: sections will not contribute to the current sequence point
+ section.AcceptVisitor(this);
+ }
+ // add switch statement itself to sequence point
+ // (call only after the sections are visited)
+ AddToSequencePoint(switchStatement);
+ EndSequencePoint(switchStatement.StartLocation, switchStatement.RParToken.EndLocation);
+ }
+
+ public override void VisitSwitchSection(Syntax.SwitchSection switchSection)
+ {
+ // every statement in the switch section is its own sequence point
+ foreach (var stmt in switchSection.Statements) {
+ VisitAsSequencePoint(stmt);
+ }
+ }
///
/// Start a new C# statement = new sequence point.
@@ -104,6 +142,10 @@ namespace ICSharpCode.Decompiler.CSharp
current = outerStates.Pop();
}
+ ///
+ /// Add the ILAst instruction associated with the AstNode to the sequence point.
+ /// Also add all its ILAst sub-instructions (unless they were already added to another sequence point).
+ ///
void AddToSequencePoint(AstNode node)
{
foreach (var inst in node.Annotations.OfType()) {
@@ -129,6 +171,9 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
+ ///
+ /// Called after the visitor is done to return the results.
+ ///
internal Dictionary> GetSequencePoints()
{
var dict = new Dictionary>();