1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef StmtToBlockMap_h__
6 #define StmtToBlockMap_h__
10 // This method is copied from clang-tidy's ExprSequence.cpp.
12 // Returns the Stmt nodes that are parents of 'S', skipping any potential
13 // intermediate non-Stmt nodes.
15 // In almost all cases, this function returns a single parent or no parents at
17 inline SmallVector
<const Stmt
*, 1> getParentStmts(const Stmt
*S
,
18 ASTContext
*Context
) {
19 SmallVector
<const Stmt
*, 1> Result
;
21 auto Parents
= Context
->getParents(*S
);
23 SmallVector
<clang::DynTypedNode
, 1> NodesToProcess(Parents
.begin(),
26 while (!NodesToProcess
.empty()) {
27 clang::DynTypedNode Node
= NodesToProcess
.back();
28 NodesToProcess
.pop_back();
30 if (const auto *S
= Node
.get
<Stmt
>()) {
33 Parents
= Context
->getParents(Node
);
34 NodesToProcess
.append(Parents
.begin(), Parents
.end());
41 // This class is a modified version of the class from clang-tidy's
44 // Maps `Stmt`s to the `CFGBlock` that contains them. Some `Stmt`s may be
45 // contained in more than one `CFGBlock`; in this case, they are mapped to the
46 // innermost block (i.e. the one that is furthest from the root of the tree).
47 // An optional outparameter provides the index into the block where the `Stmt`
49 class StmtToBlockMap
{
51 // Initializes the map for the given `CFG`.
52 StmtToBlockMap(const CFG
*TheCFG
, ASTContext
*TheContext
)
53 : Context(TheContext
) {
54 for (const auto *B
: *TheCFG
) {
55 for (size_t I
= 0; I
< B
->size(); ++I
) {
56 if (Optional
<CFGStmt
> S
= (*B
)[I
].getAs
<CFGStmt
>()) {
57 Map
[S
->getStmt()] = std::make_pair(B
, I
);
63 // Returns the block that S is contained in. Some `Stmt`s may be contained
64 // in more than one `CFGBlock`; in this case, this function returns the
65 // innermost block (i.e. the one that is furthest from the root of the tree).
67 // The optional outparameter `Index` is set to the index into the block where
68 // the `Stmt` was found.
69 const CFGBlock
*blockContainingStmt(const Stmt
*S
,
70 size_t *Index
= nullptr) const {
71 while (!Map
.count(S
)) {
72 SmallVector
<const Stmt
*, 1> Parents
= getParentStmts(S
, Context
);
78 const auto &E
= Map
.lookup(S
);
87 llvm::DenseMap
<const Stmt
*, std::pair
<const CFGBlock
*, size_t>> Map
;
90 #endif // StmtToBlockMap_h__