Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp	(revision 114448)
+++ lib/Analysis/CFG.cpp	(working copy)
@@ -52,6 +52,106 @@
   Kind k;
 };
 
+/// LocalScope - Node in tree of local scopes created for C++ implicit
+/// destructor calls generation. It contains list of automatic variables
+/// declared in the scope and link to position in previous scope this scope
+/// began in.
+///
+/// The process of creating local scopes is as follows:
+/// - Init CFGBuilder::ScopePos with invalid position (equivalent for null),
+/// - Before processing statements in scope (e.g. CompoundStmt) create
+///   LocalScope object using CFGBuilder::ScopePos as link to previous scope
+///   and set CFGBuilder::ScopePos to the end of new scope,
+/// - On every occurance of VarDecl increase CFGBuilder::ScopePos if it points
+///   at this VarDecl,
+/// - For every normal (without jump) end of scope add to CFGBlock destructors
+///   for objects in the current scope,
+/// - For every jump add to CFGBlock destructors for objects
+///   between CFGBuilder::ScopePos and local scope position saved for jump
+///   target. Thanks to C++ restrictions on goto jumps we can be sure that
+///   jump target position will be on the path to root from CFGBuilder::ScopePos
+///   (adding any variable that doesn't need constructor to be called to
+///   LocalScope can break this assumption),
+///
+class LocalScope {
+public:
+  typedef llvm::SmallVector<VarDecl*, 4> AutomaticVarsTy;
+  typedef AutomaticVarsTy::const_reverse_iterator AutomaticVarsIter;
+
+  /// const_iterator - Iterates local scope backwards and jumps to previous
+  /// scope on reaching the begining of currently iterated scope.
+  class const_iterator {
+    const LocalScope* Scope;
+    AutomaticVarsIter VarIter;
+
+    /// GuardScope - Guard for "valid" invalid iterator. This allows for simpler
+    /// implementation of increment operator for LocalScope::const_iterator.
+    static LocalScope GuardScope;
+
+  public:
+    /// Create invalid iterator.
+    const_iterator()
+        : Scope(&GuardScope), VarIter(Scope->Vars.rbegin()) {}
+    
+    /// Create valid iterator.
+    const_iterator(const LocalScope* Scope, AutomaticVarsIter VarIter)
+        : Scope(Scope), VarIter(VarIter) {}
+
+    VarDecl* operator*() const { return *VarIter; }
+    VarDecl* const* operator->() const { return &*VarIter; }
+
+    const_iterator& operator++() {
+      ++VarIter;
+      if (VarIter == Scope->Vars.rend())
+        *this = Scope->Prev;
+      return *this;
+    }
+
+    bool operator==(const const_iterator& rhs) const {
+      return Scope == rhs.Scope && VarIter == rhs.VarIter;
+    }
+    bool operator!=(const const_iterator& rhs) const {
+      return !(*this == rhs);
+    }
+  };
+
+  friend class const_iterator;
+
+private:
+  // Automatic variables in order of declaration.
+  AutomaticVarsTy Vars;
+  // Iterator to variable in previous scope that was declared just before
+  // begin of this scope.
+  const_iterator Prev;
+
+  // Creates invalid scope that can serve as guard scope for iterator.
+  LocalScope()
+      : Vars(1, NULL)
+      , Prev(this, Vars.rbegin()) {}
+
+public:
+  LocalScope(const_iterator P)
+      : Vars()
+      , Prev(P) {}
+
+  // Begin of scope in direction of CFG building (backwards).
+  const_iterator begin() const { return const_iterator(this, Vars.rbegin()); }
+};
+
+LocalScope LocalScope::const_iterator::GuardScope;
+
+/// BlockScopePosPair - Structure for specifing position in CFG during its build
+/// proces. It consists of CFGBlock that specifies position in CFG graph and
+/// LocalScope::const_iterator that specifies position in LocalScope graph.
+struct BlockScopePosPair {
+  BlockScopePosPair() {}
+  BlockScopePosPair(CFGBlock* B, LocalScope::const_iterator S)
+      : Block(B), ScopePos(S) {}
+
+  CFGBlock*                   Block;
+  LocalScope::const_iterator  ScopePos;
+};
+
 /// CFGBuilder - This class implements CFG construction from an AST.
 ///   The builder is stateful: an instance of the builder should be used to only
 ///   construct a single CFG.
