diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-23 23:05:07 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-23 23:05:07 +0000 |
commit | f0e71aede7ccf3e311feac6a414c431f7a0fc3c8 (patch) | |
tree | 1a938ca411be2650f194b5f962642556511430cd | |
parent | f1d10d939739f1a4544926d807e4f0f9fb64be61 (diff) |
CFG: record set of C++ 'try' dispatch blocks, which could be of interest to various analyses (e.g., reachability).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138409 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/CFG.h | 16 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 4 |
2 files changed, 18 insertions, 2 deletions
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index c4f521d7a8..d395e0078a 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -613,6 +613,18 @@ public: CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } + + typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator; + try_block_iterator try_blocks_begin() const { + return TryDispatchBlocks.begin(); + } + try_block_iterator try_blocks_end() const { + return TryDispatchBlocks.end(); + } + + void addTryDispatchBlock(const CFGBlock *block) { + TryDispatchBlocks.push_back(block); + } //===--------------------------------------------------------------------===// // Member templates useful for various batch operations over CFGs. @@ -691,6 +703,10 @@ private: BumpVectorContext BlkBVC; CFGBlockListTy Blocks; + + /// C++ 'try' statements are modeled with an indirect dispatch block. + /// This is the collection of such blocks present in the CFG. + std::vector<const CFGBlock *> TryDispatchBlocks; }; } // end namespace clang diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index f268c78dc5..393feffdad 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -2493,8 +2493,8 @@ CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) { Succ = TrySuccessor; // Save the current "try" context. - SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock); - TryTerminatedBlock = NewTryTerminatedBlock; + SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock, NewTryTerminatedBlock); + cfg->addTryDispatchBlock(TryTerminatedBlock); assert(Terminator->getTryBlock() && "try must contain a non-NULL body"); Block = NULL; |