diff options
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 10 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-textual.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 16 |
4 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 63581a44dbe..fb05718ff1b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1105,9 +1105,13 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, AddPushedVisibilityAttribute(NewClass); - if (TUK != TUK_Friend) - PushOnScopeChains(NewTemplate, S); - else { + if (TUK != TUK_Friend) { + // Per C++ [basic.scope.temp]p2, skip the template parameter scopes. + Scope *Outer = S; + while ((Outer->getFlags() & Scope::TemplateParamScope) != 0) + Outer = Outer->getParent(); + PushOnScopeChains(NewTemplate, Outer); + } else { if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) { NewTemplate->setAccess(PrevClassTemplate->getAccess()); NewClass->setAccess(PrevClassTemplate->getAccess()); diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h index f7c083249f8..f3c90223091 100644 --- a/clang/test/Modules/Inputs/cxx-templates-common.h +++ b/clang/test/Modules/Inputs/cxx-templates-common.h @@ -40,3 +40,5 @@ template<typename T> struct WithExplicitSpecialization; typedef WithExplicitSpecialization<int> WithExplicitSpecializationUse; template<typename T> struct WithImplicitSpecialMembers { int n; }; + +#include "cxx-templates-textual.h" diff --git a/clang/test/Modules/Inputs/cxx-templates-textual.h b/clang/test/Modules/Inputs/cxx-templates-textual.h new file mode 100644 index 00000000000..8bffb8eddc2 --- /dev/null +++ b/clang/test/Modules/Inputs/cxx-templates-textual.h @@ -0,0 +1,2 @@ +template<typename T> struct MergeClassTemplateSpecializations_basic_string {}; +typedef MergeClassTemplateSpecializations_basic_string<char> MergeClassTemplateSpecializations_string; diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index c173d670802..fedaa03ef4f 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -3,6 +3,11 @@ // RUN: not %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N // RUN: not %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump | FileCheck %s --check-prefix=CHECK-DUMP // RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 +// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 -DEARLY_IMPORT + +#ifdef EARLY_IMPORT +#include "cxx-templates-textual.h" +#endif @import cxx_templates_a; @import cxx_templates_b; @@ -22,8 +27,14 @@ void g() { f<double>(1.0); f<int>(); f(); // expected-error {{no matching function}} +#ifdef EARLY_IMPORT + // FIXME: The textual inclusion above shouldn't affect this! + // expected-note@Inputs/cxx-templates-a.h:3 {{couldn't infer template argument}} + // expected-note@Inputs/cxx-templates-a.h:4 {{requires 1 argument}} +#else // expected-note@Inputs/cxx-templates-b.h:3 {{couldn't infer template argument}} // expected-note@Inputs/cxx-templates-b.h:4 {{requires single argument}} +#endif N::f(0); N::f<double>(1.0); @@ -108,11 +119,15 @@ void g() { int *r = PartiallyInstantiatePartialSpec<int*>::bar(); (void)&WithImplicitSpecialMembers<int>::n; + + MergeClassTemplateSpecializations_string s; } static_assert(Outer<int>::Inner<int>::f() == 1, ""); static_assert(Outer<int>::Inner<int>::g() == 2, ""); +#ifndef EARLY_IMPORT +// FIXME: The textual inclusion above shouldn't cause this to fail! static_assert(MergeTemplateDefinitions<int>::f() == 1, ""); static_assert(MergeTemplateDefinitions<int>::g() == 2, ""); @@ -126,6 +141,7 @@ MergeSpecializations<int[]>::partially_specialized_in_c spec_in_c_1; MergeSpecializations<char>::explicitly_specialized_in_a spec_in_a_2; MergeSpecializations<double>::explicitly_specialized_in_b spec_in_b_2; MergeSpecializations<bool>::explicitly_specialized_in_c spec_in_c_2; +#endif @import cxx_templates_common; |