Correctly handle elaborated template ids.  Still not handled properly for friends.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80977 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 746c28a..f1e4968 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2396,7 +2396,9 @@
                       SourceLocation LAngleLoc,
                       ASTTemplateArgsPtr TemplateArgs,
                       SourceLocation *TemplateArgLocs,
-                      SourceLocation RAngleLoc);
+                      SourceLocation RAngleLoc,
+                      DeclSpec::TST TagSpec,
+                      SourceLocation TagLoc);
   
   OwningExprResult BuildTemplateIdExpr(TemplateName Template,
                                        SourceLocation TemplateNameLoc,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index abf9528..e929b5f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3966,14 +3966,7 @@
          "Nameless record must be a definition!");
 
   OwnedDecl = false;
-  TagDecl::TagKind Kind;
-  switch (TagSpec) {
-  default: assert(0 && "Unknown tag type!");
-  case DeclSpec::TST_struct: Kind = TagDecl::TK_struct; break;
-  case DeclSpec::TST_union:  Kind = TagDecl::TK_union; break;
-  case DeclSpec::TST_class:  Kind = TagDecl::TK_class; break;
-  case DeclSpec::TST_enum:   Kind = TagDecl::TK_enum; break;
-  }
+  TagDecl::TagKind Kind = TagDecl::getTagKindForTypeSpec(TagSpec);
   
   if (TUK != TUK_Reference) {
     if (TemplateParameterList *TemplateParams
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 119e17f..8eaa9fb 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1121,7 +1121,9 @@
                           SourceLocation LAngleLoc, 
                           ASTTemplateArgsPtr TemplateArgsIn,
                           SourceLocation *TemplateArgLocs,
-                          SourceLocation RAngleLoc) {
+                          SourceLocation RAngleLoc,
+                          DeclSpec::TST TagSpec,
+                          SourceLocation TagLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
@@ -1137,6 +1139,25 @@
   if (Result.isNull())
     return true;
 
+  // If we were given a tag specifier, verify it.
+  if (TagSpec != DeclSpec::TST_unspecified) {
+    TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
+
+    if (const RecordType *T = Result->getAs<RecordType>()) {
+      RecordDecl *D = T->getDecl();
+
+      IdentifierInfo *Id = D->getIdentifier();
+      assert(Id && "templated class must have an identifier");
+
+      if (!isAcceptableTagRedeclaration(D, TagKind, TagLoc, *Id)) {
+        Diag(TagLoc, diag::err_use_with_wrong_tag)
+          << Id
+          << CodeModificationHint::CreateReplacement(SourceRange(TagLoc),
+                                                     D->getKindName());
+      }
+    }
+  }
+
   return Result.getAsOpaquePtr();
 }
 
@@ -2497,6 +2518,8 @@
                                        SourceLocation RAngleLoc,
                                        AttributeList *Attr,
                                MultiTemplateParamsArg TemplateParameterLists) {
+  assert(TUK == TUK_Declaration || TUK == TUK_Definition);
+
   // Find the class template we're specializing
   TemplateName Name = TemplateD.getAsVal<TemplateName>();
   ClassTemplateDecl *ClassTemplate