Modified StmtIterator to support iteration over the size expressions
of VariableTypeArray types that appear in DeclStmts.

Removed operator-- from StmtIterator.  operator-- added undesired
complexity, and we have no consumers of it.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43471 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/StmtIterator.cpp b/AST/StmtIterator.cpp
index 7a516a7..9db5f61 100644
--- a/AST/StmtIterator.cpp
+++ b/AST/StmtIterator.cpp
@@ -17,63 +17,85 @@
 
 using namespace clang;
 
-static inline bool declHasExpr(ScopedDecl *decl) {
-  if (VarDecl* D = dyn_cast<VarDecl>(decl))
-    if (D->getInit())
-      return true;
-  
-  if (EnumConstantDecl* D = dyn_cast<EnumConstantDecl>(decl))
-    if (D->getInitExpr())
-      return true;
-  
-  return false;  
-}
-
-void StmtIteratorBase::NextDecl() {
-  assert (FirstDecl && decl);
-
-  do decl = decl->getNextDeclarator();
-  while (decl != NULL && !declHasExpr(decl));
-  
-  if (decl == NULL) FirstDecl = NULL;
-}
-
-StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) {
-  assert (d);
-  
-  while (d != NULL && !declHasExpr(d))
-    d = d->getNextDeclarator();
-  
-  FirstDecl = d;
-  decl = d;
-}
-
-void StmtIteratorBase::PrevDecl() {
-  assert (FirstDecl);
-  assert (decl != FirstDecl);
-  
-  // March through the list of decls until we find the decl just before
-  // the one we currently point 
-  
-  ScopedDecl* d = FirstDecl;
-  ScopedDecl* lastVD = d;
-  
-  while (d->getNextDeclarator() != decl) {
-    if (VarDecl* V = dyn_cast<VarDecl>(d))
-      if (V->getInit())
-        lastVD = d;
-
-    d = d->getNextDeclarator();
+static inline VariableArrayType* FindVA(Type* t) {
+  while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
+    if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
+      if (vat->getSizeExpr())
+        return vat;
+    
+    t = vt->getElementType().getTypePtr();
   }
   
-  decl = lastVD;
+  return NULL;
+}
+
+void StmtIteratorBase::NextVA() {
+  assert (getVAPtr());
+
+  VariableArrayType* p = getVAPtr();
+  p = FindVA(p->getElementType().getTypePtr());
+  setVAPtr(p);
+
+  if (!p) {
+    VarDecl* VD = cast<VarDecl>(decl);
+    
+    if (!VD->Init)
+      NextDecl();
+  }
+}
+
+void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
+  assert (inDeclMode());
+  assert (getVAPtr() == NULL);
+  assert (decl);
+  
+  if (ImmediateAdvance) {
+    decl = decl->getNextDeclarator();
+
+    if (!decl) {
+      RawVAPtr = 0;
+      return;
+    }
+  }    
+  
+  for ( ; decl ; decl = decl->getNextDeclarator()) {
+    if (!decl) {
+      RawVAPtr = 0;
+      return;
+    }
+
+    if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {        
+      if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
+        setVAPtr(VAPtr);
+        return;
+      }
+      
+      if (VD->getInit())
+        return;    
+    }
+    else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
+      if (ECD->getInitExpr())
+        return;  
+  }
+}
+
+StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
+  : decl(d), RawVAPtr(DeclMode) {
+  assert (decl);
+  NextDecl(false);
 }
 
 Stmt*& StmtIteratorBase::GetDeclExpr() const {
-  if (VarDecl* D = dyn_cast<VarDecl>(decl))
-    return reinterpret_cast<Stmt*&>(D->Init);
-  else {
-    EnumConstantDecl* Decl = cast<EnumConstantDecl>(decl);
-    return reinterpret_cast<Stmt*&>(Decl->Init);
+  if (VariableArrayType* VAPtr = getVAPtr()) {
+    assert (VAPtr->SizeExpr);
+    return reinterpret_cast<Stmt*&>(VAPtr->SizeExpr);
   }
+
+  if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
+    assert (VD->Init);
+    return reinterpret_cast<Stmt*&>(VD->Init);
+  }
+
+  EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
+  return reinterpret_cast<Stmt*&>(ECD->Init);
 }