Semantic checking for class template declarations and
redeclarations. For example, checks that a class template
redeclaration has the same template parameters as previous
declarations.

Detangled class-template checking from ActOnTag, whose logic was
getting rather convoluted because it tried to handle C, C++, and C++
template semantics in one shot.

Made some inroads toward eliminating extraneous "declaration does not
declare anything" errors by adding an "error" type specifier.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63973 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index b2b0d8f..59c086f 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -345,14 +345,17 @@
     return;
   }
 
-  // Create the tag portion of the class, possibly resulting in a template.
-  DeclTy *TagOrTempDecl
-    = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 
-                       NameLoc, Attr,
-                       Action::MultiTemplateParamsArg(
-                         Actions,
-                         TemplateParams? &(*TemplateParams)[0] : 0,
-                         TemplateParams? TemplateParams->size() : 0));
+  // Create the tag portion of the class or class template.
+  DeclTy *TagOrTempDecl;
+  if (TemplateParams && TK != Action::TK_Reference)
+    TagOrTempDecl = Actions.ActOnClassTemplate(CurScope, TagType, TK, StartLoc,
+                                               SS, Name, NameLoc, Attr,
+                       Action::MultiTemplateParamsArg(Actions, 
+                                                      &(*TemplateParams)[0],
+                                                      TemplateParams->size()));
+  else
+    TagOrTempDecl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 
+                                     NameLoc, Attr);
 
   // Parse the optional base clause (C++ only).
   if (getLang().CPlusPlus && Tok.is(tok::colon)) {
@@ -372,7 +375,9 @@
   }
 
   const char *PrevSpec = 0;
-  if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl))
+  if (!TagOrTempDecl)
+    DS.SetTypeSpecError();
+  else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl))
     Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 }
 
@@ -731,7 +736,12 @@
   // Enter a scope for the class.
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
 
-  Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+  if (TagDecl)
+    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
+  else {
+    SkipUntil(tok::r_brace, false, false);
+    return;
+  }
 
   // C++ 11p3: Members of a class defined with the keyword class are private
   // by default. Members of a class defined with the keywords struct or union