Add a forgotten place where the enclosing namespace set matters, plus a big testcase...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 31 Aug 2010 00:36:40 +0000 (00:36 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 31 Aug 2010 00:36:40 +0000 (00:36 +0000)
llvm-svn: 112565

clang/lib/Sema/SemaTemplate.cpp
clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp [new file with mode: 0644]

index 47356bc248a58da55665bcf18e7b643fb6052c89..e06d38d1797f4e3c7612c3357ed6cafb52c4d474 100644 (file)
@@ -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/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
new file mode 100644 (file)
index 0000000..540af17
--- /dev/null
@@ -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);
+}