]> granicus.if.org Git - clang/commitdiff
Fixed source range for function template specializations.
authorAbramo Bagnara <abramo.bagnara@gmail.com>
Fri, 4 Mar 2011 17:20:30 +0000 (17:20 +0000)
committerAbramo Bagnara <abramo.bagnara@gmail.com>
Fri, 4 Mar 2011 17:20:30 +0000 (17:20 +0000)
template <class T> void foo();
template <> void foo<int>(); /* Spec 1 */
template <> void foo<int>(); /* Spec 2 */

If we look at the main location of the first explicit specialization (Spec 1) it can be seen that it points to the name of the *second* explicit specialization (Spec 2), which is a redeclaration of Spec1.
Hence, the source range obtained for Spec1 is not only inaccurate, but also invalid (the end location comes before the start location).

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

lib/Sema/SemaTemplate.cpp

index 53d1a9e430be5ca687e5a0f1441f84a26dd13c39..9b0d2611ceefe8ca6043e1901af02f54e7088b1c 100644 (file)
@@ -5065,7 +5065,17 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
 
   // Ignore access information;  it doesn't figure into redeclaration checking.
   FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
-  Specialization->setLocation(FD->getLocation());
+
+  FunctionTemplateSpecializationInfo *SpecInfo
+    = Specialization->getTemplateSpecializationInfo();
+  assert(SpecInfo && "Function template specialization info missing?");
+  {
+    // Note: do not overwrite location info if previous template
+    // specialization kind was explicit.
+    TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
+    if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation)
+      Specialization->setLocation(FD->getLocation());
+  }
 
   // FIXME: Check if the prior specialization has a point of instantiation.
   // If so, we have run afoul of .
@@ -5088,10 +5098,6 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
   //   before the first use of that specialization that would cause an implicit
   //   instantiation to take place, in every translation unit in which such a
   //   use occurs; no diagnostic is required.
-  FunctionTemplateSpecializationInfo *SpecInfo
-    = Specialization->getTemplateSpecializationInfo();
-  assert(SpecInfo && "Function template specialization info missing?");
-
   bool HasNoEffect = false;
   if (!isFriend &&
       CheckSpecializationInstantiationRedecl(FD->getLocation(),