Fixed source range for function template specializations.
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
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 53d1a9e..9b0d261 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -5065,7 +5065,17 @@
// 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 @@
// 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(),