From: Ted Kremenek Date: Wed, 22 Aug 2007 21:51:58 +0000 (+0000) Subject: Added support for "break" statements in source-level ASTs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8a294713e032e4a27bae61c040abb41397952676;p=clang Added support for "break" statements in source-level ASTs. Some comment cleanups. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41299 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/CFG.cpp b/AST/CFG.cpp index 98d9c8f8f8..eb358281ef 100644 --- a/AST/CFG.cpp +++ b/AST/CFG.cpp @@ -56,6 +56,7 @@ class CFGBuilder : public StmtVisitor { CFGBlock* Exit; CFGBlock* Succ; CFGBlock* ContinueTargetBlock; + CFGBlock* BreakTargetBlock; unsigned NumBlocks; typedef llvm::DenseMap LabelMapTy; @@ -66,7 +67,7 @@ class CFGBuilder : public StmtVisitor { public: explicit CFGBuilder() : cfg(NULL), Block(NULL), Exit(NULL), Succ(NULL), - ContinueTargetBlock(NULL), + ContinueTargetBlock(NULL), BreakTargetBlock(NULL), NumBlocks(0) { // Create an empty CFG. cfg = new CFG(); @@ -336,11 +337,15 @@ public: // Save the current values for Block, Succ, and ContinueTargetBlock SaveAndRestore save_Block(Block), save_Succ(Succ), - save_continue(ContinueTargetBlock); + save_continue(ContinueTargetBlock), + save_break(BreakTargetBlock); // All continues within this loop should go to the condition block ContinueTargetBlock = ConditionBlock; + // All breaks should go to the code that follows the loop. + BreakTargetBlock = Block; + // create a new block to contain the body. Block = createBlock(); @@ -389,11 +394,15 @@ public: // Save the current values for Block, Succ, and ContinueTargetBlock SaveAndRestore save_Block(Block), save_Succ(Succ), - save_continue(ContinueTargetBlock); + save_continue(ContinueTargetBlock), + save_break(BreakTargetBlock); // All continues within this loop should go to the condition block ContinueTargetBlock = ConditionBlock; + // All breaks should go to the code that follows the loop. + BreakTargetBlock = Block; + // NULL out Block to force lazy instantiation of blocks for the body. Block = NULL; @@ -403,6 +412,8 @@ public: ConditionBlock->addSuccessor(BodyBlock); } + // Link up the condition block with the code that follows the loop. + // (the false branch). ConditionBlock->addSuccessor(Block); // There can be no more statements in the condition block @@ -414,7 +425,7 @@ public: } CFGBlock* VisitContinueStmt(ContinueStmt* C) { - // While is a control-flow statement. Thus we stop processing the + // "continue" is a control-flow statement. Thus we stop processing the // current block. if (Block) FinishBlock(Block); @@ -429,6 +440,22 @@ public: return Block; } + CFGBlock* VisitBreakStmt(BreakStmt* B) { + // "break" is a control-flow statement. Thus we stop processing the + // current block. + if (Block) FinishBlock(Block); + + // Now create a new block that ends with the continue statement. + Block = createBlock(false); + Block->setTerminator(B); + + // FIXME: We should gracefully handle breaks without resolved targets. + assert (BreakTargetBlock); + + Block->addSuccessor(BreakTargetBlock); + return Block; + } + }; // BuildCFG - A helper function that builds CFGs from ASTS.