Coelesce 'DoDestroy()' methods in Stmt.cpp, and modify the child_iterator returned by ForStmt to include the initializer of the condition variable.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92112 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index fae2e62..406684c 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -938,6 +938,9 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
+  
+protected:
+  virtual void DoDestroy(ASTContext &Ctx);
 };
 
 /// GotoStmt - This represents a direct goto.
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index dfdb2ce..ad1db90 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -47,17 +47,6 @@
   return getStmtInfoTableEntry((StmtClass)sClass).Name;
 }
 
-void Stmt::DestroyChildren(ASTContext &C) {
-  for (child_iterator I = child_begin(), E = child_end(); I !=E; )
-    if (Stmt* Child = *I++) Child->Destroy(C);
-}
-
-void Stmt::DoDestroy(ASTContext &C) {
-  DestroyChildren(C);
-  this->~Stmt();
-  C.Deallocate((void *)this);
-}
-
 void Stmt::PrintStats() {
   // Ensure the table is primed.
   getStmtInfoTableEntry(Stmt::NullStmtClass);
@@ -93,26 +82,6 @@
   return StatSwitch;
 }
 
-void SwitchStmt::DoDestroy(ASTContext &Ctx) {
-  // Destroy the SwitchCase statements in this switch. In the normal
-  // case, this loop will merely decrement the reference counts from
-  // the Retain() calls in addSwitchCase();
-  SwitchCase *SC = FirstCase;
-  while (SC) {
-    SwitchCase *Next = SC->getNextSwitchCase();
-    SC->Destroy(Ctx);
-    SC = Next;
-  }
-  
-  // We do not use child_iterator here because that will include
-  // the expressions referenced by the condition variable.
-  for (Stmt **I = &SubExprs[0], **E = &SubExprs[END_EXPR]; I != E; ++I)
-    if (Stmt *Child = *I) Child->Destroy(Ctx);
-  
-  this->~Stmt();
-  Ctx.Deallocate((void *)this);
-}
-
 void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
   if (this->Body)
     C.Deallocate(Body);
@@ -418,6 +387,71 @@
   RParenLoc = rparenloc;
 }
 
+//===----------------------------------------------------------------------===//
+// AST Destruction.
+//===----------------------------------------------------------------------===//
+
+void Stmt::DestroyChildren(ASTContext &C) {
+  for (child_iterator I = child_begin(), E = child_end(); I !=E; )
+    if (Stmt* Child = *I++) Child->Destroy(C);
+}
+
+static void BranchDestroy(ASTContext &C, Stmt *S, Stmt **SubExprs,
+                          unsigned NumExprs) {
+  // We do not use child_iterator here because that will include
+  // the expressions referenced by the condition variable.
+  for (Stmt **I = SubExprs, **E = SubExprs + NumExprs; I != E; ++I)
+    if (Stmt *Child = *I) Child->Destroy(C);
+  
+  S->~Stmt();
+  C.Deallocate((void *) S);
+}
+
+void Stmt::DoDestroy(ASTContext &C) {
+  DestroyChildren(C);
+  this->~Stmt();
+  C.Deallocate((void *)this);
+}
+
+void CXXCatchStmt::DoDestroy(ASTContext& C) {
+  if (ExceptionDecl)
+    ExceptionDecl->Destroy(C);
+  Stmt::DoDestroy(C);
+}
+
+void DeclStmt::DoDestroy(ASTContext &C) {
+  // Don't use StmtIterator to iterate over the Decls, as that can recurse
+  // into VLA size expressions (which are owned by the VLA).  Further, Decls
+  // are owned by the DeclContext, and will be destroyed with them.
+  if (DG.isDeclGroup())
+    DG.getDeclGroup().Destroy(C);
+}
+
+void IfStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void ForStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void SwitchStmt::DoDestroy(ASTContext &C) {
+  // Destroy the SwitchCase statements in this switch. In the normal
+  // case, this loop will merely decrement the reference counts from
+  // the Retain() calls in addSwitchCase();
+  SwitchCase *SC = FirstCase;
+  while (SC) {
+    SwitchCase *Next = SC->getNextSwitchCase();
+    SC->Destroy(C);
+    SC = Next;
+  }
+  
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
+
+void WhileStmt::DoDestroy(ASTContext &C) {
+  BranchDestroy(C, this, SubExprs, END_EXPR);
+}
 
 //===----------------------------------------------------------------------===//
 //  Child Iterators for iterating over subexpressions/substatements
@@ -432,14 +466,6 @@
   return StmtIterator(DG.end(), DG.end());
 }
 
-void DeclStmt::DoDestroy(ASTContext &C) {
-  // Don't use StmtIterator to iterate over the Decls, as that can recurse
-  // into VLA size expressions (which are owned by the VLA).  Further, Decls
-  // are owned by the DeclContext, and will be destroyed with them.
-  if (DG.isDeclGroup())
-    DG.getDeclGroup().Destroy(C);
-}
-
 // NullStmt
 Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
 Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
@@ -467,15 +493,6 @@
 Stmt::child_iterator IfStmt::child_end() {
   return child_iterator(0, &SubExprs[0]+END_EXPR);
 }
-void IfStmt::DoDestroy(ASTContext &C) {
-  // We do not use child_iterator here because that will include
-  // the expressions referenced by the condition variable.
-  for (Stmt **I = &SubExprs[0], **E = &SubExprs[END_EXPR]; I != E; ++I)
-    if (Stmt *Child = *I) Child->Destroy(C);
-
-  this->~Stmt();
-  C.Deallocate((void *)this);
-}
 
 // SwitchStmt
 Stmt::child_iterator SwitchStmt::child_begin() {
@@ -492,24 +509,18 @@
 Stmt::child_iterator WhileStmt::child_end() {
   return child_iterator(0, &SubExprs[0]+END_EXPR);
 }
-void WhileStmt::DoDestroy(ASTContext &C) {
-  // We do not use child_iterator here because that will include
-  // the expressions referenced by the condition variable.
-  for (Stmt **I = &SubExprs[0], **E = &SubExprs[END_EXPR]; I != E; ++I)
-    if (Stmt *Child = *I) Child->Destroy(C);
-  
-  this->~Stmt();
-  C.Deallocate((void *)this);
-}
-
 
 // DoStmt
 Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
 Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
 
 // ForStmt
-Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
-Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
+Stmt::child_iterator ForStmt::child_begin() {
+  return child_iterator(CondVar, &SubExprs[0]);
+}
+Stmt::child_iterator ForStmt::child_end() {
+  return child_iterator(CondVar, &SubExprs[0]+END_EXPR);
+}
 
 // ObjCForCollectionStmt
 Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
@@ -610,12 +621,6 @@
   return QualType();
 }
 
-void CXXCatchStmt::DoDestroy(ASTContext& C) {
-  if (ExceptionDecl)
-    ExceptionDecl->Destroy(C);
-  Stmt::DoDestroy(C);
-}
-
 // CXXTryStmt
 Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
 Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }