diff options
author | Mike Stump <mrs@apple.com> | 2009-07-22 22:56:04 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-07-22 22:56:04 +0000 |
commit | 0979d80615df97c675423de631c1b884819f4712 (patch) | |
tree | 18d1d588ec10fed6e56d062ecf078b61f3946c9f /lib/Analysis/CFG.cpp | |
parent | f0549e2b5c73d65ce96fc37c9030577997fe19d4 (diff) |
Improve CFG support for C++ throw expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76814 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFG.cpp')
-rw-r--r-- | lib/Analysis/CFG.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 4c2ecb92f6..f43631c4d0 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -99,6 +99,7 @@ private: CFGBlock *VisitCompoundStmt(CompoundStmt *C); CFGBlock *VisitConditionalOperator(ConditionalOperator *C); CFGBlock *VisitContinueStmt(ContinueStmt *C); + CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T); CFGBlock *VisitDeclStmt(DeclStmt *DS); CFGBlock *VisitDeclSubExpr(Decl* D); CFGBlock *VisitDefaultStmt(DefaultStmt *D); @@ -319,6 +320,9 @@ tryAgain: case Stmt::ObjCAtCatchStmtClass: return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S)); + case Stmt::CXXThrowExprClass: + return VisitCXXThrowExpr(cast<CXXThrowExpr>(S)); + case Stmt::ObjCAtSynchronizedStmtClass: return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S)); @@ -1262,6 +1266,23 @@ CFGBlock* CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return VisitStmt(S, true); } +CFGBlock* CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr* T) { + // If we were in the middle of a block we stop processing that block and + // reverse its statements. + if (Block && !FinishBlock(Block)) + return 0; + + // Create the new block. + Block = createBlock(false); + + // The Exit block is the only successor. + Block->addSuccessor(&cfg->getExit()); + + // Add the statement to the block. This may create new blocks if S contains + // control-flow (short-circuit operations). + return VisitStmt(T, true); +} + CFGBlock *CFGBuilder::VisitDoStmt(DoStmt* D) { // See if this is a known constant. bool KnownTrue = false; |