Bug 1839316: part 5) Guard the "fetchpriority" attribute behind a pref. r=kershaw...
[gecko.git] / build / clang-plugin / StmtToBlockMap.h
blob09b0cac4152db5de0fd9d47b73b4f327287b7fdd
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__
8 #include "Utils.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
16 // all.
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(),
24 Parents.end());
26 while (!NodesToProcess.empty()) {
27 clang::DynTypedNode Node = NodesToProcess.back();
28 NodesToProcess.pop_back();
30 if (const auto *S = Node.get<Stmt>()) {
31 Result.push_back(S);
32 } else {
33 Parents = Context->getParents(Node);
34 NodesToProcess.append(Parents.begin(), Parents.end());
38 return Result;
41 // This class is a modified version of the class from clang-tidy's
42 // ExprSequence.cpp
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`
48 // was found.
49 class StmtToBlockMap {
50 public:
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 (auto 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);
73 if (Parents.empty())
74 return nullptr;
75 S = Parents[0];
78 const auto &E = Map.lookup(S);
79 if (Index)
80 *Index = E.second;
81 return E.first;
84 private:
85 ASTContext *Context;
87 llvm::DenseMap<const Stmt *, std::pair<const CFGBlock *, size_t>> Map;
90 #endif // StmtToBlockMap_h__