Push DeclGroup much farther throughout the compiler.  Now the various
productions (except the already broken ObjC cases like @class X,Y;) in 
the parser that can produce more than one Decl return a DeclGroup instead
of a Decl, etc.

This allows elimination of the Decl::NextDeclarator field, and exposes
various clients that should look at all decls in a group, but which were
only looking at one (such as the dumper, printer, etc).  These have been
fixed.

Still TODO:

1) there are some FIXME's in the code about potentially using
DeclGroup for better location info.
2) ParseObjCAtDirectives should return a DeclGroup due to @class etc.
3) I'm not sure what is going on with StmtIterator.cpp, or if it can
   be radically simplified now.
4) I put a truly horrible hack in ParseTemplate.cpp.

I plan to bring up #3/4 on the mailing list, but don't plan to tackle
#1/2 in the short term.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68002 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/clang-cc/ASTConsumers.cpp b/tools/clang-cc/ASTConsumers.cpp
index cb09659..3910c77 100644
--- a/tools/clang-cc/ASTConsumers.cpp
+++ b/tools/clang-cc/ASTConsumers.cpp
@@ -539,8 +539,9 @@
   public:
     ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
     
-    virtual void HandleTopLevelDecl(Decl *D) {
-      PrintDecl(D);
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        PrintDecl(*I);
     }
   };
 } // end anonymous namespace
@@ -562,11 +563,15 @@
       SM = &Context.getSourceManager();
     }
 
-    virtual void HandleTopLevelDecl(Decl *D);
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
   };
 } // end anonymous namespace
 
-void ASTDumper::HandleTopLevelDecl(Decl *D) {
+void ASTDumper::HandleTopLevelSingleDecl(Decl *D) {
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     PrintFunctionDeclStart(FD);
     
@@ -624,12 +629,17 @@
     void Initialize(ASTContext &Context) {
       SM = &Context.getSourceManager();
     }
+
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
     
-    virtual void HandleTopLevelDecl(Decl *D);
+    void HandleTopLevelSingleDecl(Decl *D);
   };
 }
 
-void ASTViewer::HandleTopLevelDecl(Decl *D) {
+void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     DeclPrinter().PrintFunctionDeclStart(FD);
     
diff --git a/tools/clang-cc/AnalysisConsumer.cpp b/tools/clang-cc/AnalysisConsumer.cpp
index 366f384..bc38593 100644
--- a/tools/clang-cc/AnalysisConsumer.cpp
+++ b/tools/clang-cc/AnalysisConsumer.cpp
@@ -220,7 +220,12 @@
       Ctx = &Context;
     }
     
-    virtual void HandleTopLevelDecl(Decl *D);
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    
+    void HandleTopLevelSingleDecl(Decl *D);
     virtual void HandleTranslationUnit(ASTContext &C);
     
     void HandleCode(Decl* D, Stmt* Body, Actions& actions);
@@ -411,7 +416,7 @@
 // AnalysisConsumer implementation.
 //===----------------------------------------------------------------------===//
 
-void AnalysisConsumer::HandleTopLevelDecl(Decl *D) { 
+void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { 
   switch (D->getKind()) {
     case Decl::Function: {
       FunctionDecl* FD = cast<FunctionDecl>(D);
diff --git a/tools/clang-cc/Backend.cpp b/tools/clang-cc/Backend.cpp
index 0faabbe..3b3be31 100644
--- a/tools/clang-cc/Backend.cpp
+++ b/tools/clang-cc/Backend.cpp
@@ -8,11 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "ASTConsumers.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompileOptions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/Module.h"
 #include "llvm/ModuleProvider.h"
 #include "llvm/PassManager.h"
@@ -117,13 +118,14 @@
         LLVMIRGeneration.stopTimer();
     }
     
-    virtual void HandleTopLevelDecl(Decl *D) {
-      PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                      Context->getSourceManager(),
                                      "LLVM IR generation of declaration");
+      
       if (CompileOpts.TimePasses)
         LLVMIRGeneration.startTimer();
-      
+
       Gen->HandleTopLevelDecl(D);
 
       if (CompileOpts.TimePasses)
diff --git a/tools/clang-cc/PrintParserCallbacks.cpp b/tools/clang-cc/PrintParserCallbacks.cpp
index 9dce6d8..dc25f54 100644
--- a/tools/clang-cc/PrintParserCallbacks.cpp
+++ b/tools/clang-cc/PrintParserCallbacks.cpp
@@ -29,8 +29,7 @@
     /// ActOnDeclarator - This callback is invoked when a declarator is parsed
     /// and 'Init' specifies the initializer if any.  This is for things like:
     /// "int X = 4" or "typedef int foo".
-    virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
-                                      DeclPtrTy LastInGroup) {
+    virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
       llvm::cout << __FUNCTION__ << " ";
       if (IdentifierInfo *II = D.getIdentifier()) {
         llvm::cout << "'" << II->getName() << "'";
@@ -40,7 +39,7 @@
       llvm::cout << "\n";
       
       // Pass up to EmptyActions so that the symbol table is maintained right.
-      return MinimalAction::ActOnDeclarator(S, D, LastInGroup);
+      return MinimalAction::ActOnDeclarator(S, D);
     }
     /// ActOnPopScope - This callback is called immediately before the specified
     /// scope is popped and deleted.
@@ -112,17 +111,20 @@
       llvm::cout << __FUNCTION__ << "\n";
     }
 
-    /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
-    /// gives the actions implementation a chance to process the group as a whole.
-    virtual DeclPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy Group) {
+    /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed,
+    /// this gives the actions implementation a chance to process the group as
+    /// a whole.
+    virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
+                                                   unsigned NumDecls) {
       llvm::cout << __FUNCTION__ << "\n";
-      return DeclPtrTy();
+      return DeclGroupPtrTy();
     }
 
     /// ActOnStartOfFunctionDef - This is called at the start of a function
     /// definition, instead of calling ActOnDeclarator.  The Declarator includes
     /// information about formal arguments that are part of this function.
-    virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+    virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope,
+                                              Declarator &D){
       llvm::cout << __FUNCTION__ << "\n";
       return DeclPtrTy();
     }