@@ -67,24 +167,30 @@
 ///  implicit fall-throughs without extra basic blocks.
 ///
 class CFGBuilder {
+  typedef BlockScopePosPair JumpTarget;
+  typedef BlockScopePosPair JumpSource;
+
   ASTContext *Context;
   llvm::OwningPtr<CFG> cfg;
 
   CFGBlock* Block;
   CFGBlock* Succ;
-  CFGBlock* ContinueTargetBlock;
-  CFGBlock* BreakTargetBlock;
+  JumpTarget ContinueJumpTarget;
+  JumpTarget BreakJumpTarget;
   CFGBlock* SwitchTerminatedBlock;
   CFGBlock* DefaultCaseBlock;
   CFGBlock* TryTerminatedBlock;
 
-  // LabelMap records the mapping from Label expressions to their blocks.
-  typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;
+  // Current position in local scope.
+  LocalScope::const_iterator ScopePos;
+
+  // LabelMap records the mapping from Label expressions to their jump targets.
+  typedef llvm::DenseMap<LabelStmt*, JumpTarget> LabelMapTy;
   LabelMapTy LabelMap;
 
   // A list of blocks that end with a "goto" that must be backpatched to their
   // resolved targets upon completion of CFG construction.
-  typedef std::vector<CFGBlock*> BackpatchBlocksTy;
+  typedef std::vector<JumpSource> BackpatchBlocksTy;
   BackpatchBlocksTy BackpatchBlocks;
 
   // A list of labels whose address has been taken (for indirect gotos).
@@ -97,7 +203,6 @@
 public:
   explicit CFGBuilder() : cfg(new CFG()), // crew a new CFG
                           Block(NULL), Succ(NULL),
-                          ContinueTargetBlock(NULL), BreakTargetBlock(NULL),
                           SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
                           TryTerminatedBlock(NULL), badCFG(false) {}
 
@@ -259,7 +364,7 @@
   for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
                                    E = BackpatchBlocks.end(); I != E; ++I ) {
 
-    CFGBlock* B = *I;
+    CFGBlock* B = I->Block;
     GotoStmt* G = cast<GotoStmt>(B->getTerminator());
     LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
 
@@ -267,7 +372,8 @@
     // incomplete AST.  Handle this by not registering a successor.
     if (LI == LabelMap.end()) continue;
 
-    AddSuccessor(B, LI->second);
+    JumpTarget JT = LI->second;
+    AddSuccessor(B, JT.Block);
   }
 
   // Add successors to the Indirect Goto Dispatch block (if we have one).
@@ -282,7 +388,7 @@
       // at an incomplete AST.  Handle this by not registering a successor.
       if (LI == LabelMap.end()) continue;
       
-      AddSuccessor(B, LI->second);
+      AddSuccessor(B, LI->second.Block);
     }
 
   // Create an empty entry block that has no predecessors.
@@ -549,9 +655,9 @@
 
   // If there is no target for the break, then we are looking at an incomplete
   // AST.  This means that the CFG cannot be constructed.
-  if (BreakTargetBlock)
-    AddSuccessor(Block, BreakTargetBlock);
-  else
+  if (BreakJumpTarget.Block) {
+    AddSuccessor(Block, BreakJumpTarget.Block);
+  } else
     badCFG = true;
 
 
@@ -921,7 +1027,7 @@
     LabelBlock = createBlock(); // scopes that only contains NullStmts.
 
   assert(LabelMap.find(L) == LabelMap.end() && "label already in map");
-  LabelMap[ L ] = LabelBlock;
+  LabelMap[ L ] = JumpTarget(LabelBlock, ScopePos);
 
   // Labels partition blocks, so this is the end of the basic block we were
   // processing (L is the block's label).  Because this is label (and we have
@@ -952,9 +1058,11 @@
 
   if (I == LabelMap.end())
     // We will need to backpatch this block later.
-    BackpatchBlocks.push_back(Block);
-  else
-    AddSuccessor(Block, I->second);
+    BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
+  else {
+    JumpTarget JT = I->second;
+    AddSuccessor(Block, JT.Block);
+  }
 
   return Block;
 }
@@ -962,6 +1070,8 @@
 CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
   CFGBlock* LoopSuccessor = NULL;
 
+  LocalScope::const_iterator LoopBeginScopePos = ScopePos;
+
   // "for" is a control-flow statement.  Thus we stop processing the current
   // block.
   if (Block) {
@@ -973,8 +1083,8 @@
 
   // Save the current value for the break targets.
   // All breaks should go to the code following the loop.
-  SaveAndRestore<CFGBlock*> save_break(BreakTargetBlock);
-  BreakTargetBlock = LoopSuccessor;
+  SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
+  BreakJumpTarget = JumpTarget(LoopSuccessor, LoopBeginScopePos);
 
   // Because of short-circuit evaluation, the condition of the loop can span
   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
@@ -1025,8 +1135,8 @@
     assert(F->getBody());
 
    // Save the current values for Block, Succ, and continue targets.
-   SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
-      save_continue(ContinueTargetBlock);
+   SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
+   SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget);
 
     // Create a new block to contain the (bottom) of the loop body.
     Block = NULL;
