summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/CFG.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/CFG.h')
-rw-r--r--include/clang/Analysis/CFG.h90
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
OpenPOWER on IntegriCloud