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/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
index 59a04da..4bcb478 100644
--- a/lib/Sema/ParseAST.cpp
+++ b/lib/Sema/ParseAST.cpp
@@ -44,16 +44,14 @@
   
   Consumer->Initialize(Ctx);
   
-  Parser::DeclPtrTy ADecl;
+  Parser::DeclGroupPtrTy ADecl;
   
   while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
     // If we got a null return and something *was* parsed, ignore it.  This
     // is due to a top-level semicolon, an action override, or a parse error
     // skipping something.
-    if (ADecl) {
-      Decl *D = ADecl.getAs<Decl>();      
-      Consumer->HandleTopLevelDecl(D);
-    }
+    if (ADecl)
+      Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
   };
   
   Consumer->HandleTranslationUnit(Ctx);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 0ebccf3..b7903c1 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -328,29 +328,28 @@
   /// an empty string if not.  This is used for pretty crash reporting. 
   virtual std::string getDeclName(DeclPtrTy D);
   
+  DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
+
   virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, 
                               Scope *S, const CXXScopeSpec *SS);
-  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
-                                    DeclPtrTy LastInGroup){
-    return ActOnDeclarator(S, D, LastInGroup, false);
+  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
+    return ActOnDeclarator(S, D, false);
   }
-  DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy LastInGroup,
-                            bool IsFunctionDefinition);
+  DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition);
   void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
                                         Scope *S);
   NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                    QualType R, Decl* LastDeclarator,
+                                    QualType R,
                                     Decl* PrevDecl, bool& InvalidDecl,
                                     bool &Redeclaration);
   NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                     QualType R, Decl* LastDeclarator,
+                                     QualType R, 
                                      NamedDecl* PrevDecl, bool& InvalidDecl,
                                      bool &Redeclaration);
   bool CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
                                 bool &Redeclaration);
   NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                     QualType R, Decl *LastDeclarator,
-                                     NamedDecl* PrevDecl, 
+                                     QualType R, NamedDecl* PrevDecl, 
                                      bool IsFunctionDefinition,
                                      bool& InvalidDecl, bool &Redeclaration);
   bool CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
@@ -367,8 +366,8 @@
   void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
   void ActOnUninitializedDecl(DeclPtrTy dcl);
   virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
-  virtual DeclPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy Group);
-
+  virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
+                                                 unsigned NumDecls);
   virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);
   virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D);
@@ -490,8 +489,7 @@
                                 Stmt* ParentCompoundStmt);
 
   /// Subroutines of ActOnDeclarator().
-  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
-                                Decl *LastDecl);
+  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
   bool MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
@@ -1084,7 +1082,7 @@
   virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                              MultiStmtArg Elts,
                                              bool isStmtExpr);
-  virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,
+  virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
                                          SourceLocation StartLoc,
                                          SourceLocation EndLoc);
   virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
@@ -1589,8 +1587,7 @@
   virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
                                              Declarator &D,
                                              ExprTy *BitfieldWidth,
-                                             ExprTy *Init,
-                                             DeclPtrTy LastInGroup);
+                                             ExprTy *Init);
 
   virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
                                             Scope *S,
@@ -2076,7 +2073,7 @@
   virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
                       DeclPtrTy *allMethods = 0, unsigned allNum = 0,
                       DeclPtrTy *allProperties = 0, unsigned pNum = 0,
-                      DeclPtrTy *allTUVars = 0, unsigned tuvNum = 0);
+                      DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
   
   virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
                                   FieldDeclarator &FD, ObjCDeclSpec &ODS,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f98da95..be9a0e2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -39,6 +39,10 @@
   return "";
 }
 
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
+  return DeclGroupPtrTy::make(DeclGroupRef(Ptr.getAs<Decl>()));
+}
+
 /// \brief If the identifier refers to a type name within this scope,
 /// return the declaration of that type.
 ///
@@ -1235,10 +1239,7 @@
 }
 
 Sema::DeclPtrTy 
-Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy lastDecl,
-                      bool IsFunctionDefinition) {
-  NamedDecl *LastDeclarator =
-    dyn_cast_or_null<NamedDecl>(lastDecl.getAs<Decl>());
+Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
   DeclarationName Name = GetNameForDeclarator(D);
 
   // All of these full declarators require an identifier.  If it doesn't have
@@ -1356,14 +1357,14 @@
 
   bool Redeclaration = false;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
-    New = ActOnTypedefDeclarator(S, D, DC, R, LastDeclarator, PrevDecl,
+    New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl,
                                  InvalidDecl, Redeclaration);
   } else if (R->isFunctionType()) {
-    New = ActOnFunctionDeclarator(S, D, DC, R, LastDeclarator, PrevDecl, 
+    New = ActOnFunctionDeclarator(S, D, DC, R, PrevDecl, 
                                   IsFunctionDefinition, InvalidDecl,
                                   Redeclaration);
   } else {
-    New = ActOnVariableDeclarator(S, D, DC, R, LastDeclarator, PrevDecl, 
+    New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, 
                                   InvalidDecl, Redeclaration);
   }
 
@@ -1454,8 +1455,7 @@
 
 NamedDecl*
 Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                             QualType R, Decl* LastDeclarator,
-                             Decl* PrevDecl, bool& InvalidDecl, 
+                             QualType R, Decl* PrevDecl, bool& InvalidDecl, 
                              bool &Redeclaration) {
   // Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
   if (D.getCXXScopeSpec().isSet()) {
@@ -1475,7 +1475,7 @@
            diag::err_virtual_non_function);
   }
 
