24
24
#include " clang/Analysis/FlowSensitive/Transfer.h"
25
25
#include " clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
26
26
#include " clang/Analysis/FlowSensitive/Value.h"
27
+ #include " llvm/ADT/ArrayRef.h"
27
28
#include " llvm/ADT/DenseSet.h"
28
29
#include " llvm/ADT/None.h"
29
30
#include " llvm/ADT/Optional.h"
32
33
namespace clang {
33
34
namespace dataflow {
34
35
36
+ class StmtToEnvMapImpl : public StmtToEnvMap {
37
+ public:
38
+ StmtToEnvMapImpl (
39
+ const ControlFlowContext &CFCtx,
40
+ llvm::ArrayRef<llvm::Optional<TypeErasedDataflowAnalysisState>>
41
+ BlockToState)
42
+ : CFCtx(CFCtx), BlockToState(BlockToState) {}
43
+
44
+ const Environment *getEnvironment (const Stmt &S) const override {
45
+ auto BlockIT = CFCtx.getStmtToBlock ().find (&S);
46
+ assert (BlockIT != CFCtx.getStmtToBlock ().end ());
47
+ const auto &State = BlockToState[BlockIT->getSecond ()->getBlockID ()];
48
+ assert (State.hasValue ());
49
+ return &State.getValue ().Env ;
50
+ }
51
+
52
+ private:
53
+ const ControlFlowContext &CFCtx;
54
+ llvm::ArrayRef<llvm::Optional<TypeErasedDataflowAnalysisState>> BlockToState;
55
+ };
56
+
35
57
// / Computes the input state for a given basic block by joining the output
36
58
// / states of its predecessors.
37
59
// /
@@ -42,7 +64,7 @@ namespace dataflow {
42
64
// / `llvm::None` represent basic blocks that are not evaluated yet.
43
65
static TypeErasedDataflowAnalysisState computeBlockInputState (
44
66
const ControlFlowContext &CFCtx,
45
- std::vector <llvm::Optional<TypeErasedDataflowAnalysisState>> & BlockStates,
67
+ llvm::ArrayRef <llvm::Optional<TypeErasedDataflowAnalysisState>> BlockStates,
46
68
const CFGBlock &Block, const Environment &InitEnv,
47
69
TypeErasedDataflowAnalysis &Analysis) {
48
70
llvm::DenseSet<const CFGBlock *> Preds;
@@ -111,17 +133,19 @@ static TypeErasedDataflowAnalysisState computeBlockInputState(
111
133
// / Transfers `State` by evaluating `CfgStmt` in the context of `Analysis`.
112
134
// / `HandleTransferredStmt` (if provided) will be applied to `CfgStmt`, after it
113
135
// / is evaluated.
114
- static void
115
- transferCFGStmt (const CFGStmt &CfgStmt, TypeErasedDataflowAnalysis &Analysis,
116
- TypeErasedDataflowAnalysisState &State,
117
- std::function<void (const CFGStmt &,
118
- const TypeErasedDataflowAnalysisState &)>
119
- HandleTransferredStmt) {
136
+ static void transferCFGStmt (
137
+ const ControlFlowContext &CFCtx,
138
+ llvm::ArrayRef<llvm::Optional<TypeErasedDataflowAnalysisState>> BlockStates,
139
+ const CFGStmt &CfgStmt, TypeErasedDataflowAnalysis &Analysis,
140
+ TypeErasedDataflowAnalysisState &State,
141
+ std::function<void (const CFGStmt &,
142
+ const TypeErasedDataflowAnalysisState &)>
143
+ HandleTransferredStmt) {
120
144
const Stmt *S = CfgStmt.getStmt ();
121
145
assert (S != nullptr );
122
146
123
147
if (Analysis.applyBuiltinTransfer ())
124
- transfer (*S, State.Env );
148
+ transfer (StmtToEnvMapImpl (CFCtx, BlockStates), *S, State.Env );
125
149
Analysis.transferTypeErased (S, State.Lattice , State.Env );
126
150
127
151
if (HandleTransferredStmt != nullptr )
@@ -176,8 +200,8 @@ TypeErasedDataflowAnalysisState transferBlock(
176
200
for (const CFGElement &Element : Block) {
177
201
switch (Element.getKind ()) {
178
202
case CFGElement::Statement:
179
- transferCFGStmt (*Element.getAs <CFGStmt>(), Analysis, State ,
180
- HandleTransferredStmt);
203
+ transferCFGStmt (CFCtx, BlockStates, *Element.getAs <CFGStmt>(), Analysis,
204
+ State, HandleTransferredStmt);
181
205
break ;
182
206
case CFGElement::Initializer:
183
207
if (Analysis.applyBuiltinTransfer ())
0 commit comments