Add a forgotten place where the enclosing namespace set matters, plus a big testcase for inline namespace fun.

llvm-svn: 112565
This commit is contained in:
Sebastian Redl 2010-08-31 00:36:40 +00:00
parent b5c2baa2d7
commit 35034569c7
2 changed files with 76 additions and 2 deletions

View 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;

View File

@ -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);
}