-  TypedefDecl *NewTD = ParseTypedefDecl(S, D, R, LastDeclarator);
+  TypedefDecl *NewTD = ParseTypedefDecl(S, D, R);
   if (!NewTD) return 0;
 
   // Handle attributes prior to checking for duplicates in MergeVarDecl
@@ -1580,8 +1580,7 @@
 
 NamedDecl*
 Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                              QualType R, Decl* LastDeclarator,
-                              NamedDecl* PrevDecl, bool& InvalidDecl,
+                              QualType R,NamedDecl* PrevDecl, bool& InvalidDecl,
                               bool &Redeclaration) {
   DeclarationName Name = GetNameForDeclarator(D);
 
@@ -1645,7 +1644,6 @@
                           // FIXME: Move to DeclGroup...
                           D.getDeclSpec().getSourceRange().getBegin());
   NewVD->setThreadSpecified(ThreadSpecified);
-  NewVD->setNextDeclarator(LastDeclarator);
 
   // Set the lexical context. If the declarator has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
@@ -1800,8 +1798,8 @@
 
 NamedDecl* 
 Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                              QualType R, Decl *LastDeclarator,
-                              NamedDecl* PrevDecl, bool IsFunctionDefinition,
+                              QualType R, NamedDecl* PrevDecl,
+                              bool IsFunctionDefinition,
                               bool& InvalidDecl, bool &Redeclaration) {
   assert(R.getTypePtr()->isFunctionType());
 
@@ -1937,7 +1935,6 @@
                                  // FIXME: Move to DeclGroup...
                                  D.getDeclSpec().getSourceRange().getBegin());
   }
-  NewFD->setNextDeclarator(LastDeclarator);
 
   // Set the lexical context. If the declarator has a C++
   // scope specifier, the lexical context will be different
@@ -2517,39 +2514,29 @@
   }
 }
 
-/// The declarators are chained together backwards, reverse the list.
-Sema::DeclPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy group) {
-  // Often we have single declarators, handle them quickly.
-  Decl *Group = group.getAs<Decl>();
-  if (Group == 0)
-    return DeclPtrTy();
+Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
+                                                   unsigned NumDecls) {
+  llvm::SmallVector<Decl*, 8> Decls;
   
-  Decl *NewGroup = 0;
-  if (Group->getNextDeclarator() == 0) 
-    NewGroup = Group;
-  else { // reverse the list.
-    while (Group) {
-      Decl *Next = Group->getNextDeclarator();
-      Group->setNextDeclarator(NewGroup);
-      NewGroup = Group;
-      Group = Next;
-    }
-  }
+  for (unsigned i = 0; i != NumDecls; ++i)
+    if (Decl *D = Group[i].getAs<Decl>())
+      Decls.push_back(D);
+  
   // Perform semantic analysis that depends on having fully processed both
   // the declarator and initializer.
-  for (Decl *ID = NewGroup; ID; ID = ID->getNextDeclarator()) {
-    VarDecl *IDecl = dyn_cast<VarDecl>(ID);
+  for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
+    VarDecl *IDecl = dyn_cast<VarDecl>(Decls[i]);
     if (!IDecl)
       continue;
     QualType T = IDecl->getType();
-
+    
     // Block scope. C99 6.7p7: If an identifier for an object is declared with
     // no linkage (C99 6.2.2p6), the type for the object shall be complete...
     if (IDecl->isBlockVarDecl() && 
         IDecl->getStorageClass() != VarDecl::Extern) {
       if (!IDecl->isInvalidDecl() &&
           RequireCompleteType(IDecl->getLocation(), T, 
-                                 diag::err_typecheck_decl_incomplete_type))
+                              diag::err_typecheck_decl_incomplete_type))
         IDecl->setInvalidDecl();
     }
     // File scope. C99 6.9.2p2: A declaration of an identifier for and 
@@ -2560,13 +2547,13 @@
     if (IDecl->isTentativeDefinition(Context)) {
       QualType CheckType = T;
       unsigned DiagID = diag::err_typecheck_decl_incomplete_type;
-
+      
       const IncompleteArrayType *ArrayT = Context.getAsIncompleteArrayType(T);
       if (ArrayT) {
         CheckType = ArrayT->getElementType();
         DiagID = diag::err_illegal_decl_array_incomplete_type;
       }
-
+      
       if (IDecl->isInvalidDecl()) {
         // Do nothing with invalid declarations
       } else if ((ArrayT || IDecl->getStorageClass() == VarDecl::Static) &&
@@ -2578,9 +2565,11 @@
       }
     }
   }
