aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-08-31 00:36:40 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-08-31 00:36:40 +0000
commit03b16a7d476789d62d61d3e57e75f0bf6a8229bb (patch)
tree21a42730c14398840c1c2d7c89bd8e2bffb59fd7
parent4e4d57069cf9402728e05f7fc856295a86e4801f (diff)
Add a forgotten place where the enclosing namespace set matters, plus a big testcase for inline namespace fun.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112565 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplate.cpp4
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp74
2 files changed, 76 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 47356bc248..e06d38d179 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3440,8 +3440,8 @@ static bool CheckTemplateSpecializationScope(Sema &S,
getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
// There is no prior declaration of this entity, so this
// specialization must be in the same context as the template
- // itself.
- if (!DC->Equals(SpecializedContext)) {
+ // itself, or in the enclosing namespace set.
+ if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
if (isa<TranslationUnitDecl>(SpecializedContext))
S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
<< EntityKind << Specialized;
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
new file mode 100644
index 0000000000..540af17423
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Fun things you can do with inline namespaces:
+
+inline namespace X {
+ void f1();
+
+ inline namespace Y {
+ void f2();
+
+ template <typename T> class C {};
+ }
+
+ // Specialize and partially specialize somewhere else.
+ template <> class C<int> {};
+ template <typename T> class C<T*> {};
+}
+
+// Qualified and unqualified lookup as if member of enclosing NS.
+void foo1() {
+ f1();
+ ::f1();
+ X::f1();
+ Y::f1(); // expected-error {{no member named 'f1' in namespace 'X::Y'}}
+
+ f2();
+ ::f2();
+ X::f2();
+ Y::f2();
+}
+
+template <> class C<float> {};
+template <typename T> class C<T&> {};
+
+template class C<double>;
+
+
+// As well as all the fun with ADL.
+
+namespace ADL {
+ struct Outer {};
+
+ inline namespace IL {
+ struct Inner {};
+
+ void fo(Outer);
+ }
+
+ void fi(Inner);
+
+ inline namespace IL2 {
+ void fi2(Inner);
+ }
+}
+
+void foo2() {
+ ADL::Outer o;
+ ADL::Inner i;
+ fo(o);
+ fi(i);
+ fi2(i);
+}
+
+// Let's not forget overload sets.
+struct Distinct {};
+inline namespace Over {
+ void over(Distinct);
+}
+void over(int);
+
+void foo3() {
+ Distinct d;
+ ::over(d);
+}