]> granicus.if.org Git - clang/commitdiff
Correct that last fixit: if the user wrote
authorJohn McCall <rjmccall@apple.com>
Wed, 24 Mar 2010 08:27:58 +0000 (08:27 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 24 Mar 2010 08:27:58 +0000 (08:27 +0000)
  template <> friend void foo(int);
we need to change it to
  friend void foo<>(int);
or else the user won't get the template specialization they obviously want.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99390 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp

index 1435a8f7212154f11f02443f5bbf7b0d5cdc15e2..e802018c9f80ddd9cc30ff4a84a2f17377439ea0 100644 (file)
@@ -2921,9 +2921,24 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
       // C++0x [temp.expl.spec]p20 forbids "template<> void foo(int);".
       if (isFriend && isFunctionTemplateSpecialization) {
-        SourceRange Range = TemplateParams->getSourceRange();
+        // We want to remove the "template<>", found here.
+        SourceRange RemoveRange = TemplateParams->getSourceRange();
+
+        // If we remove the template<> and the name is not a
+        // template-id, we're actually silently creating a problem:
+        // the friend declaration will refer to an untemplated decl,
+        // and clearly the user wants a template specialization.  So
+        // we need to insert '<>' after the name.
+        SourceLocation InsertLoc;
+        if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
+          InsertLoc = D.getName().getSourceRange().getEnd();
+          InsertLoc = PP.getLocForEndOfToken(InsertLoc);
+        }
+
         Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
-          << Name << Range << CodeModificationHint::CreateRemoval(Range);
+          << Name << RemoveRange
+          << CodeModificationHint::CreateRemoval(RemoveRange)
+          << CodeModificationHint::CreateInsertion(InsertLoc, "<>");
       }
     }