-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][dataflow][NFC] Rename ControlFlowContext
to AdornedCFG
.
#85640
[clang][dataflow][NFC] Rename ControlFlowContext
to AdornedCFG
.
#85640
Conversation
This expresses better what the class actually does, and it reduces the number of `Context`s that we have in the codebase. A deprecated alias `ControlFlowContext` is available from the old header.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-analysis Author: None (martinboehme) ChangesThis expresses better what the class actually does, and it reduces the number of A deprecated alias Patch is 40.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85640.diff 19 Files Affected:
diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index 40ab76fa26a9e3..70687c23b15e61 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -122,6 +122,7 @@ clang/include/clang/Analysis/MacroExpansionContext.h
clang/include/clang/Analysis/Analyses/CalledOnceCheck.h
clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -306,7 +307,7 @@ clang/include/clang-c/Index.h
clang/lib/Analysis/CalledOnceCheck.cpp
clang/lib/Analysis/CloneDetection.cpp
clang/lib/Analysis/CodeInjector.cpp
-clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
+clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
diff --git a/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
new file mode 100644
index 00000000000000..420f13ce11bfde
--- /dev/null
+++ b/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
@@ -0,0 +1,96 @@
+//===-- AdornedCFG.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an AdornedCFG class that is used by dataflow analyses that
+// run over Control-Flow Graphs (CFGs).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Error.h"
+#include <memory>
+#include <utility>
+
+namespace clang {
+namespace dataflow {
+
+/// Holds CFG with additional information derived from it that is needed to
+/// perform dataflow analysis.
+class AdornedCFG {
+public:
+ /// Builds an `AdornedCFG` from a `FunctionDecl`.
+ /// `Func.doesThisDeclarationHaveABody()` must be true, and
+ /// `Func.isTemplated()` must be false.
+ static llvm::Expected<AdornedCFG> build(const FunctionDecl &Func);
+
+ /// Builds an `AdornedCFG` from an AST node. `D` is the function in which
+ /// `S` resides. `D.isTemplated()` must be false.
+ static llvm::Expected<AdornedCFG> build(const Decl &D, Stmt &S,
+ ASTContext &C);
+
+ /// Returns the `Decl` containing the statement used to construct the CFG, if
+ /// available.
+ const Decl &getDecl() const { return ContainingDecl; }
+
+ /// Returns the CFG that is stored in this context.
+ const CFG &getCFG() const { return *Cfg; }
+
+ /// Returns a mapping from statements to basic blocks that contain them.
+ const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
+ return StmtToBlock;
+ }
+
+ /// Returns whether `B` is reachable from the entry block.
+ bool isBlockReachable(const CFGBlock &B) const {
+ return BlockReachable[B.getBlockID()];
+ }
+
+ /// Returns whether `B` contains an expression that is consumed in a
+ /// different block than `B` (i.e. the parent of the expression is in a
+ /// different block).
+ /// This happens if there is control flow within a full-expression (triggered
+ /// by `&&`, `||`, or the conditional operator). Note that the operands of
+ /// these operators are not the only expressions that can be consumed in a
+ /// different block. For example, in the function call
+ /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
+ bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
+ return ContainsExprConsumedInDifferentBlock.contains(&B);
+ }
+
+private:
+ AdornedCFG(
+ const Decl &D, std::unique_ptr<CFG> Cfg,
+ llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
+ llvm::BitVector BlockReachable,
+ llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
+ : ContainingDecl(D), Cfg(std::move(Cfg)),
+ StmtToBlock(std::move(StmtToBlock)),
+ BlockReachable(std::move(BlockReachable)),
+ ContainsExprConsumedInDifferentBlock(
+ std::move(ContainsExprConsumedInDifferentBlock)) {}
+
+ /// The `Decl` containing the statement used to construct the CFG.
+ const Decl &ContainingDecl;
+ std::unique_ptr<CFG> Cfg;
+ llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
+ llvm::BitVector BlockReachable;
+ llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
diff --git a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
index 9a0a00f3c01343..3972962d0b2daa 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
@@ -6,89 +6,20 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines a ControlFlowContext class that is used by dataflow
-// analyses that run over Control-Flow Graphs (CFGs).
+// This file defines a deprecated alias for AdornedCFG.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Analysis/CFG.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Error.h"
-#include <memory>
-#include <utility>
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
namespace clang {
namespace dataflow {
-/// Holds CFG and other derived context that is needed to perform dataflow
-/// analysis.
-class ControlFlowContext {
-public:
- /// Builds a ControlFlowContext from a `FunctionDecl`.
- /// `Func.doesThisDeclarationHaveABody()` must be true, and
- /// `Func.isTemplated()` must be false.
- static llvm::Expected<ControlFlowContext> build(const FunctionDecl &Func);
-
- /// Builds a ControlFlowContext from an AST node. `D` is the function in which
- /// `S` resides. `D.isTemplated()` must be false.
- static llvm::Expected<ControlFlowContext> build(const Decl &D, Stmt &S,
- ASTContext &C);
-
- /// Returns the `Decl` containing the statement used to construct the CFG, if
- /// available.
- const Decl &getDecl() const { return ContainingDecl; }
-
- /// Returns the CFG that is stored in this context.
- const CFG &getCFG() const { return *Cfg; }
-
- /// Returns a mapping from statements to basic blocks that contain them.
- const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
- return StmtToBlock;
- }
-
- /// Returns whether `B` is reachable from the entry block.
- bool isBlockReachable(const CFGBlock &B) const {
- return BlockReachable[B.getBlockID()];
- }
-
- /// Returns whether `B` contains an expression that is consumed in a
- /// different block than `B` (i.e. the parent of the expression is in a
- /// different block).
- /// This happens if there is control flow within a full-expression (triggered
- /// by `&&`, `||`, or the conditional operator). Note that the operands of
- /// these operators are not the only expressions that can be consumed in a
- /// different block. For example, in the function call
- /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
- bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
- return ContainsExprConsumedInDifferentBlock.contains(&B);
- }
-
-private:
- ControlFlowContext(
- const Decl &D, std::unique_ptr<CFG> Cfg,
- llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
- llvm::BitVector BlockReachable,
- llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
- : ContainingDecl(D), Cfg(std::move(Cfg)),
- StmtToBlock(std::move(StmtToBlock)),
- BlockReachable(std::move(BlockReachable)),
- ContainsExprConsumedInDifferentBlock(
- std::move(ContainsExprConsumedInDifferentBlock)) {}
-
- /// The `Decl` containing the statement used to construct the CFG.
- const Decl &ContainingDecl;
- std::unique_ptr<CFG> Cfg;
- llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
- llvm::BitVector BlockReachable;
- llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
-};
+// This is a deprecated alias. Use `AdornedCFG` instead.
+using ControlFlowContext = AdornedCFG;
} // namespace dataflow
} // namespace clang
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index 3c84704d0d6ceb..67eccdd030dcdd 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -22,7 +22,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
@@ -195,8 +195,7 @@ template <typename AnalysisT>
llvm::Expected<std::vector<
std::optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>>
runDataflowAnalysis(
- const ControlFlowContext &CFCtx, AnalysisT &Analysis,
- const Environment &InitEnv,
+ const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv,
std::function<void(const CFGElement &, const DataflowAnalysisState<
typename AnalysisT::Lattice> &)>
PostVisitCFG = nullptr,
@@ -218,7 +217,7 @@ runDataflowAnalysis(
}
auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis(
- CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
+ ACFG, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
if (!TypeErasedBlockStates)
return TypeErasedBlockStates.takeError();
@@ -280,8 +279,7 @@ llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
Diagnoser,
std::int64_t MaxSATIterations = 1'000'000'000,
std::int32_t MaxBlockVisits = 20'000) {
- llvm::Expected<ControlFlowContext> Context =
- ControlFlowContext::build(FuncDecl);
+ llvm::Expected<AdornedCFG> Context = AdornedCFG::build(FuncDecl);
if (!Context)
return Context.takeError();
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index 98bdf037880ab0..909a91059438ca 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -18,8 +18,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/Arena.h"
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/Solver.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
@@ -183,9 +183,9 @@ class DataflowAnalysisContext {
LLVM_DUMP_METHOD void dumpFlowCondition(Atom Token,
llvm::raw_ostream &OS = llvm::dbgs());
- /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
+ /// Returns the `AdornedCFG` registered for `F`, if any. Otherwise,
/// returns null.
- const ControlFlowContext *getControlFlowContext(const FunctionDecl *F);
+ const AdornedCFG *getAdornedCFG(const FunctionDecl *F);
const Options &getOptions() { return Opts; }
@@ -296,7 +296,7 @@ class DataflowAnalysisContext {
llvm::DenseMap<Atom, const Formula *> FlowConditionConstraints;
const Formula *Invariant = nullptr;
- llvm::DenseMap<const FunctionDecl *, ControlFlowContext> FunctionContexts;
+ llvm::DenseMap<const FunctionDecl *, AdornedCFG> FunctionContexts;
// Fields modeled by environments covered by this context.
FieldSet ModeledFields;
diff --git a/clang/include/clang/Analysis/FlowSensitive/Logger.h b/clang/include/clang/Analysis/FlowSensitive/Logger.h
index f4bd39f6ed49ef..f2e64810d00506 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Logger.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Logger.h
@@ -15,7 +15,7 @@
namespace clang::dataflow {
// Forward declarations so we can use Logger anywhere in the framework.
-class ControlFlowContext;
+class AdornedCFG;
class TypeErasedDataflowAnalysis;
struct TypeErasedDataflowAnalysisState;
@@ -40,8 +40,8 @@ class Logger {
/// Called by the framework as we start analyzing a new function or statement.
/// Forms a pair with endAnalysis().
- virtual void beginAnalysis(const ControlFlowContext &,
- TypeErasedDataflowAnalysis &) {}
+ virtual void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) {
+ }
virtual void endAnalysis() {}
// At any time during the analysis, we're computing the state for some target
diff --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index 7713df747cb76e..ed148250d8eb29 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -29,12 +29,12 @@ class StmtToEnvMap {
// `CurState` is the pending state currently associated with this block. These
// are supplied separately as the pending state for the current block may not
// yet be represented in `BlockToState`.
- StmtToEnvMap(const ControlFlowContext &CFCtx,
+ StmtToEnvMap(const AdornedCFG &ACFG,
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
BlockToState,
unsigned CurBlockID,
const TypeErasedDataflowAnalysisState &CurState)
- : CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID),
+ : ACFG(ACFG), BlockToState(BlockToState), CurBlockID(CurBlockID),
CurState(CurState) {}
/// Returns the environment of the basic block that contains `S`.
@@ -42,7 +42,7 @@ class StmtToEnvMap {
const Environment *getEnvironment(const Stmt &S) const;
private:
- const ControlFlowContext &CFCtx;
+ const AdornedCFG &ACFG;
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockToState;
unsigned CurBlockID;
const TypeErasedDataflowAnalysisState &CurState;
diff --git a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index a0ca7440230b04..b3722bf3ec80a8 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -21,7 +21,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
@@ -146,7 +146,7 @@ struct TypeErasedDataflowAnalysisState {
/// from converging.
llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>>
runTypeErasedDataflowAnalysis(
- const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis,
+ const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis,
const Environment &InitEnv,
std::function<void(const CFGElement &,
const TypeErasedDataflowAnalysisState &)>
diff --git a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
similarity index 89%
rename from clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
rename to clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
index 7c9f8fbb0a7009..3813b8c3ee8a23 100644
--- a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
@@ -1,4 +1,4 @@
-//===- ControlFlowContext.cpp ---------------------------------------------===//
+//===- AdornedCFG.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines a ControlFlowContext class that is used by dataflow
-// analyses that run over Control-Flow Graphs (CFGs).
+// This file defines an `AdornedCFG` class that is used by dataflow analyses
+// that run over Control-Flow Graphs (CFGs).
//
//===----------------------------------------------------------------------===//
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
@@ -126,8 +126,7 @@ buildContainsExprConsumedInDifferentBlock(
return Result;
}
-llvm::Expected<ControlFlowContext>
-ControlFlowContext::build(const FunctionDecl &Func) {
+llvm::Expected<AdornedCFG> AdornedCFG::build(const FunctionDecl &Func) {
if (!Func.doesThisDeclarationHaveABody())
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
@@ -136,8 +135,8 @@ ControlFlowContext::build(const FunctionDecl &Func) {
return build(Func, *Func.getBody(), Func.getASTContext());
}
-llvm::Expected<ControlFlowContext>
-ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
+llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,
+ ASTContext &C) {
if (D.isTemplated())
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
@@ -175,9 +174,9 @@ ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =
buildContainsExprConsumedInDifferentBlock(*Cfg, StmtToBlock);
- return ControlFlowContext(D, std::move(Cfg), std::move(StmtToBlock),
- std::move(BlockReachable),
- std::move(ContainsExprConsumedInDifferentBlock));
+ return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock),
+ std::move(BlockReachable),
+ std::move(ContainsExprConsumedInDifferentBlock));
}
} // namespace dataflow
diff --git a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
index 5af4ecfc9efa5d..a3b5d9adc24bda 100644
--- a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
+++ b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
@@ -1,6 +1,6 @@
add_clang_library(clangAnalysisFlowSensitive
+ AdornedCFG.cpp
Arena.cpp
- ControlFlowContext.cpp
DataflowAnalysisContext.cpp
DataflowEnvironment.cpp
Formula.cpp
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index f4c4af022f51f6..d520539dd25355 100644
--- a/clang...
[truncated]
|
…lvm#85640) This expresses better what the class actually does, and it reduces the number of `Context`s that we have in the codebase. A deprecated alias `ControlFlowContext` is available from the old header.
This expresses better what the class actually does, and it reduces the number of
Context
s that we have in the codebase.A deprecated alias
ControlFlowContext
is available from the old header.