diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-18 02:28:33 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-10-18 02:28:33 +0000 |
commit | 3e2e91e934ecf083a7c0835b58d9627ca2faddc9 (patch) | |
tree | 91a9ccf45a8c387e6e4ae33a0c3e5ff41f4a41b8 /lib/Sema/SemaTemplate.cpp | |
parent | d80d90d65895a2004b0d01c67ac417cde6cc62fd (diff) |
Refactor the checking for explicit template instantiations being performed in
the right namespace in C++11 mode. Teach the code to prefer the 'must be in
precisely this namespace' diagnostic whenever that's true, and fix a defect
which resulted in the -Wc++11-compat warning in C++98 mode sometimes being
omitted.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142329 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8dda34c8ab..82a88312d7 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5728,45 +5728,41 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, return true; } - // C++0x [temp.explicit]p2: + // C++11 [temp.explicit]p3: // An explicit instantiation shall appear in an enclosing namespace of its - // template. + // template. If the name declared in the explicit instantiation is an + // unqualified name, the explicit instantiation shall appear in the + // namespace where its template is declared or, if that namespace is inline + // (7.3.1), any namespace from its enclosing namespace set. // // This is DR275, which we do not retroactively apply to C++98/03. - if (S.getLangOptions().CPlusPlus0x && - !CurContext->Encloses(OrigContext)) { - if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) + if (WasQualifiedName) { + if (CurContext->Encloses(OrigContext)) + return false; + } else { + if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) + return false; + } + + if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) { + if (WasQualifiedName) S.Diag(InstLoc, S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_out_of_scope - : diag::warn_explicit_instantiation_out_of_scope_0x) + diag::err_explicit_instantiation_out_of_scope : + diag::warn_explicit_instantiation_out_of_scope_0x) << D << NS; else S.Diag(InstLoc, S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_must_be_global - : diag::warn_explicit_instantiation_out_of_scope_0x) - << D; - S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); - return false; - } - - // C++0x [temp.explicit]p2: - // If the name declared in the explicit instantiation is an unqualified - // name, the explicit instantiation shall appear in the namespace where - // its template is declared or, if that namespace is inline (7.3.1), any - // namespace from its enclosing namespace set. - if (WasQualifiedName) - return false; - - if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) - return false; - - S.Diag(InstLoc, - S.getLangOptions().CPlusPlus0x? - diag::err_explicit_instantiation_unqualified_wrong_namespace - : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) - << D << OrigContext; + diag::err_explicit_instantiation_unqualified_wrong_namespace : + diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) + << D << NS; + } else + S.Diag(InstLoc, + S.getLangOptions().CPlusPlus0x? + diag::err_explicit_instantiation_must_be_global : + diag::warn_explicit_instantiation_must_be_global_0x) + << D; S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); return false; } @@ -5776,7 +5772,7 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) { if (!SS.isSet()) return false; - // C++0x [temp.explicit]p2: + // C++11 [temp.explicit]p3: // If the explicit instantiation is for a member function, a member class // or a static data member of a class template specialization, the name of // the class template specialization in the qualified-id for the member |