diff options
author | Nico Weber <nicolasweber@gmx.de> | 2011-12-23 20:58:04 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2011-12-23 20:58:04 +0000 |
commit | d3bdadf616298fa91baebabfeebd491b6b9c40ce (patch) | |
tree | 8f088f81c1a57c1a9bbf16c470aee883fc013838 /clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp | |
parent | 9b6b2e553524d59e496222c045ec0009a7188caf (diff) | |
download | bcm5719-llvm-d3bdadf616298fa91baebabfeebd491b6b9c40ce.tar.gz bcm5719-llvm-d3bdadf616298fa91baebabfeebd491b6b9c40ce.zip |
Fix several issues related to specializations and explicit instantiations.
Explicit instantiations following specializations are no-ops and hence have
no PointOfInstantiation. That was done correctly in most cases, but for a
specialization -> instantiation decl -> instantiation definition chain, the
definition didn't realize that it was a no-op. Fix that.
Also, when printing diagnostics for these no-ops, get the diag location from
the decl name location.
Add many test cases, one of them not yet passing (but it failed the same way
before this change). Fixes http://llvm.org/pr11558 and more.
llvm-svn: 147225
Diffstat (limited to 'clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp')
-rw-r--r-- | clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp index f04c544aa44..89f343869f2 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp @@ -207,3 +207,131 @@ namespace template_class_spec_perClassDecl_nested static void foo(); }; } + + +namespace spec_vs_expl_inst { + + // Test all permutations of Specialization, + // explicit instantiation Declaration, and explicit instantiation defInition. + + namespace SDI { // PR11558 + template <typename STRING_TYPE> class BasicStringPiece; + template <> class BasicStringPiece<int> { }; + extern template class BasicStringPiece<int>; + template class BasicStringPiece<int>; + } + + namespace SID { + template <typename STRING_TYPE> class BasicStringPiece; + template <> class BasicStringPiece<int> { }; + template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} + } + + namespace ISD { + template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} + template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}} + template <> class BasicStringPiece<int> { }; + extern template class BasicStringPiece<int>; + } + + namespace IDS { + template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} + template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::IDS::BasicStringPiece<int>'}} // expected-note {{explicit instantiation definition is here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} + template <> class BasicStringPiece<int> { }; + } + + namespace DIS { + template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}} + template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; + } + + namespace DSI { + template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}} + template <> class BasicStringPiece<int> { }; + template class BasicStringPiece<int>; + } + + // The same again, with a defined template class. + + namespace SDI_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + template <> class BasicStringPiece<int> { }; + extern template class BasicStringPiece<int>; + template class BasicStringPiece<int>; + } + + namespace SID_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + template <> class BasicStringPiece<int> { }; + template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} + } + + namespace ISD_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} + template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} + extern template class BasicStringPiece<int>; + } + + namespace IDS_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}} + extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} + template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}} + } + + namespace DIS_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} + template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} + } + + namespace DSI_WithDefinedTemplate { + template <typename STRING_TYPE> class BasicStringPiece {}; + extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} + template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} + template class BasicStringPiece<int>; + } + + // 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 SIS { + template <typename STRING_TYPE> class BasicStringPiece; + template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} + template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}} + } + + namespace SDS { + template <typename STRING_TYPE> class BasicStringPiece; + template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} + extern template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}} + } + + namespace SDIS { + template <typename STRING_TYPE> class BasicStringPiece; + template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} + extern template class BasicStringPiece<int>; + template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}} + } + +} |