]> granicus.if.org Git - clang/commitdiff
CFG: record set of C++ 'try' dispatch blocks, which could be of interest to various...
authorTed Kremenek <kremenek@apple.com>
Tue, 23 Aug 2011 23:05:07 +0000 (23:05 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 23 Aug 2011 23:05:07 +0000 (23:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138409 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/CFG.h
lib/Analysis/CFG.cpp

index c4f521d7a8b01a993e662c86be2dfc109beb115f..d395e0078a18f161207198bb5a79707083814dfd 100644 (file)
@@ -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
index f268c78dc5d0cc41520dad87a6aa21121b006c9d..393feffdadad9b9684badcfd98e75e748ff93926 100644 (file)
@@ -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;