Support templateids in friend declarations.  Fixes bug 4859.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81233 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index c243765..bc2c304 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1121,9 +1121,7 @@
                           SourceLocation LAngleLoc, 
                           ASTTemplateArgsPtr TemplateArgsIn,
                           SourceLocation *TemplateArgLocs,
-                          SourceLocation RAngleLoc,
-                          DeclSpec::TST TagSpec,
-                          SourceLocation TagLoc) {
+                          SourceLocation RAngleLoc) {
   TemplateName Template = TemplateD.getAsVal<TemplateName>();
 
   // Translate the parser's template argument list in our AST format.
@@ -1139,26 +1137,38 @@
   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);
+  return Result.getAsOpaquePtr();
+}
 
-    if (const RecordType *T = Result->getAs<RecordType>()) {
-      RecordDecl *D = T->getDecl();
+Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
+                                              TagUseKind TUK,
+                                              DeclSpec::TST TagSpec,
+                                              SourceLocation TagLoc) {
+  if (TypeResult.isInvalid())
+    return Sema::TypeResult();
 
-      IdentifierInfo *Id = D->getIdentifier();
-      assert(Id && "templated class must have an identifier");
+  QualType Type = QualType::getFromOpaquePtr(TypeResult.get());
 
-      if (!isAcceptableTagRedeclaration(D, TagKind, TagLoc, *Id)) {
-        Diag(TagLoc, diag::err_use_with_wrong_tag)
-          << Id
-          << CodeModificationHint::CreateReplacement(SourceRange(TagLoc),
-                                                     D->getKindName());
-      }
+  // Verify the tag specifier.
+  TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
+  
+  if (const RecordType *RT = Type->getAs<RecordType>()) {
+    RecordDecl *D = RT->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();
+  QualType ElabType = Context.getElaboratedType(Type, TagKind);
+
+  return ElabType.getAsOpaquePtr();
 }
 
 Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template,