14 #ifndef LLVM_CLANG_ANALYSIS_CFG_H 15 #define LLVM_CLANG_ANALYSIS_CFG_H 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/GraphTraits.h" 24 #include "llvm/ADT/None.h" 25 #include "llvm/ADT/Optional.h" 26 #include "llvm/ADT/PointerIntPair.h" 27 #include "llvm/ADT/iterator_range.h" 28 #include "llvm/Support/Allocator.h" 29 #include "llvm/Support/raw_ostream.h" 42 class CXXBaseSpecifier;
43 class CXXBindTemporaryExpr;
44 class CXXCtorInitializer;
46 class CXXDestructorDecl;
83 llvm::PointerIntPair<void *, 2>
Data1;
84 llvm::PointerIntPair<void *, 2>
Data2;
87 : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
88 Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
99 assert(T::isKind(*
this));
110 if (!T::isKind(*
this))
119 unsigned x = Data2.getInt();
135 assert(isKind(*
this));
139 return static_cast<const Stmt *
>(
Data1.getPointer());
161 Data2.setPointer(const_cast<ConstructionContext *>(C));
189 assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E));
199 assert(isCXXRecordTypedCall(E));
200 assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
202 isa<ReturnedValueConstructionContext>(C) ||
203 isa<VariableConstructionContext>(C) ||
204 isa<ConstructorInitializerConstructionContext>(C) ||
205 isa<ArgumentConstructionContext>(C)));
206 Data2.setPointer(const_cast<ConstructionContext *>(C));
276 return static_cast<Stmt *
>(
Data1.getPointer());
300 return static_cast<Stmt *
>(
Data2.getPointer());
323 return static_cast<Stmt*
>(
Data2.getPointer());
351 return static_cast<Stmt *
>(
Data2.getPointer());
375 bool isNoReturn(
ASTContext &astContext)
const;
400 return static_cast<Stmt*
>(
Data2.getPointer());
521 NumKindsMinusOne = VirtualBaseBranch
525 static constexpr
int KindBits = 2;
526 static_assert((1 << KindBits) > NumKindsMinusOne,
527 "Not enough room for kind!");
528 llvm::PointerIntPair<Stmt *, KindBits> Data;
534 bool isValid()
const {
return Data.getOpaqueValue() !=
nullptr; }
540 return getKind() == StmtBranch;
543 return getKind() == TemporaryDtorsBranch;
546 return getKind() == VirtualBaseBranch;
585 using iterator = std::reverse_iterator<ImplTy::iterator>;
586 using const_iterator = std::reverse_iterator<ImplTy::const_iterator>;
589 using const_reference = ImplTy::const_reference;
595 return Impl.insert(I, Cnt, E, C);
598 const_reference front()
const {
return Impl.back(); }
599 const_reference back()
const {
return Impl.front(); }
601 iterator begin() {
return Impl.rbegin(); }
602 iterator end() {
return Impl.rend(); }
611 assert(i < Impl.size());
612 return Impl[Impl.size() - 1 - i];
615 size_t size()
const {
return Impl.size(); }
616 bool empty()
const {
return Impl.empty(); }
622 template <
bool IsConst>
class ElementRefImpl {
624 template <
bool IsOtherConst>
friend class ElementRefImpl;
629 using CFGElementPtr =
typename std::conditional<IsConst,
const CFGElement *,
637 ElementRefImpl(CFGBlockPtr Parent,
size_t Index)
638 :
Parent(Parent), Index(Index) {}
640 template <
bool IsOtherConst>
641 ElementRefImpl(ElementRefImpl<IsOtherConst> Other)
642 : ElementRefImpl(Other.Parent, Other.Index) {}
644 size_t getIndexInBlock()
const {
return Index; }
646 CFGBlockPtr getParent() {
return Parent; }
647 CFGBlockPtr getParent()
const {
return Parent; }
649 bool operator<(ElementRefImpl Other)
const {
650 return std::make_pair(Parent, Index) <
651 std::make_pair(Other.Parent, Other.Index);
655 return Parent == Other.Parent && Index == Other.Index;
658 bool operator!=(ElementRefImpl Other)
const {
return !(*
this == Other); }
659 CFGElement
operator*()
const {
return (*Parent)[Index]; }
660 CFGElementPtr operator->()
const {
return &*(Parent->begin() + Index); }
663 OS << getIndexInBlock() + 1 <<
": ";
664 (*this)->dumpToStream(OS);
672 template <
bool IsReverse,
bool IsConst>
class ElementRefIterator {
674 template <
bool IsOtherReverse,
bool IsOtherConst>
675 friend class ElementRefIterator;
680 using UnderlayingIteratorTy =
typename std::conditional<
682 typename std::conditional<IsReverse,
684 ElementList::const_iterator>
::type,
686 ElementList::iterator>::type>
::type;
688 using IteratorTraits =
typename std::iterator_traits<UnderlayingIteratorTy>;
689 using ElementRef =
typename CFGBlock::ElementRefImpl<IsConst>;
692 using difference_type =
typename IteratorTraits::difference_type;
693 using value_type = ElementRef;
694 using pointer = ElementRef *;
695 using iterator_category =
typename IteratorTraits::iterator_category;
699 UnderlayingIteratorTy Pos;
702 ElementRefIterator(CFGBlockRef Parent, UnderlayingIteratorTy Pos)
703 :
Parent(Parent), Pos(Pos) {}
705 template <
bool IsOtherConst>
706 ElementRefIterator(ElementRefIterator<false, IsOtherConst> E)
707 : ElementRefIterator(E.Parent, E.Pos.base()) {}
709 template <
bool IsOtherConst>
710 ElementRefIterator(ElementRefIterator<true, IsOtherConst> E)
711 : ElementRefIterator(E.Parent, llvm::make_reverse_iterator(E.Pos)) {}
713 bool operator<(ElementRefIterator Other)
const {
714 assert(Parent == Other.Parent);
715 return Pos < Other.Pos;
718 bool operator==(ElementRefIterator Other)
const {
719 return Parent == Other.Parent && Pos == Other.Pos;
722 bool operator!=(ElementRefIterator Other)
const {
723 return !(*
this == Other);
727 template <
bool IsOtherConst>
729 getIndexInBlock(CFGBlock::ElementRefIterator<true, IsOtherConst> E) {
730 return E.Parent->size() - (E.Pos - E.Parent->rbegin()) - 1;
733 template <
bool IsOtherConst>
735 getIndexInBlock(CFGBlock::ElementRefIterator<false, IsOtherConst> E) {
736 return E.Pos - E.Parent->begin();
742 difference_type operator-(ElementRefIterator Other)
const {
743 return Pos - Other.Pos;
746 ElementRefIterator operator++() {
750 ElementRefIterator operator++(
int) {
751 ElementRefIterator
Ret = *
this;
755 ElementRefIterator operator+(
size_t count) {
759 ElementRefIterator operator-(
size_t count) {
781 const Stmt *LoopTarget =
nullptr;
800 llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
812 return ReachableBlock;
817 return UnreachableBlock.getPointer();
823 return getReachableBlock();
827 return *getReachableBlock();
831 return getReachableBlock();
835 Kind K = (
Kind) UnreachableBlock.getInt();
836 return K == AB_Normal || K == AB_Alternate;
855 unsigned HasNoReturnElement : 1;
862 : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
863 Succs(C, 1), HasNoReturnElement(
false), Parent(parent) {}
871 size_t getIndexInCFG()
const;
899 llvm::iterator_range<const_reverse_ref_iterator>;
915 return {rref_begin(), rref_end()};
918 unsigned size()
const {
return Elements.size(); }
919 bool empty()
const {
return Elements.empty(); }
987 : IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {}
993 template <
typename IMPL,
bool IsPred>
1004 : I(i), E(e), F(f), From(from) {
1005 while (hasMore() &&
Filter(*I))
1012 do { ++I; }
while (hasMore() &&
Filter(*I));
1020 return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
1047 bool isInevitablySinking()
const;
1060 const Expr *getLastCondition()
const;
1083 bool ShowColors)
const;
1085 void printTerminator(raw_ostream &OS,
const LangOptions &LO)
const;
1086 void printTerminatorJson(raw_ostream &Out,
const LangOptions &LO,
1087 bool AddQuotes)
const;
1090 OS <<
"BB#" << getBlockID();
1097 Elements.push_back(
CFGStmt(statement), C);
1136 Elements.insert(Elements.rbegin(), 1,
CFGScopeEnd(VD, S),
C);
1172 return iterator(Elements.insert(I.base(), Cnt,
1198 Elements.insert(I.base(), Cnt,
CFGScopeEnd(
nullptr,
nullptr),
C));
1215 bool isAlwaysTrue) {}
1233 std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
1240 bool PruneTriviallyFalseEdges =
true;
1241 bool AddEHEdges =
false;
1242 bool AddInitializers =
false;
1243 bool AddImplicitDtors =
false;
1244 bool AddLifetime =
false;
1245 bool AddLoopExit =
false;
1246 bool AddTemporaryDtors =
false;
1247 bool AddScopes =
false;
1248 bool AddStaticInitBranches =
false;
1249 bool AddCXXNewAllocator =
false;
1250 bool AddCXXDefaultInitExprInCtors =
false;
1251 bool AddCXXDefaultInitExprInAggregates =
false;
1252 bool AddRichCXXConstructors =
false;
1253 bool MarkElidedCXXConstructors =
false;
1254 bool AddVirtualBaseBranches =
false;
1255 bool OmitImplicitValueInitializers =
false;
1264 alwaysAddMask[stmtClass] = val;
1269 alwaysAddMask.set();
1330 return TryDispatchBlocks.begin();
1334 return TryDispatchBlocks.end();
1338 TryDispatchBlocks.push_back(block);
1347 assert(Synthetic->
isSingleDecl() &&
"Can handle single declarations only");
1348 assert(Synthetic != Source &&
"Don't include original DeclStmts in map");
1349 assert(!SyntheticDeclStmts.count(Synthetic) &&
"Already in map");
1350 SyntheticDeclStmts[Synthetic] = Source;
1354 llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
1363 return SyntheticDeclStmts.begin();
1368 return SyntheticDeclStmts.end();
1380 template <
typename CALLBACK>
1386 O(const_cast<Stmt*>(
stmt->getStmt()));
1400 unsigned size()
const {
return NumBlockIDs; }
1406 bool isLinear()
const;
1423 return BlkBVC.getAllocator();
1435 CFGBlock* IndirectGotoBlock =
nullptr;
1437 unsigned NumBlockIDs = 0;
1445 std::vector<const CFGBlock *> TryDispatchBlocks;
1449 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
1542 static NodeRef
getEntryNode(const ::clang::CFG *F) {
return &F->getEntry(); }
1545 return F->nodes_begin();
1549 return F->nodes_end();
1552 static unsigned size(const ::clang::CFG* F) {
1558 :
public GraphTraits<Inverse< ::clang::CFGBlock *>> {
1567 :
public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1570 static NodeRef
getEntryNode(const ::clang::CFG *F) {
return &F->getExit(); }
1573 return F->nodes_begin();
1577 return F->nodes_end();
1583 #endif // LLVM_CLANG_ANALYSIS_CFG_H void setIndirectGotoBlock(CFGBlock *B)
Set the block used for indirect goto jumps.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Represents C++ allocator call.
static NodeRef getEntryNode(::clang::CFG *F)
const_iterator end() const
succ_reverse_iterator succ_rbegin()
static unsigned size(const ::clang::CFG *F)
const_reverse_ref_iterator rref_begin() const
const_reverse_ref_iterator rref_end() const
CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
AdjacentBlocks::const_iterator const_pred_iterator
iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C)
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const Stmt * getStmt() const
bool operator==(CanQual< T > x, CanQual< U > y)
succ_iterator succ_begin()
ElementRefIterator< true, false > reverse_ref_iterator
const_pred_reverse_iterator pred_rend() const
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
reverse_ref_iterator rref_begin()
CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
Stmt - This represents one statement.
const_iterator nodes_end() const
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
void prependScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
unsigned getBlockID() const
Decl - This represents one declaration (or definition), e.g.
AdjacentBlocks::iterator succ_iterator
CFGTerminator(Stmt *S, Kind K=StmtBranch)
void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C)
std::reverse_iterator< iterator > reverse_iterator
CFGNewAllocator(const CXXNewExpr *S)
CFGElement operator[](size_t i) const
void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C)
llvm::BumpPtrAllocator & getAllocator()
static ChildIteratorType child_end(NodeRef N)
::clang::CFGBlock::succ_iterator ChildIteratorType
Represents C++ object destructor generated from a call to delete.
const Stmt * getLoopTarget() const
Represents a call to a C++ constructor.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const Stmt * getTriggerStmt() const
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator
unsigned IgnoreDefaultsWithCoveredEnums
A shortcut around virtual base initializers.
void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Represents a point when we exit a loop.
unsigned succ_size() const
static ChildIteratorType child_begin(NodeRef N)
reverse_iterator rbegin()
Represents a variable declaration or definition.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
static ChildIteratorType child_end(NodeRef N)
const ConstructionContext * getConstructionContext() const
synthetic_stmt_range synthetic_stmts() const
const_reverse_iterator rbegin() const
CFGBlock * getReachableBlock() const
Get the reachable block, if one exists.
const CFGBlock & getEntry() const
const Stmt * getTriggerStmt() const
void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, QualType Ty)
const_succ_reverse_iterator succ_rbegin() const
Defines the clang::Expr interface and subclasses for C++ expressions.
const_pred_iterator pred_begin() const
std::reverse_iterator< iterator > reverse_iterator
Represents a function call that returns a C++ object by value.
const ConstructionContext * getConstructionContext() const
pred_const_range preds() const
const_reverse_iterator rend() const
std::vector< const CFGBlock * >::const_iterator try_block_iterator
CFGBlock * getPossiblyUnreachableBlock() const
Get the potentially unreachable block.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void setLoopTarget(const Stmt *loopTarget)
::clang::CFGBlock::const_pred_iterator ChildIteratorType
CFGScopeBegin(const VarDecl *VD, const Stmt *S)
static NodeRef getEntryNode(const clang::CFGBlock *BB)
Represents a member of a struct/union/class.
static ChildIteratorType child_end(NodeRef N)
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S)
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const Stmt * getTerminatorStmt() const
void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C)
const CXXRecordDecl * getCXXRecordDecl() const
const_iterator nodes_begin() const
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
void setTerminator(CFGTerminator Term)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
llvm::iterator_range< succ_iterator > succ_range
const_iterator begin() const
ElementRefIterator< false, true > const_ref_iterator
AdjacentBlocks::const_iterator const_succ_iterator
const_iterator end() const
AdjacentBlocks::iterator pred_iterator
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ElementRefImpl< false > CFGElementRef
A builtin binary operation expression such as "x + y" or "x <= y".
static NodeRef getEntryNode(::clang::CFGBlock *BB)
CFGBlockListTy::iterator iterator
const VarDecl * getVarDecl() const
const CXXBaseSpecifier * getBaseSpecifier() const
void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C)
const_succ_iterator succ_end() const
FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, const CFGBlock *from, const FilterOptions &f)
Represents binding an expression to a temporary.
CFGScopeEnd(const VarDecl *VD, const Stmt *S)
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
static ChildIteratorType child_end(NodeRef N)
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
CFGBlockListTy::const_iterator const_iterator
CXXCtorInitializer * getInitializer() const
void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC, BumpVectorContext &C)
static nodes_iterator nodes_begin(::clang::CFG *F)
static ChildIteratorType child_begin(NodeRef N)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const FieldDecl * getFieldDecl() const
const_iterator begin() const
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C)
Represents a single basic block in a source-level CFG.
const_ref_iterator_range refs() const
const VarDecl * getVarDecl() const
CFGCXXRecordTypedCall(Expr *E, const ConstructionContext *C)
::clang::CFG::const_iterator nodes_iterator
This represents one expression.
const_succ_iterator succ_begin() const
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
void dumpToStream(llvm::raw_ostream &OS) const
::clang::CFGBlock::const_succ_iterator ChildIteratorType
Represents a C++ destructor within a class.
CFGLoopExit(const Stmt *stmt)
Represents C++ constructor call.
const_reverse_iterator rend() const
ElementList::const_iterator const_iterator
bool isTemporaryDtorsBranch() const
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val)
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const
const_pred_iterator pred_end() const
succ_const_range succs() const
std::reverse_iterator< const_iterator > const_reverse_iterator
static NodeRef getEntryNode(Inverse< const ::clang::CFGBlock *> G)
Represents C++ object destructor implicitly generated for base object in destructor.
llvm::iterator_range< reverse_ref_iterator > reverse_ref_iterator_range
void addTryDispatchBlock(const CFGBlock *block)
reverse_iterator rbegin()
try_block_iterator try_blocks_begin() const
const_succ_reverse_iterator succ_rend() const
void appendStmt(Stmt *statement, BumpVectorContext &C)
QualType getCanonicalType() const
CFGImplicitDtor(Kind kind, const void *data1, const void *data2=nullptr)
virtual void compareBitwiseOr(const BinaryOperator *B)
llvm::iterator_range< ref_iterator > ref_iterator_range
pred_reverse_iterator pred_rend()
BuildOptions & setAlwaysAdd(Stmt::StmtClass stmtClass, bool val=true)
reverse_iterator rbegin()
::clang::CFGBlock::const_pred_iterator ChildIteratorType
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
void setLabel(Stmt *Statement)
iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S)
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
llvm::iterator_range< const_succ_iterator > succ_const_range
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue)
succ_reverse_iterator succ_rend()
static NodeRef getEntryNode(::clang::CFG *F)
CFGTerminator Terminator
The terminator for a basic block that indicates the type of control-flow that occurs between a block ...
A branch in control flow of destructors of temporaries.
static bool isCXXRecordTypedCall(Expr *E)
Returns true when call expression CE needs to be represented by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
llvm::PointerIntPair< void *, 2 > Data1
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
CFGConstructor(CXXConstructExpr *CE, const ConstructionContext *C)
BumpVectorContext & getBumpVectorContext()
ElementRefIterator< false, false > ref_iterator
void appendScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
static ChildIteratorType child_begin(NodeRef N)
BuildOptions & setAllAlwaysAdd()
const_pred_reverse_iterator pred_rbegin() const
bool isStmtBranch() const
Represents end of a scope implicitly generated by the compiler after the last Stmt in a CompoundStmt'...
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
FilteredCFGBlockIterator & operator++()
const Stmt * getTerminatorCondition(bool StripParens=true) const
static NodeRef getEntryNode(const ::clang::CFG *F)
pred_iterator pred_begin()
static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G)
const VarDecl * getVarDecl() const
std::reverse_iterator< const_iterator > const_reverse_iterator
Dataflow Directional Tag Classes.
llvm::PointerIntPair< void *, 2 > Data2
void VisitBlockStmts(CALLBACK &O) const
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
static nodes_iterator nodes_begin(const ::clang::CFG *F)
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 VarDecl * getVarDecl() const
llvm::iterator_range< const_pred_iterator > pred_const_range
bool NE(InterpState &S, CodePtr OpPC)
static nodes_iterator nodes_begin(const ::clang::CFG *F)
void appendCXXRecordTypedCall(Expr *E, const ConstructionContext *CC, BumpVectorContext &C)
static unsigned size(::clang::CFG *F)
unsigned pred_size() const
A branch that corresponds to a statement in the code, such as an if-statement.
StmtClass getStmtClass() const
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C)
bool isVirtualBaseBranch() const
Stmt * getTerminatorStmt()
static nodes_iterator nodes_begin(::clang::CFG *F)
void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C)
void appendInitializer(CXXCtorInitializer *initializer, BumpVectorContext &C)
static const Stmt * getTerminatorCondition(const CFGBlock *B)
A customized wrapper for CFGBlock::getTerminatorCondition() which returns the element for ObjCForColl...
reverse_ref_iterator rref_end()
This class represents a potential adjacent block in the CFG.
CFGInitializer(CXXCtorInitializer *initializer)
llvm::iterator_range< const_reverse_ref_iterator > const_reverse_ref_iterator_range
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
const Stmt * getLoopStmt() const
static nodes_iterator nodes_end(const ::clang::CFG *F)
Represents the point where the lifetime of an automatic object ends.
::clang::CFG::iterator nodes_iterator
const CXXDeleteExpr * getDeleteExpr() const
pred_reverse_iterator pred_rbegin()
CFGBlock * getIndirectGotoBlock()
ElementRefIterator< true, true > const_reverse_ref_iterator
ElementRefImpl< true > ConstCFGElementRef
const CFGBlock * operator*() const
bool alwaysAdd(const Stmt *stmt) const
try_block_iterator try_blocks_end() const
Represents a C++ base or member initializer.
const CFGBlock * getIndirectGotoBlock() const
AdjacentBlocks::reverse_iterator succ_reverse_iterator
iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S)
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Represents a base class of a C++ class.
::clang::CFG::iterator nodes_iterator
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2=nullptr)
CFGStmt(Stmt *S, Kind K=Statement)
unsigned IgnoreNullPredecessors
bool hasNoReturnElement() const
void setHasNoReturnElement()
CFGMemberDtor(const FieldDecl *field)
const CXXNewExpr * getAllocatorExpr() const
static nodes_iterator nodes_end(::clang::CFG *F)
ConstructionContext's subclasses describe different ways of constructing an object in C++...
void printAsOperand(raw_ostream &OS, bool)
Represents a C++ struct/union/class.
llvm::iterator_range< synthetic_stmt_iterator > synthetic_stmt_range
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)
llvm::iterator_range< pred_iterator > pred_range
Represents C++ object destructor implicitly generated by compiler on various occasions.
bool operator!=(CanQual< T > x, CanQual< U > y)
reverse_ref_iterator_range rrefs()
Represents a top-level expression in a basic block.
const CFGBlock & getExit() const
ref_iterator_range refs()
const Stmt * getStmt() const
static NodeRef getEntryNode(const ::clang::CFG *F)
unsigned kind
All of the diagnostics that can be emitted by the frontend.
synthetic_stmt_iterator synthetic_stmt_end() const
ElementList Elements
The set of statements in the basic block.
Represents CFGBlock terminator statement.
Represents C++ object destructor implicitly generated for member object in destructor.
AdjacentBlocks::reverse_iterator pred_reverse_iterator
void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C)
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
unsigned BlockID
A numerical ID assigned to a CFGBlock during construction of the CFG.
const Stmt * getTriggerStmt() const
const_ref_iterator ref_end() const
const_reverse_ref_iterator_range rrefs() const
const Stmt * getTriggerStmt() const
CFGBaseDtor(const CXXBaseSpecifier *base)
const AdjacentBlock * const_iterator
Represents C++ base or member initializer from constructor's initialization list. ...
const_reverse_iterator rbegin() const
filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const
CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
CFGTerminator getTerminator() const
const_ref_iterator ref_begin() const
llvm::iterator_range< const_ref_iterator > const_ref_iterator_range
const Stmt * getLabel() const
void setEntry(CFGBlock *B)
Set the entry block of the CFG.
iterator beginLifetimeEndsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source)
Records a synthetic DeclStmt and the DeclStmt it was constructed from.
::clang::CFG::const_iterator nodes_iterator
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
static nodes_iterator nodes_end(::clang::CFG *F)
static ChildIteratorType child_begin(NodeRef N)
Represents beginning of a scope implicitly generated by the compiler on encountering a CompoundStmt...
Represents the point where a loop ends.