diff options
author | Marcin Swiderski <marcin.sfider@gmail.com> | 2010-10-01 01:38:14 +0000 |
---|---|---|
committer | Marcin Swiderski <marcin.sfider@gmail.com> | 2010-10-01 01:38:14 +0000 |
commit | 6d5ee0c7f9fc642fcff4690729925b5841b1c869 (patch) | |
tree | 507ce86b8aacd347e273b48e0180c2d83216c001 /clang/lib/Analysis/CFG.cpp | |
parent | e407a3ba1ec9f04d592511cc7540b6e541e0fceb (diff) | |
download | bcm5719-llvm-6d5ee0c7f9fc642fcff4690729925b5841b1c869.tar.gz bcm5719-llvm-6d5ee0c7f9fc642fcff4690729925b5841b1c869.zip |
Added generating CFGAutomaticObjDtors for init statement, condition variable and implicit scope in for statement.
llvm-svn: 115265
Diffstat (limited to 'clang/lib/Analysis/CFG.cpp')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index bc83e207538..ac49ca52ca4 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -1313,8 +1313,23 @@ CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) { CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { CFGBlock* LoopSuccessor = NULL; + // Save local scope position because in case of condition variable ScopePos + // won't be restored when traversing AST. + SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); + + // Create local scope for init statement and possible condition variable. + // Add destructor for init statement and condition variable. + // Store scope position for continue statement. + if (Stmt* Init = F->getInit()) + addLocalScopeForStmt(Init); LocalScope::const_iterator LoopBeginScopePos = ScopePos; + if (VarDecl* VD = F->getConditionVariable()) + addLocalScopeForVarDecl(VD); + LocalScope::const_iterator ContinueScopePos = ScopePos; + + addAutomaticObjDtors(ScopePos, save_scope_pos.get(), F); + // "for" is a control-flow statement. Thus we stop processing the current // block. if (Block) { @@ -1327,7 +1342,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { // Save the current value for the break targets. // All breaks should go to the code following the loop. SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); - BreakJumpTarget = JumpTarget(LoopSuccessor, LoopBeginScopePos); + BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); // Because of short-circuit evaluation, the condition of the loop can span // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that @@ -1383,6 +1398,9 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { // Create a new block to contain the (bottom) of the loop body. Block = NULL; + + // Loop body should end with destructor of Condition variable (if any). + addAutomaticObjDtors(ScopePos, LoopBeginScopePos, F); if (Stmt* I = F->getInc()) { // Generate increment code in its own basic block. This is the target of @@ -1392,7 +1410,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { // No increment code. Create a special, empty, block that is used as the // target block for "looping back" to the start of the loop. assert(Succ == EntryConditionBlock); - Succ = createBlock(); + Succ = Block ? Block : createBlock(); } // Finish up the increment (or empty) block if it hasn't been already. @@ -1403,12 +1421,17 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) { Block = 0; } - ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos); + ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); // The starting block for the loop increment is the block that should // represent the 'loop target' for looping back to the start of the loop. ContinueJumpTarget.Block->setLoopTarget(F); + // If body is not a compound statement create implicit scope + // and add destructors. + if (!isa<CompoundStmt>(F->getBody())) + addLocalScopeAndDtors(F->getBody()); + // Now populate the body block, and in the process create new blocks as we // walk the body of the loop. CFGBlock* BodyBlock = addStmt(F->getBody()); |