20#include "llvm/ADT/BitVector.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/Support/Error.h"
29static llvm::DenseMap<const Stmt *, const CFGBlock *>
31 llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
53 if (
const Stmt *TerminatorCond =
Block->getTerminatorCondition())
54 StmtToBlock.insert({TerminatorCond,
Block});
70 if (
const Stmt *TerminatorStmt =
Block->getTerminatorStmt())
71 StmtToBlock.insert({TerminatorStmt,
Block});
80 BlocksToVisit.push_back(&Cfg.
getEntry());
81 while (!BlocksToVisit.empty()) {
83 BlocksToVisit.pop_back();
85 if (BlockReachable[
Block->getBlockID()])
88 BlockReachable[
Block->getBlockID()] =
true;
92 BlocksToVisit.push_back(Succ);
95 return BlockReachable;
98static llvm::DenseSet<const CFGBlock *>
101 llvm::DenseSet<const CFGBlock *> Result;
103 auto CheckChildExprs = [&Result, &StmtToBlock](
const Stmt *S,
105 for (
const Stmt *Child : S->children()) {
106 if (!isa_and_nonnull<Expr>(Child))
109 if (ChildBlock !=
Block)
110 Result.insert(ChildBlock);
115 if (
Block ==
nullptr)
119 if (
auto S = Element.getAs<
CFGStmt>())
120 CheckChildExprs(S->getStmt(),
Block);
122 if (
const Stmt *TerminatorCond =
Block->getTerminatorCondition())
123 CheckChildExprs(TerminatorCond,
Block);
131StmtToBlockMap::StmtToBlockMap(
const CFG &Cfg)
137 if (!
Func.doesThisDeclarationHaveABody())
138 return llvm::createStringError(
139 std::make_error_code(std::errc::invalid_argument),
140 "Cannot analyze function without a body");
148 return llvm::createStringError(
149 std::make_error_code(std::errc::invalid_argument),
150 "Cannot analyze templated declarations");
154 if (!
C.getLangOpts().CPlusPlus ||
C.getLangOpts().ObjC)
155 return llvm::createStringError(
156 std::make_error_code(std::errc::invalid_argument),
157 "Can only analyze C++");
160 Options.PruneTriviallyFalseEdges =
true;
161 Options.AddImplicitDtors =
true;
162 Options.AddTemporaryDtors =
true;
163 Options.AddInitializers =
true;
164 Options.AddCXXDefaultInitExprInCtors =
true;
165 Options.AddLifetime =
true;
168 Options.setAllAlwaysAdd();