15 #ifndef LLVM_CLANG_ANALYSIS_CFG_H
16 #define LLVM_CLANG_ANALYSIS_CFG_H
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/GraphTraits.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/PointerIntPair.h"
25 #include "llvm/ADT/iterator_range.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/raw_ostream.h"
35 class CXXDestructorDecl;
41 class CXXCtorInitializer;
42 class CXXBaseSpecifier;
43 class CXXBindTemporaryExpr;
74 llvm::PointerIntPair<void *, 2>
Data1;
75 llvm::PointerIntPair<void *, 2>
Data2;
79 Data2(const_cast<void*>(Ptr2), (((
unsigned) kind) >> 2) & 0x3) {
90 assert(T::isKind(*
this));
101 if (!T::isKind(*
this))
110 unsigned x =
Data2.getInt();
122 return static_cast<const Stmt *
>(
Data1.getPointer());
182 return static_cast<Stmt *
>(
Data2.getPointer());
229 return static_cast<Stmt*
>(
Data2.getPointer());
328 llvm::PointerIntPair<Stmt *, 1> Data;
332 : Data(S, TemporaryDtorsBranch) {}
384 typedef std::reverse_iterator<ImplTy::iterator>
iterator;
385 typedef std::reverse_iterator<ImplTy::const_iterator>
const_iterator;
393 return Impl.insert(I, Cnt, E, C);
396 const_reference
front()
const {
return Impl.back(); }
397 const_reference
back()
const {
return Impl.front(); }
409 assert(i < Impl.size());
410 return Impl[Impl.size() - 1 - i];
413 size_t size()
const {
return Impl.size(); }
414 bool empty()
const {
return Impl.empty(); }
418 ElementList Elements;
433 const Stmt *LoopTarget;
453 llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
465 return ReachableBlock;
470 return UnreachableBlock.getPointer();
488 Kind K = (Kind) UnreachableBlock.getInt();
489 return K == AB_Normal || K == AB_Alternate;
497 AdjacentBlocks Preds;
498 AdjacentBlocks Succs;
509 unsigned HasNoReturnElement : 1;
516 : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
517 BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(
false),
539 unsigned size()
const {
return Elements.size(); }
540 bool empty()
const {
return Elements.empty(); }
614 template <
typename IMPL,
bool IsPred>
624 : I(i), E(e), F(f), From(from) {
625 while (
hasMore() && Filter(*I))
632 do { ++I; }
while (
hasMore() && Filter(*I));
639 return IsPred ?
FilterEdge(F, To, From) : FilterEdge(F, From, To);
643 typedef FilteredCFGBlockIterator<const_pred_iterator, true>
688 bool ShowColors)
const;
698 Elements.push_back(
CFGStmt(statement), C);
740 return iterator(Elements.insert(I.base(), Cnt,
769 bool isAlwaysTrue) {}
787 std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
807 alwaysAddMask[stmtClass] = val;
828 const BuildOptions &BO);
881 return TryDispatchBlocks.begin();
884 return TryDispatchBlocks.end();
888 TryDispatchBlocks.push_back(block);
897 assert(Synthetic->
isSingleDecl() &&
"Can handle single declarations only");
898 assert(Synthetic != Source &&
"Don't include original DeclStmts in map");
899 assert(!SyntheticDeclStmts.count(Synthetic) &&
"Already in map");
900 SyntheticDeclStmts[Synthetic] = Source;
903 typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
913 return SyntheticDeclStmts.begin();
918 return SyntheticDeclStmts.end();
930 template <
typename CALLBACK>
936 O(const_cast<Stmt*>(
stmt->getStmt()));
951 unsigned size()
const {
return NumBlockIDs; }
966 : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
967 Blocks(BlkBVC, 10) {}
982 unsigned NumBlockIDs;
990 std::vector<const CFGBlock *> TryDispatchBlocks;
994 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
1066 :
public GraphTraits< ::clang::CFGBlock *> {
1077 :
public GraphTraits<const ::clang::CFGBlock *> {
1081 static NodeRef
getEntryNode(const ::clang::CFG *F) {
return &F->getEntry(); }
1083 return F->nodes_begin();
1086 return F->nodes_end();
1088 static unsigned size(const ::clang::CFG* F) {
1094 :
public GraphTraits<Inverse< ::clang::CFGBlock*> > {
1104 :
public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
1108 static NodeRef
getEntryNode(const ::clang::CFG *F) {
return &F->getExit(); }
1110 return F->nodes_begin();
1113 return F->nodes_end();
1118 #endif // LLVM_CLANG_ANALYSIS_CFG_H
FilteredCFGBlockIterator< const_pred_iterator, true > filtered_pred_iterator
void setIndirectGotoBlock(CFGBlock *B)
setIndirectGotoBlock - Set the block used for indirect goto jumps.
const_pred_reverse_iterator pred_rend() const
CFGNewAllocator - Represents C++ allocator call.
StmtClass getStmtClass() const
succ_reverse_iterator succ_rbegin()
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const CXXNewExpr * getAllocatorExpr() const
static NodeRef getEntryNode(::clang::CFG *F)
::clang::CFG::const_iterator nodes_iterator
CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
llvm::iterator_range< pred_iterator > pred_range
CFGElement operator[](size_t i) const
ElementList::const_reverse_iterator const_reverse_iterator
succ_iterator succ_begin()
ElementList::reverse_iterator reverse_iterator
CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
Stmt - This represents one statement.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
Decl - This represents one declaration (or definition), e.g.
void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C)
CFGNewAllocator(const CXXNewExpr *S)
CFGBlockListTy::iterator iterator
void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C)
llvm::BumpPtrAllocator & getAllocator()
static ChildIteratorType child_end(NodeRef N)
const CFGBlock * operator*() const
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
static unsigned size(const ::clang::CFG *F)
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const CXXDeleteExpr * getDeleteExpr() const
const CFGBlock & getEntry() const
std::reverse_iterator< iterator > reverse_iterator
unsigned IgnoreDefaultsWithCoveredEnums
bool AddStaticInitBranches
const_pred_iterator pred_end() const
::clang::CFGBlock::const_pred_iterator ChildIteratorType
void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const
print - A simple pretty printer of a CFG that outputs to an ostream.
llvm::BumpPtrAllocator & getAllocator()
const FieldDecl * getFieldDecl() const
static ChildIteratorType child_begin(NodeRef N)
reverse_iterator rbegin()
CFGBlock * getReachableBlock() const
Get the reachable block, if one exists.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
static NodeRef getEntryNode(const ::clang::CFG *F)
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
static ChildIteratorType child_end(NodeRef N)
unsigned succ_size() const
AdjacentBlocks::iterator succ_iterator
pred_const_range preds() const
::clang::CFG::iterator nodes_iterator
const_iterator nodes_end() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void setLoopTarget(const Stmt *loopTarget)
static NodeRef getEntryNode(const clang::CFGBlock *BB)
synthetic_stmt_iterator synthetic_stmt_end() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
static ChildIteratorType child_end(NodeRef N)
const Stmt * getLabel() const
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S)
llvm::iterator_range< succ_iterator > succ_range
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C)
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
CFGBlock * operator->() const
void setTerminator(CFGTerminator Term)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static unsigned size(::clang::CFG *F)
const Stmt & operator*() const
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
static nodes_iterator nodes_end(const ::clang::CFG *F)
const Stmt * getLoopTarget() const
std::vector< const CFGBlock * >::const_iterator try_block_iterator
CFGBlock * getPossiblyUnreachableBlock() const
Get the potentially unreachable block.
BumpVector< CFGBlock * > CFGBlockListTy
const_iterator begin() const
bool AddCXXDefaultInitExprInCtors
llvm::iterator_range< const_pred_iterator > pred_const_range
const VarDecl * getVarDecl() const
unsigned size() const
size - Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlo...
unsigned pred_size() const
static nodes_iterator nodes_begin(const ::clang::CFG *F)
ElementList::const_iterator const_iterator
A builtin binary operation expression such as "x + y" or "x <= y".
typedefconst::clang::CFGBlock * NodeRef
static NodeRef getEntryNode(::clang::CFGBlock *BB)
FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, const CFGBlock *from, const FilterOptions &f)
::clang::CFGBlock::succ_iterator ChildIteratorType
Represents binding an expression to a temporary.
detail::InMemoryDirectory::const_iterator I
const Stmt * getTriggerStmt() const
static ChildIteratorType child_end(NodeRef N)
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const
::clang::CFGBlock * NodeRef
AdjacentBlocks::reverse_iterator succ_reverse_iterator
const_succ_iterator succ_begin() const
static nodes_iterator nodes_begin(::clang::CFG *F)
static nodes_iterator nodes_begin(::clang::CFG *F)
static ChildIteratorType child_begin(NodeRef N)
ForcedBlkExprs ** forcedBlkExprs
const Stmt * getStmt() const
AdjacentBlocks::iterator pred_iterator
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C)
CFGBlock - Represents a single basic block in a source-level CFG.
bool alwaysAdd(const Stmt *stmt) const
Stmt * getTerminatorCondition(bool StripParens=true)
bool isNoReturn(ASTContext &astContext) const
void VisitBlockStmts(CALLBACK &O) const
typedefconst::clang::CFGBlock * NodeRef
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Represents a C++ destructor within a class.
CXXCtorInitializer * getInitializer() const
const CXXRecordDecl * getCXXRecordDecl() const
const_iterator nodes_begin() const
::clang::CFG::const_iterator nodes_iterator
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val)
llvm::iterator_range< synthetic_stmt_iterator > synthetic_stmt_range
AdjacentBlocks::const_iterator const_pred_iterator
unsigned getBlockID() const
const_iterator end() const
const_iterator begin() const
CFGBaseDtor - Represents C++ object destructor implicitly generated for base object in destructor...
std::reverse_iterator< const_iterator > const_reverse_iterator
void viewCFG(const LangOptions &LO) const
void addTryDispatchBlock(const CFGBlock *block)
reverse_iterator rbegin()
ElementList::iterator iterator
const_pred_iterator pred_begin() const
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
const_reverse_iterator rbegin() const
void appendStmt(Stmt *statement, BumpVectorContext &C)
bool hasNoReturnElement() const
CFGTerminator getTerminator()
CFGImplicitDtor(Kind kind, const void *data1, const void *data2=nullptr)
pred_reverse_iterator pred_rend()
BuildOptions & setAlwaysAdd(Stmt::StmtClass stmtClass, bool val=true)
reverse_iterator rbegin()
const Stmt * operator->() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
void setLabel(Stmt *Statement)
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
buildCFG - Builds a CFG from an AST.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
bool PruneTriviallyFalseEdges
bool isTemporaryDtorsBranch() const
std::reverse_iterator< const_iterator > const_reverse_iterator
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue)
const Stmt * getStmt() const
succ_reverse_iterator succ_rend()
static NodeRef getEntryNode(::clang::CFG *F)
static NodeRef getEntryNode(Inverse< const ::clang::CFGBlock * > G)
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
llvm::PointerIntPair< void *, 2 > Data1
BumpVectorContext & getBumpVectorContext()
llvm::iterator_range< const_succ_iterator > succ_const_range
static ChildIteratorType child_begin(NodeRef N)
BuildOptions & setAllAlwaysAdd()
void print(raw_ostream &OS, const CFG *cfg, const LangOptions &LO, bool ShowColors) const
print - A simple pretty printer of a CFGBlock that outputs to an ostream.
AdjacentBlocks::const_iterator const_succ_iterator
FilteredCFGBlockIterator & operator++()
static nodes_iterator nodes_end(::clang::CFG *F)
static NodeRef getEntryNode(const ::clang::CFG *F)
const_pred_reverse_iterator pred_rbegin() const
::clang::CFGBlock::const_pred_iterator ChildIteratorType
pred_iterator pred_begin()
AdjacentBlocks::reverse_iterator pred_reverse_iterator
llvm::PointerIntPair< void *, 2 > Data2
CFGBlockListTy::const_iterator const_iterator
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
static nodes_iterator nodes_begin(const ::clang::CFG *F)
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch=false)
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
virtual void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue)
const_iterator end() const
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C)
const_succ_reverse_iterator succ_rend() const
detail::InMemoryDirectory::const_iterator E
void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C)
try_block_iterator try_blocks_end() const
void appendInitializer(CXXCtorInitializer *initializer, BumpVectorContext &C)
This class represents a potential adjacent block in the CFG.
CFGInitializer(CXXCtorInitializer *initializer)
const Stmt * getTriggerStmt() const
Represents the point where the lifetime of an automatic object ends.
pred_reverse_iterator pred_rbegin()
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
CFGBlock * getIndirectGotoBlock()
Represents a C++ base or member initializer.
::clang::CFGBlock::const_succ_iterator ChildIteratorType
iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S)
try_block_iterator try_blocks_begin() const
const_reverse_iterator rbegin() const
static NodeRef getEntryNode(Inverse<::clang::CFGBlock * > G)
Represents a base class of a C++ class.
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2=nullptr)
unsigned IgnoreNullPredecessors
void setHasNoReturnElement()
const VarDecl * getVarDecl() const
CFGMemberDtor(const FieldDecl *field)
Defines the clang::SourceLocation class and associated facilities.
AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator
const_reverse_iterator rend() const
void printAsOperand(raw_ostream &OS, bool)
Represents a C++ struct/union/class.
CFGCallback defines methods that should be called when a logical operator error is found when buildin...
static nodes_iterator nodes_end(const ::clang::CFG *F)
CFGImplicitDtor - Represents C++ object destructor implicitly generated by compiler on various occasi...
::clang::CFG::iterator nodes_iterator
CFGElement - Represents a top-level expression in a basic block.
void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C)
Adds a (potentially unreachable) successor block to the current block.
const_reverse_iterator rend() const
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
unsigned kind
All of the diagnostics that can be emitted by the frontend.
CFGTerminator - Represents CFGBlock terminator statement.
CFGMemberDtor - Represents C++ object destructor implicitly generated for member object in destructor...
const CFGElement * const_iterator
::clang::Stmt * SimpleType
AdjacentBlock(CFGBlock *B, bool IsReachable)
Construct an AdjacentBlock with a possibly unreachable block.
synthetic_stmt_range synthetic_stmts() const
void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C)
FilteredCFGBlockIterator< const_succ_iterator, false > filtered_succ_iterator
CFGBlock & operator*() const
const Stmt * getTerminatorCondition(bool StripParens=true) const
const_succ_iterator succ_end() const
const CFGElement & const_reference
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
CFGBaseDtor(const CXXBaseSpecifier *base)
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
const CFGTerminator getTerminator() const
succ_const_range succs() const
CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
CFGBlock * createBlock()
createBlock - Create a new block in the CFG.
const CXXBaseSpecifier * getBaseSpecifier() const
const CFGBlock & getExit() const
unsigned getNumBlockIDs() const
getNumBlockIDs - Returns the total number of BlockIDs allocated (which start at 0).
::clang::CFGBlock * NodeRef
void setEntry(CFGBlock *B)
setEntry - Set the entry block of the CFG.
iterator beginLifetimeEndsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
std::reverse_iterator< iterator > reverse_iterator
void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source)
Records a synthetic DeclStmt and the DeclStmt it was constructed from.
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
CFGTemporaryDtor - Represents C++ object destructor implicitly generated at the end of full expressio...
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, const CFGBlock *Dst)
static nodes_iterator nodes_end(::clang::CFG *F)
const_succ_reverse_iterator succ_rbegin() const
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
const CFGBlock * getIndirectGotoBlock() const
filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const
static ChildIteratorType child_begin(NodeRef N)