diff options
Diffstat (limited to 'include/clang/Analysis/CFG.h')
-rw-r--r-- | include/clang/Analysis/CFG.h | 90 |
1 files changed, 66 insertions, 24 deletions
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index ee0be73..14b7ab8 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -43,6 +43,8 @@ namespace clang { class PrinterHelper; class LangOptions; class ASTContext; + class CXXRecordDecl; + class CXXDeleteExpr; /// CFGElement - Represents a top-level expression in a basic block. class CFGElement { @@ -53,6 +55,7 @@ public: Initializer, // dtor kind AutomaticObjectDtor, + DeleteDtor, BaseDtor, MemberDtor, TemporaryDtor, @@ -185,6 +188,31 @@ private: } }; +/// CFGDeleteDtor - Represents C++ object destructor generated +/// from a call to delete. +class CFGDeleteDtor : public CFGImplicitDtor { +public: + CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE) + : CFGImplicitDtor(DeleteDtor, RD, DE) {} + + const CXXRecordDecl *getCXXRecordDecl() const { + return static_cast<CXXRecordDecl*>(Data1.getPointer()); + } + + // Get Delete expression which triggered the destructor call. + const CXXDeleteExpr *getDeleteExpr() const { + return static_cast<CXXDeleteExpr *>(Data2.getPointer()); + } + + +private: + friend class CFGElement; + CFGDeleteDtor() {} + static bool isKind(const CFGElement &elem) { + return elem.getKind() == DeleteDtor; + } +}; + /// CFGBaseDtor - Represents C++ object destructor implicitly generated for /// base object in destructor. class CFGBaseDtor : public CFGImplicitDtor { @@ -269,7 +297,7 @@ public: Stmt &operator*() { return *getStmt(); } const Stmt &operator*() const { return *getStmt(); } - operator bool() const { return getStmt(); } + LLVM_EXPLICIT operator bool() const { return getStmt(); } }; /// CFGBlock - Represents a single basic block in a source-level CFG. @@ -564,6 +592,10 @@ public: Elements.push_back(CFGAutomaticObjDtor(VD, S), C); } + void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { + Elements.push_back(CFGDeleteDtor(RD, DE), C); + } + // Destructors must be inserted in reversed order. So insertion is in two // steps. First we prepare space for some number of elements, then we insert // the elements beginning at the last position in prepared space. @@ -745,6 +777,35 @@ public: TryDispatchBlocks.push_back(block); } + /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. + /// + /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains + /// multiple decls. + void addSyntheticDeclStmt(const DeclStmt *Synthetic, + const DeclStmt *Source) { + assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); + assert(Synthetic != Source && "Don't include original DeclStmts in map"); + assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); + SyntheticDeclStmts[Synthetic] = Source; + } + + typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator + synthetic_stmt_iterator; + + /// Iterates over synthetic DeclStmts in the CFG. + /// + /// Each element is a (synthetic statement, source statement) pair. + /// + /// \sa addSyntheticDeclStmt + synthetic_stmt_iterator synthetic_stmt_begin() const { + return SyntheticDeclStmts.begin(); + } + + /// \sa synthetic_stmt_begin + synthetic_stmt_iterator synthetic_stmt_end() const { + return SyntheticDeclStmts.end(); + } + //===--------------------------------------------------------------------===// // Member templates useful for various batch operations over CFGs. //===--------------------------------------------------------------------===// @@ -763,21 +824,6 @@ public: // CFG Introspection. //===--------------------------------------------------------------------===// - struct BlkExprNumTy { - const signed Idx; - explicit BlkExprNumTy(signed idx) : Idx(idx) {} - explicit BlkExprNumTy() : Idx(-1) {} - operator bool() const { return Idx >= 0; } - operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; } - }; - - bool isBlkExpr(const Stmt *S) { return getBlkExprNum(S); } - bool isBlkExpr(const Stmt *S) const { - return const_cast<CFG*>(this)->isBlkExpr(S); - } - BlkExprNumTy getBlkExprNum(const Stmt *S); - unsigned getNumBlkExprs(); - /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which /// start at 0). unsigned getNumBlockIDs() const { return NumBlockIDs; } @@ -800,9 +846,7 @@ public: //===--------------------------------------------------------------------===// CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), - BlkExprMap(NULL), Blocks(BlkBVC, 10) {} - - ~CFG(); + Blocks(BlkBVC, 10) {} llvm::BumpPtrAllocator& getAllocator() { return BlkBVC.getAllocator(); @@ -819,11 +863,6 @@ private: // for indirect gotos unsigned NumBlockIDs; - // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h. - // It represents a map from Expr* to integers to record the set of - // block-level expressions and their "statement number" in the CFG. - void * BlkExprMap; - BumpVectorContext BlkBVC; CFGBlockListTy Blocks; @@ -832,6 +871,9 @@ private: /// This is the collection of such blocks present in the CFG. std::vector<const CFGBlock *> TryDispatchBlocks; + /// Collects DeclStmts synthesized for this CFG and maps each one back to its + /// source DeclStmt. + llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; }; } // end namespace clang |