[cfe-commits] r41298 - /cfe/trunk/AST/CFG.cpp
Ted Kremenek
kremenek at apple.com
Wed Aug 22 14:36:54 PDT 2007
Author: kremenek
Date: Wed Aug 22 16:36:54 2007
New Revision: 41298
URL: http://llvm.org/viewvc/llvm-project?rev=41298&view=rev
Log:
Added support for "continue" statements in source-level CFGs
Cleaned up some code for "for" and "while" loops by making their
implementations more symmetrical (and added a few comments).
Modified:
cfe/trunk/AST/CFG.cpp
Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=41298&r1=41297&r2=41298&view=diff
==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Wed Aug 22 16:36:54 2007
@@ -55,6 +55,7 @@
CFGBlock* Block;
CFGBlock* Exit;
CFGBlock* Succ;
+ CFGBlock* ContinueTargetBlock;
unsigned NumBlocks;
typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;
@@ -64,7 +65,8 @@
BackpatchBlocksTy BackpatchBlocks;
public:
- explicit CFGBuilder() : cfg(NULL), Block(NULL), Exit(NULL), Succ(NULL),
+ explicit CFGBuilder() : cfg(NULL), Block(NULL), Exit(NULL), Succ(NULL),
+ ContinueTargetBlock(NULL),
NumBlocks(0) {
// Create an empty CFG.
cfg = new CFG();
@@ -320,15 +322,24 @@
// We create the initialization block last, as that will be the block
// we return for the recursion.
- CFGBlock* CondBlock = createBlock(false);
- if (Stmt* C = F->getCond()) CondBlock->appendStmt(C);
- CondBlock->setTerminator(F);
- Succ = CondBlock;
+ CFGBlock* ConditionBlock = createBlock(false);
+ if (Stmt* C = F->getCond()) ConditionBlock->appendStmt(C);
+ ConditionBlock->setTerminator(F);
+
+ // The condition block is the implicit successor for the loop body as
+ // well as any code above the loop.
+ Succ = ConditionBlock;
// Now create the loop body.
{
assert (F->getBody());
- SaveAndRestore<CFGBlock*> sv(Block);
+
+ // Save the current values for Block, Succ, and ContinueTargetBlock
+ SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+ save_continue(ContinueTargetBlock);
+
+ // All continues within this loop should go to the condition block
+ ContinueTargetBlock = ConditionBlock;
// create a new block to contain the body.
Block = createBlock();
@@ -344,15 +355,14 @@
FinishBlock(BodyBlock);
// This new body block is a successor to our condition block.
- CondBlock->addSuccessor(BodyBlock);
+ ConditionBlock->addSuccessor(BodyBlock);
}
// Link up the condition block with the code that follows the loop.
// (the false branch).
- CondBlock->addSuccessor(Block);
+ ConditionBlock->addSuccessor(Block);
// Now create the block to contain the initialization.
- Succ = CondBlock;
Block = createBlock();
if (Stmt* I = F->getInit()) Block->appendStmt(I);
@@ -363,20 +373,31 @@
// While is a control-flow statement. Thus we stop processing the
// current block.
if (Block) FinishBlock(Block);
-
+
+ // Create the condition block.
CFGBlock* ConditionBlock = createBlock(false);
ConditionBlock->setTerminator(W);
if (Stmt* C = W->getCond()) ConditionBlock->appendStmt(C);
+ // The condition block is the implicit successor for the loop body as
+ // well as any code above the loop.
+ Succ = ConditionBlock;
+
// Process the loop body.
{
assert (W->getBody());
- SaveAndRestore<CFGBlock*> sv(Block);
- Succ = ConditionBlock;
+ // Save the current values for Block, Succ, and ContinueTargetBlock
+ SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+ save_continue(ContinueTargetBlock);
+
+ // All continues within this loop should go to the condition block
+ ContinueTargetBlock = ConditionBlock;
+
+ // NULL out Block to force lazy instantiation of blocks for the body.
Block = NULL;
+
CFGBlock* BodyBlock = Visit(W->getBody());
-
assert (BodyBlock);
ConditionBlock->addSuccessor(BodyBlock);
@@ -388,11 +409,26 @@
// since we loop back to this block. NULL out Block to force
// lazy creation of another block.
Block = NULL;
- Succ = ConditionBlock;
return ConditionBlock;
}
+ CFGBlock* VisitContinueStmt(ContinueStmt* C) {
+ // While 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(C);
+
+ // FIXME: We should gracefully handle continues without resolved targets.
+ assert (ContinueTargetBlock);
+
+ Block->addSuccessor(ContinueTargetBlock);
+ return Block;
+ }
+
};
// BuildCFG - A helper function that builds CFGs from ASTS.
More information about the cfe-commits
mailing list