summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp10
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-common.h2
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-textual.h2
-rw-r--r--clang/test/Modules/cxx-templates.cpp16
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;
OpenPOWER on IntegriCloud