Introduce redecl_iterator, used for iterating over the redeclarations of a FunctionDecl or VarDecl.

It iterates over all the redeclarations, regardless of the starting point. For example:

1) int f();
2) int f();
3) int f();

if you have the (2) FunctionDecl and call redecls_begin/redecls_end to iterate, you'll get this sequence:
(2)
(1)
(3)

The motivation to introduce this was that, previously, if (3) was a function definition,
and you called getBody() at (2), it would not return it, since getBody() iterated over the previous declarations only,
so it would only check (2) and (1).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75604 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index ae1df92..19f1718 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -351,11 +351,15 @@
 }
 
 const Expr *VarDecl::getDefinition(const VarDecl *&Def) const {
-  Def = this;
-  while (Def && !Def->getInit())
-    Def = Def->getPreviousDeclaration();
+  redecl_iterator I = redecls_begin(), E = redecls_end();
+  while (I != E && !I->getInit())
+    ++I;
 
-  return Def? Def->getInit() : 0;
+  if (I != E) {
+    Def = *I;
+    return I->getInit();
+  }
+  return 0;
 }
 
 void VarDecl::setPreviousDeclaration(VarDecl *PrevDecl) {
@@ -405,11 +409,10 @@
 
 
 Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
-  for (const FunctionDecl *FD = this;
-       FD != 0; FD = FD->getPreviousDeclaration()) {
-    if (FD->Body) {
-      Definition = FD;
-      return FD->Body.get(getASTContext().getExternalSource());
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->Body) {
+      Definition = *I;
+      return I->Body.get(getASTContext().getExternalSource());
     }
   }
 
@@ -417,10 +420,9 @@
 }
 
 Stmt *FunctionDecl::getBodyIfAvailable() const {
-  for (const FunctionDecl *FD = this;
-       FD != 0; FD = FD->getPreviousDeclaration()) {
-    if (FD->Body && !FD->Body.isOffset()) {
-      return FD->Body.get(0);
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    if (I->Body && !I->Body.isOffset()) {
+      return I->Body.get(0);
     }
   }
 
@@ -568,11 +570,9 @@
   if (!isInline() || !hasAttr<GNUInlineAttr>())
     return false;
 
-  for (const FunctionDecl *FD = getPreviousDeclaration(); FD; 
-       FD = FD->getPreviousDeclaration()) {
-    if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>())
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+    if (I->isInline() && !I->hasAttr<GNUInlineAttr>())
       return false;
-  }
 
   return true;
 }
@@ -581,8 +581,8 @@
   if (!hasActiveGNUInlineAttribute(Context))
     return false;
 
-  for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration())
-    if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>())
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+    if (I->getStorageClass() == Extern && I->hasAttr<GNUInlineAttr>())
       return true;
 
   return false;