From: Marcin Swiderski Date: Thu, 30 Sep 2010 22:54:37 +0000 (+0000) Subject: Added methods for inserting CFGAutomaticObjDtors to CFGBlocks, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=53de134e7b4686eed40bc031438d8a4560a2cda4;p=clang Added methods for inserting CFGAutomaticObjDtors to CFGBlocks, Fixed some misspells in comments. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115236 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index e0719feed0..3960f51704 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -124,7 +124,7 @@ public: } }; -/// CFGImplicitDtor - Represents C++ object destructor imlicitly generated +/// CFGImplicitDtor - Represents C++ object destructor implicitly generated /// by compiler on various occasions. class CFGImplicitDtor : public CFGElement { protected: @@ -221,6 +221,11 @@ class CFGBlock { typedef ImplTy::const_iterator const_reverse_iterator; void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } + reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, + BumpVectorContext& C) { + return Impl.insert(I, Cnt, E, C); + } + CFGElement front() const { return Impl.back(); } CFGElement back() const { return Impl.front(); } @@ -427,6 +432,18 @@ public: void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) { Elements.push_back(CFGStmt(Statement, asLValue), 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. + iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, + BumpVectorContext& C) { + return iterator(Elements.insert(I.base(), Cnt, CFGElement(), C)); + } + iterator insertAutomaticObjDtor(iterator I, VarDecl* VD, Stmt* S) { + *I = CFGAutomaticObjDtor(VD, S); + return ++I; + } }; /// CFG - Represents a source-level, intra-procedural CFG that represents the diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 912d1edc3c..d82704d1f5 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -310,6 +310,13 @@ private: B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue()); } + void insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I, + LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S); + void appendAutomaticObjDtors(CFGBlock* Blk, LocalScope::const_iterator B, + LocalScope::const_iterator E, Stmt* S); + void prependAutomaticObjDtorsWithTerminator(CFGBlock* Blk, + LocalScope::const_iterator B, LocalScope::const_iterator E); + void AddSuccessor(CFGBlock *B, CFGBlock *S) { B->addSuccessor(S, cfg->getBumpVectorContext()); } @@ -447,6 +454,36 @@ CFGBlock* CFGBuilder::createBlock(bool add_successor) { return B; } +/// insertAutomaticObjDtors - Insert destructor CFGElements for variables with +/// automatic storage duration to CFGBlock's elements vector. Insertion will be +/// performed in place specified with iterator. +void CFGBuilder::insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I, + LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S) { + BumpVectorContext& C = cfg->getBumpVectorContext(); + I = Blk->beginAutomaticObjDtorsInsert(I, B.distance(E), C); + while (B != E) + I = Blk->insertAutomaticObjDtor(I, *B++, S); +} + +/// appendAutomaticObjDtors - Append destructor CFGElements for variables with +/// automatic storage duration to CFGBlock's elements vector. Elements will be +/// appended to physical end of the vector which happens to be logical +/// beginning. +void CFGBuilder::appendAutomaticObjDtors(CFGBlock* Blk, + LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S) { + insertAutomaticObjDtors(Blk, Blk->begin(), B, E, S); +} + +/// prependAutomaticObjDtorsWithTerminator - Prepend destructor CFGElements for +/// variables with automatic storage duration to CFGBlock's elements vector. +/// Elements will be prepended to physical beginning of the vector which +/// happens to be logical end. Use blocks terminator as statement that specifies +/// destructors call site. +void CFGBuilder::prependAutomaticObjDtorsWithTerminator(CFGBlock* Blk, + LocalScope::const_iterator B, LocalScope::const_iterator E) { + insertAutomaticObjDtors(Blk, Blk->end(), B, E, Blk->getTerminator()); +} + /// Visit - Walk the subtree of a statement and add extra /// blocks for ternary operators, &&, and ||. We also process "," and /// DeclStmts (which may contain nested control-flow).