19#include "llvm/ADT/BitVector.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/Support/Error.h"
28static llvm::DenseMap<const Stmt *, const CFGBlock *>
30 llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
52 if (
const Stmt *TerminatorCond =
Block->getTerminatorCondition())
53 StmtToBlock.insert({TerminatorCond,
Block});
69 if (
const Stmt *TerminatorStmt =
Block->getTerminatorStmt())
70 StmtToBlock.insert({TerminatorStmt,
Block});
79 BlocksToVisit.push_back(&Cfg.
getEntry());
80 while (!BlocksToVisit.empty()) {
82 BlocksToVisit.pop_back();
84 if (BlockReachable[
Block->getBlockID()])
87 BlockReachable[
Block->getBlockID()] =
true;
91 BlocksToVisit.push_back(Succ);
94 return BlockReachable;
97static llvm::DenseSet<const CFGBlock *>
100 llvm::DenseSet<const CFGBlock *> Result;
102 auto CheckChildExprs = [&Result, &StmtToBlock](
const Stmt *S,
104 for (
const Stmt *Child : S->children()) {
105 if (!isa_and_nonnull<Expr>(Child))
108 if (ChildBlock !=
Block)
109 Result.insert(ChildBlock);
114 if (
Block ==
nullptr)
118 if (
auto S = Element.getAs<
CFGStmt>())
119 CheckChildExprs(S->getStmt(),
Block);
121 if (
const Stmt *TerminatorCond =
Block->getTerminatorCondition())
122 CheckChildExprs(TerminatorCond,
Block);
130StmtToBlockMap::StmtToBlockMap(
const CFG &Cfg)
136 if (!
Func.doesThisDeclarationHaveABody())
137 return llvm::createStringError(
138 std::make_error_code(std::errc::invalid_argument),
139 "Cannot analyze function without a body");
147 return llvm::createStringError(
148 std::make_error_code(std::errc::invalid_argument),
149 "Cannot analyze templated declarations");
153 if (!
C.getLangOpts().CPlusPlus ||
C.getLangOpts().ObjC)
154 return llvm::createStringError(
155 std::make_error_code(std::errc::invalid_argument),
156 "Can only analyze C++");
159 Options.PruneTriviallyFalseEdges =
true;
160 Options.AddImplicitDtors =
true;
161 Options.AddTemporaryDtors =
true;
162 Options.AddInitializers =
true;
163 Options.AddCXXDefaultInitExprInCtors =
true;
164 Options.AddLifetime =
true;
167 Options.setAllAlwaysAdd();
171 return llvm::createStringError(
172 std::make_error_code(std::errc::invalid_argument),
173 "CFG::buildCFG failed");
179 llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =
182 return AdornedCFG(
D, std::move(Cfg), std::move(StmtToBlock),
183 std::move(BlockReachable),
184 std::move(ContainsExprConsumedInDifferentBlock));
Defines the clang::ASTContext interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a single basic block in a source-level CFG.
Represents a top-level expression in a basic block.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
Builds a CFG from an AST.
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Decl - This represents one declaration (or definition), e.g.
Represents a function declaration or definition.
Stmt - This represents one statement.
Holds CFG with additional information derived from it that is needed to perform dataflow analysis.
static llvm::Expected< AdornedCFG > build(const FunctionDecl &Func)
Builds an AdornedCFG from a FunctionDecl.
const CFGBlock * lookup(const Stmt &S) const
static llvm::DenseSet< const CFGBlock * > buildContainsExprConsumedInDifferentBlock(const CFG &Cfg, const internal::StmtToBlockMap &StmtToBlock)
static llvm::DenseMap< const Stmt *, const CFGBlock * > buildStmtToBasicBlockMap(const CFG &Cfg)
Returns a map from statements to basic blocks that contain them.
static llvm::BitVector findReachableBlocks(const CFG &Cfg)
The JSON file list parser is used to communicate input to InstallAPI.