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/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 00a3349..56f922d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -324,8 +324,8 @@
 
 /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
 /// action tells us to.  This returns true if the EOF was encountered.
-bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) {
-  Result = DeclPtrTy();
+bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
+  Result = DeclGroupPtrTy();
   if (Tok.is(tok::eof)) {
     Actions.ActOnEndOfTranslationUnit();
     return true;
@@ -342,7 +342,7 @@
 void Parser::ParseTranslationUnit() {
   Initialize();
 
-  DeclPtrTy Res;
+  DeclGroupPtrTy Res;
   while (!ParseTopLevelDecl(Res))
     /*parse them all*/;
   
@@ -368,20 +368,21 @@
 /// [GNU] asm-definition:
 ///         simple-asm-expr ';'
 ///
-Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
+Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() {
+  DeclPtrTy SingleDecl;
   switch (Tok.getKind()) {
   case tok::semi:
     Diag(Tok, diag::ext_top_level_semi);
     ConsumeToken();
     // TODO: Invoke action for top-level semicolon.
-    return DeclPtrTy();
+    return DeclGroupPtrTy();
   case tok::r_brace:
     Diag(Tok, diag::err_expected_external_declaration);
     ConsumeBrace();
-    return DeclPtrTy();
+    return DeclGroupPtrTy();
   case tok::eof:
     Diag(Tok, diag::err_expected_external_declaration);
-    return DeclPtrTy();
+    return DeclGroupPtrTy();
   case tok::kw___extension__: {
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
@@ -394,20 +395,26 @@
     ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
                      "top-level asm block");
 
-    if (!Result.isInvalid())
-      return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
-    return DeclPtrTy();
+    if (Result.isInvalid())
+      return DeclGroupPtrTy();
+    SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
+    break;
   }
   case tok::at:
-    // @ is not a legal token unless objc is enabled, no need to check.
-    return ParseObjCAtDirectives();
+    // @ is not a legal token unless objc is enabled, no need to check for ObjC.
+    /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like
+    /// @class foo, bar;
+    SingleDecl = ParseObjCAtDirectives();
+    break;
   case tok::minus:
   case tok::plus:
-    if (getLang().ObjC1)
-      return ParseObjCMethodDefinition();
-    Diag(Tok, diag::err_expected_external_declaration);
-    ConsumeToken();
-    return DeclPtrTy();
+    if (!getLang().ObjC1) {
+      Diag(Tok, diag::err_expected_external_declaration);
+      ConsumeToken();
+      return DeclGroupPtrTy();
+    }
+    SingleDecl = ParseObjCMethodDefinition();
+    break;
   case tok::kw_using:
   case tok::kw_namespace:
   case tok::kw_typedef:
@@ -420,6 +427,10 @@
     // We can't tell whether this is a function-definition or declaration yet.
     return ParseDeclarationOrFunctionDefinition();
   }
+  
+  // This routine returns a DeclGroup, if the thing we parsed only contains a
+  // single decl, convert it now.
+  return Actions.ConvertDeclToDeclGroup(SingleDecl);
 }
 
 /// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
@@ -438,7 +449,7 @@
 /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
 /// [OMP]   threadprivate-directive                              [TODO]
 ///
-Parser::DeclPtrTy
+Parser::DeclGroupPtrTy
 Parser::ParseDeclarationOrFunctionDefinition(
                                   TemplateParameterLists *TemplateParams,
                                   AccessSpecifier AS) {
@@ -450,7 +461,8 @@
   // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.is(tok::semi)) {
     ConsumeToken();
-    return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
 
   // ObjC2 allows prefix attributes on class interfaces and protocols.
@@ -462,14 +474,18 @@
         !Tok.isObjCAtKeyword(tok::objc_protocol)) {
       Diag(Tok, diag::err_objc_unexpected_attr);
       SkipUntil(tok::semi); // FIXME: better skip?
-      return DeclPtrTy();
+      return DeclGroupPtrTy();
     }
     const char *PrevSpec = 0;
     if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
       Diag(AtLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+    
+    DeclPtrTy TheDecl;
     if (Tok.isObjCAtKeyword(tok::objc_protocol))
-      return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
-    return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
+      TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
+    else
+      TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
 
   // If the declspec consisted only of 'extern' and we have a string
@@ -477,8 +493,10 @@
   // 'extern "C"'.
   if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
       DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
-      DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier)
-    return ParseLinkage(Declarator::FileContext);
+      DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
+    DeclPtrTy TheDecl = ParseLinkage(Declarator::FileContext);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
+  }
 
   // Parse the first declarator.
   Declarator DeclaratorInfo(DS, Declarator::FileContext);
@@ -489,7 +507,7 @@
     SkipUntil(tok::r_brace, true, true);
     if (Tok.is(tok::semi))
       ConsumeToken();
-    return DeclPtrTy();
+    return DeclGroupPtrTy();
   }
 
   // If the declarator is the start of a function definition, handle it.
@@ -500,8 +518,12 @@
       Tok.is(tok::kw___attribute) ||  // int X() __attr__ -> not a function def
       (getLang().CPlusPlus &&
        Tok.is(tok::l_paren)) ) {      // int X(0) -> not a function def [C++]
-    // FALL THROUGH.
-  } else if (DeclaratorInfo.isFunctionDeclarator() &&
+    // Parse the init-declarator-list for a normal declaration.
+    return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+  }
+  
+  
+  if (DeclaratorInfo.isFunctionDeclarator() &&
              (Tok.is(tok::l_brace) ||             // int X() {}
               (!getLang().CPlusPlus &&
                isDeclarationSpecifier()) ||   // int X(f) int f; {}
@@ -519,20 +541,18 @@
       } else {
         SkipUntil(tok::semi);
       }
-      return DeclPtrTy();
+      return DeclGroupPtrTy();
     }
-    return ParseFunctionDefinition(DeclaratorInfo);
-  } else {
-    if (DeclaratorInfo.isFunctionDeclarator())
-      Diag(Tok, diag::err_expected_fn_body);
-    else
-      Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
-    SkipUntil(tok::semi);
-    return DeclPtrTy();
+    DeclPtrTy TheDecl = ParseFunctionDefinition(DeclaratorInfo);
+    return Actions.ConvertDeclToDeclGroup(TheDecl);
   }
-
-  // Parse the init-declarator-list for a normal declaration.
-  return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+  
+  if (DeclaratorInfo.isFunctionDeclarator())
+    Diag(Tok, diag::err_expected_fn_body);
+  else
+    Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
+  SkipUntil(tok::semi);
+  return DeclGroupPtrTy();
 }
 
 /// ParseFunctionDefinition - We parsed and verified that the specified