diff options
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 29 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp | 15 |
2 files changed, 26 insertions, 18 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2527ac6a1c..b6babb6f75 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5234,6 +5234,23 @@ static void StripImplicitInstantiation(NamedDecl *D) { } } +/// \brief Compute the diagnostic location for an explicit instantiation +// declaration or definition. +static SourceLocation DiagLocForExplicitInstantiation( + NamedDecl* Decl, SourceLocation PointOfInstantiation) { + // Explicit instantiations following a specialization have no effect and + // hence no PointOfInstantiation. In that case, walk decl backwards + // until a valid name loc is found. + SourceLocation PrevDiagLoc = PointOfInstantiation; + for (NamedDecl *Prev = Decl; Prev && !PrevDiagLoc.isValid(); + Prev = getPreviousDecl(Prev)) { + PrevDiagLoc = Prev->getLocation(); + } + assert(PrevDiagLoc.isValid() && + "Explicit instantiation without point of instantiation?"); + return PrevDiagLoc; +} + /// \brief Diagnose cases where we have an explicit template specialization /// before/after an explicit template instantiation, producing diagnostics /// for those cases where they are required and determining whether the @@ -5348,14 +5365,8 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // Explicit instantiations following a specialization have no effect and // hence no PrevPointOfInstantiation. In that case, walk decl backwards // until a valid name loc is found. - SourceLocation PrevDiagLoc = PrevPointOfInstantiation; - for (NamedDecl *Prev = PrevDecl; Prev && !PrevDiagLoc.isValid(); - Prev = getPreviousDecl(Prev)) { - PrevDiagLoc = Prev->getLocation(); - } - Diag(PrevDiagLoc, diag::note_explicit_instantiation_definition_here); - assert(PrevDiagLoc.isValid() && - "Explicit instantiation without point of instantiation?"); + Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation), + diag::note_explicit_instantiation_definition_here); HasNoEffect = true; return false; } @@ -5414,7 +5425,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // in a program, Diag(NewLoc, diag::err_explicit_instantiation_duplicate) << PrevDecl; - Diag(PrevPointOfInstantiation, + Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation), diag::note_previous_explicit_instantiation); HasNoEffect = true; return false; diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp index 89f343869f..aecbfb5649 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp @@ -302,15 +302,12 @@ namespace spec_vs_expl_inst { // And some more random tests. -// FIXME: Enable this test. The error is printed fine, but the note is at some -// weird source location that causes "previous explicit instantiation is here" -// without anything after it to be printed. That happened before this patch too. -// namespace SII_WithDefinedTemplate { -// template <typename STRING_TYPE> class BasicStringPiece {}; -// template <> class BasicStringPiece<int> { }; -// template class BasicStringPiece<int>; -// template class BasicStringPiece<int>; -// } + namespace SII_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + template <> class BasicStringPiece<int> { }; + template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} + template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}} + } namespace SIS { template <typename STRING_TYPE> class BasicStringPiece; |