@@ -1050,18 +1160,18 @@
       Block = 0;
     }
 
-    ContinueTargetBlock = Succ;
+    ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos);
 
     // 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.
-    ContinueTargetBlock->setLoopTarget(F);
+    ContinueJumpTarget.Block->setLoopTarget(F);
 
     // 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());
 
     if (!BodyBlock)
-      BodyBlock = ContinueTargetBlock; // can happen for "for (...;...;...) ;"
+      BodyBlock = ContinueJumpTarget.Block;//can happen for "for (...;...;...);"
     else if (badCFG)
       return 0;
 
@@ -1170,11 +1280,12 @@
   // Now create the true branch.
   {
     // Save the current values for Succ, continue and break targets.
-    SaveAndRestore<CFGBlock*> save_Succ(Succ),
-      save_continue(ContinueTargetBlock), save_break(BreakTargetBlock);
+    SaveAndRestore<CFGBlock*> save_Succ(Succ);
+    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
+        save_break(BreakJumpTarget);
 
-    BreakTargetBlock = LoopSuccessor;
-    ContinueTargetBlock = EntryConditionBlock;
+    BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
+    ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
 
     CFGBlock* BodyBlock = addStmt(S->getBody());
 
@@ -1230,6 +1341,8 @@
 CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
   CFGBlock* LoopSuccessor = NULL;
 
+  LocalScope::const_iterator LoopBeginScopePos = ScopePos;
+
   // "while" is a control-flow statement.  Thus we stop processing the current
   // block.
   if (Block) {
@@ -1285,9 +1398,9 @@
     assert(W->getBody());
 
     // Save the current values for Block, Succ, and continue and break targets
-    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
-                              save_continue(ContinueTargetBlock),
-                              save_break(BreakTargetBlock);
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
+    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
+        save_break(BreakJumpTarget);
 
     // Create an empty block to represent the transition block for looping back
     // to the head of the loop.
@@ -1295,10 +1408,10 @@
     assert(Succ == EntryConditionBlock);
     Succ = createBlock();
     Succ->setLoopTarget(W);
-    ContinueTargetBlock = Succ;
+    ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos);
 
     // All breaks should go to the code following the loop.
-    BreakTargetBlock = LoopSuccessor;
+    BreakJumpTarget = JumpTarget(LoopSuccessor, LoopBeginScopePos);
 
     // NULL out Block to force lazy instantiation of blocks for the body.
     Block = NULL;
@@ -1307,7 +1420,7 @@
     CFGBlock* BodyBlock = addStmt(W->getBody());
 
     if (!BodyBlock)
-      BodyBlock = ContinueTargetBlock; // can happen for "while(...) ;"
+      BodyBlock = ContinueJumpTarget.Block; // can happen for "while(...) ;"
     else if (Block) {
       if (badCFG)
         return 0;
@@ -1420,15 +1533,15 @@
     assert(D->getBody());
 
     // Save the current values for Block, Succ, and continue and break targets
-    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
-      save_continue(ContinueTargetBlock),
-      save_break(BreakTargetBlock);
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
+    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
+        save_break(BreakJumpTarget);
 
     // All continues within this loop should go to the condition block
-    ContinueTargetBlock = EntryConditionBlock;
+    ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
 
     // All breaks should go to the code following the loop.
-    BreakTargetBlock = LoopSuccessor;
+    BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
 
     // NULL out Block to force lazy instantiation of blocks for the body.
     Block = NULL;
@@ -1486,9 +1599,9 @@
 
   // If there is no target for the continue, then we are looking at an
   // incomplete AST.  This means the CFG cannot be constructed.
-  if (ContinueTargetBlock)
-    AddSuccessor(Block, ContinueTargetBlock);
-  else
+  if (ContinueJumpTarget.Block) {
+    AddSuccessor(Block, ContinueJumpTarget.Block);
+  } else
     badCFG = true;
 
   return Block;
@@ -1535,8 +1648,8 @@
 
   // Save the current "switch" context.
   SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
-                            save_break(BreakTargetBlock),
                             save_default(DefaultCaseBlock);
+  SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
 
   // Set the "default" case to be the block after the switch statement.  If the
   // switch statement contains a "default:", this value will be overwritten with
@@ -1549,7 +1662,7 @@
   // Now process the switch body.  The code after the switch is the implicit
   // successor.
   Succ = SwitchSuccessor;
-  BreakTargetBlock = SwitchSuccessor;
+  BreakJumpTarget = JumpTarget(SwitchSuccessor, ScopePos);
 
   // When visiting the body, the case statements should automatically get linked
   // up to the switch.  We also don't keep a pointer to the body, since all
