//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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 the CFGStmtMap class, which defines a mapping from // Stmt* to CFGBlock* // //===----------------------------------------------------------------------===// #include "clang/AST/ParentMap.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CFGStmtMap.h" #include using namespace clang; const CFGBlock *CFGStmtMap::getBlock(const Stmt *S) const { const Stmt *X = S; // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors // is in the map. while (X) { auto I = M.find(X); if (I != M.end()) return I->second; X = PM->getParentIgnoreParens(X); } return nullptr; } CFGStmtMap::CFGStmtMap(const CFG &C, const ParentMap &PM) : PM(&PM) { // Walk all blocks, accumulating the block-level expressions, labels, // and terminators. for (const CFGBlock *B : C) { // First walk the block-level expressions. for (const CFGElement &CE : *B) { if (std::optional CS = CE.getAs()) M.try_emplace(CS->getStmt(), B); } // Look at the label of the block. if (const Stmt *Label = B->getLabel()) M[Label] = B; // Finally, look at the terminator. If the terminator was already added // because it is a block-level expression in another block, overwrite // that mapping. if (const Stmt *Term = B->getTerminatorStmt()) M[Term] = B; } }