From abfb4059e5c4c5ce35649f328d6917b1b6c1ba9c Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Fri, 4 Mar 2011 17:20:30 +0000 Subject: [PATCH] Fixed source range for function template specializations. template void foo(); template <> void foo(); /* Spec 1 */ template <> void foo(); /* 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 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 53d1a9e430..9b0d2611ce 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5065,7 +5065,17 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast(*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(), -- 2.50.1