[cfe-commits] r147798 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp

Nico Weber nicolasweber at gmx.de
Mon Jan 9 11:52:25 PST 2012


Author: nico
Date: Mon Jan  9 13:52:25 2012
New Revision: 147798

URL: http://llvm.org/viewvc/llvm-project?rev=147798&view=rev
Log:
Fix "note" of a duplicate explicit instantiation definition following a specialization.


Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=147798&r1=147797&r2=147798&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jan  9 13:52:25 2012
@@ -5234,6 +5234,23 @@
   }
 }
 
+/// \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 @@
       // 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 @@
       //       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;

Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp?rev=147798&r1=147797&r2=147798&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp Mon Jan  9 13:52:25 2012
@@ -302,15 +302,12 @@
 
   // 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;





More information about the cfe-commits mailing list