-  return DeclPtrTy::make(NewGroup);
+  return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
+                                                   &Decls[0], NumDecls));
 }
 
+
 /// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
 /// to introduce parameters into function prototype scope.
 Sema::DeclPtrTy 
@@ -2722,9 +2711,8 @@
   
   Scope *ParentScope = FnBodyScope->getParent();
 
-  return ActOnStartOfFunctionDef(FnBodyScope,
-                                 ActOnDeclarator(ParentScope, D, DeclPtrTy(), 
-                                                /*IsFunctionDefinition=*/true));
+  DeclPtrTy DP = ActOnDeclarator(ParentScope, D, /*IsFunctionDefinition=*/true);
+  return ActOnStartOfFunctionDef(FnBodyScope, DP);
 }
 
 Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
@@ -3056,8 +3044,7 @@
   }
 }
 
-TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
-                                    Decl *LastDeclarator) {
+TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T) {
   assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
   assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
   
@@ -3076,7 +3063,6 @@
       TD->setTypedefForAnonDecl(NewTD);
   }
 
-  NewTD->setNextDeclarator(LastDeclarator);
   if (D.getInvalidType())
     NewTD->setInvalidDecl();
   return NewTD;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 258641f..ea2af68 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -473,8 +473,7 @@
 /// declarators on it.
 Sema::DeclPtrTy
 Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
-                               ExprTy *BW, ExprTy *InitExpr,
-                               DeclPtrTy LastInGroup) {
+                               ExprTy *BW, ExprTy *InitExpr) {
   const DeclSpec &DS = D.getDeclSpec();
   DeclarationName Name = GetNameForDeclarator(D);
   Expr *BitWidth = static_cast<Expr*>(BW);
@@ -553,10 +552,10 @@
                          AS);
     assert(Member && "HandleField never returns null");
   } else {
-    Member = ActOnDeclarator(S, D, LastInGroup).getAs<Decl>();
+    Member = ActOnDeclarator(S, D).getAs<Decl>();
     if (!Member) {
       if (BitWidth) DeleteExpr(BitWidth);
-      return LastInGroup;
+      return DeclPtrTy();
     }
 
     // Non-instance-fields can't have a bitfield.
@@ -595,7 +594,7 @@
 
   if (isInstField) {
     FieldCollector->Add(cast<FieldDecl>(Member));
-    return LastInGroup;
+    return DeclPtrTy();
   }
   return DeclPtrTy::make(Member);
 }
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index d84a0d1..18e3e4f 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1234,8 +1234,7 @@
 void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
                       DeclPtrTy *allMethods, unsigned allNum,
                       DeclPtrTy *allProperties, unsigned pNum,
-                      DeclPtrTy *allTUVars,
-                      unsigned tuvNum) {
+                      DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
   Decl *ClassDecl = classDecl.getAs<Decl>();
 
   // FIXME: If we don't have a ClassDecl, we have an error. We should consider
@@ -1339,16 +1338,18 @@
       }
     }
   }
-  if (isInterfaceDeclKind)
-    for (unsigned i = 0; i < tuvNum; i++) {
-      if (VarDecl *VDecl = dyn_cast<VarDecl>(allTUVars[i].getAs<Decl>())) {
-        if (VDecl->getStorageClass() != VarDecl::Extern &&
-            VDecl->getStorageClass() != VarDecl::PrivateExtern) {
-          NamedDecl  *ClassNameDecl = dyn_cast<NamedDecl>(ClassDecl);
-          Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass) 
-            << ClassNameDecl->getIdentifier();
+  if (isInterfaceDeclKind) {
+    // Reject invalid vardecls.
+    for (unsigned i = 0; i != tuvNum; i++) {
+      DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
+      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
+        if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
+          if (VDecl->getStorageClass() != VarDecl::Extern &&
+              VDecl->getStorageClass() != VarDecl::PrivateExtern)
+            Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass) 
+              << cast<NamedDecl>(ClassDecl)->getIdentifier();
         }
-     }
+    }
   }
 }
 
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b331911..d258ec3 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -37,31 +37,13 @@
   return Owned(new (Context) NullStmt(SemiLoc));
 }
 
-Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclPtrTy decl,
+Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
                                            SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
-  Decl *D = decl.getAs<Decl>();
-  if (D == 0)
-    return StmtError();
-
-  // This is a temporary hack until we are always passing around
-  // DeclGroupRefs.
-  llvm::SmallVector<Decl*, 10> decls;
-  while (D) { 
-    Decl* d = D;
-    D = D->getNextDeclarator();
-    d->setNextDeclarator(0);
-    decls.push_back(d);
-  }
-
-  assert (!decls.empty());
-
-  if (decls.size() == 1) {
-    DeclGroupRef DG(*decls.begin());                      
-    return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
-  }
-
-  DeclGroupRef DG(DeclGroup::Create(Context, decls.size(), &decls[0]));
+  // If we have an invalid decl, just return an error.
+  if (!dg) return StmtError();
+  
+  DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
   return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
 }