diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-23 21:00:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-23 21:00:28 +0000 |
commit | 871cd4c131e0b635de9cc6519832b43bc899633f (patch) | |
tree | 11d916d15234ffd47ea5f7f7f9dca954f40a5752 | |
parent | b429083aff15c87ddf598fc09309b55bb1299bf1 (diff) | |
download | bcm5719-llvm-871cd4c131e0b635de9cc6519832b43bc899633f.tar.gz bcm5719-llvm-871cd4c131e0b635de9cc6519832b43bc899633f.zip |
[modules] If a referenced-but-not-instantiated class template specialization
gets explicitly specialized, don't reuse the previous class template
specialization declaration as a new declaration. The benefit here is fairly
marginal, it harms source fidelity, and this is horrible to model if the
specialization was imported from another module (without this change, it
asserts or worse).
llvm-svn: 209552
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 19 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 7 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 3 | ||||
-rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 1 |
4 files changed, 12 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index dd2faf60d4a..af80f1a5f6e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -6066,24 +6066,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // The canonical type QualType CanonType; - if (PrevDecl && - (PrevDecl->getSpecializationKind() == TSK_Undeclared || - TUK == TUK_Friend)) { - // Since the only prior class template specialization with these - // arguments was referenced but not declared, or we're only - // referencing this specialization as a friend, reuse that - // declaration node as our own, updating its source location and - // the list of outer template parameters to reflect our new declaration. - Specialization = PrevDecl; - Specialization->setLocation(TemplateNameLoc); - if (TemplateParameterLists.size() > 0) { - Specialization->setTemplateParameterListsInfo(Context, - TemplateParameterLists.size(), - TemplateParameterLists.data()); - } - PrevDecl = 0; - CanonType = Context.getTypeDeclType(Specialization); - } else if (isPartialSpecialization) { + if (isPartialSpecialization) { // Build the canonical type that describes the converted template // arguments of the class template partial specialization. TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h index 04acf5929d1..12b647b52de 100644 --- a/clang/test/Modules/Inputs/cxx-templates-a.h +++ b/clang/test/Modules/Inputs/cxx-templates-a.h @@ -56,3 +56,10 @@ template<typename T> struct WithPartialSpecialization<T*> { T &f() { static T t; return t; } }; typedef WithPartialSpecializationUse::type WithPartialSpecializationInstantiate; + +template<> struct WithExplicitSpecialization<int> { + int n; + template<typename T> T &inner_template() { + return n; + } +}; diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h index a31be8758cc..986c52b362c 100644 --- a/clang/test/Modules/Inputs/cxx-templates-common.h +++ b/clang/test/Modules/Inputs/cxx-templates-common.h @@ -33,3 +33,6 @@ template<typename T> struct Outer { template<typename T> struct WithPartialSpecialization {}; typedef WithPartialSpecialization<int*> WithPartialSpecializationUse; + +template<typename T> struct WithExplicitSpecialization; +typedef WithExplicitSpecialization<int> WithExplicitSpecializationUse; diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index a880c9b2f18..f68bc72a271 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -104,6 +104,7 @@ void g() { TemplateInstantiationVisibility<char[4]> tiv4; int &p = WithPartialSpecializationUse().f(); + int &q = WithExplicitSpecializationUse().inner_template<int>(); } RedeclaredAsFriend<int> raf1; |