@@ -256,7 +258,7 @@
       llvm::cout << __FUNCTION__ << "\n";
       return StmtEmpty();
     }
-    virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,
+    virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
                                            SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
       llvm::cout << __FUNCTION__ << "\n";
diff --git a/tools/clang-cc/RewriteBlocks.cpp b/tools/clang-cc/RewriteBlocks.cpp
index 2672d32..f302913 100644
--- a/tools/clang-cc/RewriteBlocks.cpp
+++ b/tools/clang-cc/RewriteBlocks.cpp
@@ -83,7 +83,11 @@
                    const char *NewStr, unsigned NewLength);
 
   // Top Level Driver code.
-  virtual void HandleTopLevelDecl(Decl *D);
+  virtual void HandleTopLevelDecl(DeclGroupRef D) {
+    for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+      HandleTopLevelSingleDecl(*I);
+  }
+  void HandleTopLevelSingleDecl(Decl *D);
   void HandleDeclInMainFile(Decl *D);
   
   // Top level 
@@ -336,7 +340,7 @@
 // Top Level Driver Code
 //===----------------------------------------------------------------------===//
 
-void RewriteBlocks::HandleTopLevelDecl(Decl *D) {
+void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
   // Two cases: either the decl could be in the main file, or it could be in a
   // #included file.  If the former, rewrite it now.  If the later, check to see
   // if we rewrote the #include/#import.
diff --git a/tools/clang-cc/RewriteObjC.cpp b/tools/clang-cc/RewriteObjC.cpp
index e0267ec..5fcecc6 100644
--- a/tools/clang-cc/RewriteObjC.cpp
+++ b/tools/clang-cc/RewriteObjC.cpp
@@ -126,7 +126,11 @@
     virtual void Initialize(ASTContext &context);
 
     // Top Level Driver code.
-    virtual void HandleTopLevelDecl(Decl *D);
+    virtual void HandleTopLevelDecl(DeclGroupRef D) {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+        HandleTopLevelSingleDecl(*I);
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
     void HandleDeclInMainFile(Decl *D);
     RewriteObjC(std::string inFile, std::string outFile,
                 Diagnostic &D, const LangOptions &LOpts);
@@ -550,7 +554,7 @@
 // Top Level Driver Code
 //===----------------------------------------------------------------------===//
 
-void RewriteObjC::HandleTopLevelDecl(Decl *D) {
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
   // Two cases: either the decl could be in the main file, or it could be in a
   // #included file.  If the former, rewrite it now.  If the later, check to see
   // if we rewrote the #include/#import.
@@ -583,7 +587,7 @@
     for (DeclContext::decl_iterator DI = LSD->decls_begin(),
                                  DIEnd = LSD->decls_end();
          DI != DIEnd; ++DI)
-      HandleTopLevelDecl(*DI);
+      HandleTopLevelSingleDecl(*DI);
   }
   // If we have a decl in the main file, see if we should rewrite it.
   if (SM->isFromMainFile(Loc))
diff --git a/tools/clang-cc/SerializationTest.cpp b/tools/clang-cc/SerializationTest.cpp
index 74ccb4b..fda8d88 100644
--- a/tools/clang-cc/SerializationTest.cpp
+++ b/tools/clang-cc/SerializationTest.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CFG.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
 #include "clang.h"
 #include "ASTConsumers.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -73,7 +74,7 @@
     TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl();
     for (DeclContext::decl_iterator I = TUD->decls_begin(), E =TUD->decls_end();
          I != E; ++I)
-      FilePrinter->HandleTopLevelDecl(*I);
+      FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
   }
   
   // Serialize the translation unit.
@@ -124,7 +125,7 @@
     TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl();
     for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
          I != E; ++I)
-      FilePrinter->HandleTopLevelDecl(*I);
+      FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
   }
 
   delete NewCtx;
diff --git a/tools/clang-cc/clang.cpp b/tools/clang-cc/clang.cpp
index c0a2ae7..5b1e6ab 100644
--- a/tools/clang-cc/clang.cpp
+++ b/tools/clang-cc/clang.cpp
@@ -37,6 +37,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/LexDiagnostic.h"
@@ -1563,7 +1564,7 @@
   TranslationUnitDecl *TUD = Ctx->getTranslationUnitDecl();
   for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
        I != E; ++I)
-    Consumer->HandleTopLevelDecl(*I);
+    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
 }