tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StmtToBlockMap.h (2926B)


      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/. */
      4 
      5 #ifndef StmtToBlockMap_h__
      6 #define StmtToBlockMap_h__
      7 
      8 #include "Utils.h"
      9 
     10 // This method is copied from clang-tidy's ExprSequence.cpp.
     11 //
     12 // Returns the Stmt nodes that are parents of 'S', skipping any potential
     13 // intermediate non-Stmt nodes.
     14 //
     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;
     20 
     21  auto Parents = Context->getParents(*S);
     22 
     23  SmallVector<clang::DynTypedNode, 1> NodesToProcess(Parents.begin(),
     24                                                     Parents.end());
     25 
     26  while (!NodesToProcess.empty()) {
     27    clang::DynTypedNode Node = NodesToProcess.back();
     28    NodesToProcess.pop_back();
     29 
     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());
     35    }
     36  }
     37 
     38  return Result;
     39 }
     40 
     41 // This class is a modified version of the class from clang-tidy's
     42 // ExprSequence.cpp
     43 //
     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);
     58        }
     59      }
     60    }
     61  }
     62 
     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).
     66  //
     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];
     76    }
     77 
     78    const auto &E = Map.lookup(S);
     79    if (Index)
     80      *Index = E.second;
     81    return E.first;
     82  }
     83 
     84 private:
     85  ASTContext *Context;
     86 
     87  llvm::DenseMap<const Stmt *, std::pair<const CFGBlock *, size_t>> Map;
     88 };
     89 
     90 #endif // StmtToBlockMap_h__