PR25731: namespace alias declarations can appear at block scope; ensure that we
do scope-based lookup when looking for redeclarations of them. Add some related
missing checks for the scope-based redeclaration lookup: properly filter the
list of found declarations to match the scope, and diagnose shadowing of a
template parameter name.
llvm-svn: 254663
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index eb010e9..3745641 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -8682,29 +8682,39 @@
}
}
assert(!R.isAmbiguous() && !R.empty());
+ NamedDecl *ND = R.getFoundDecl();
// Check if we have a previous declaration with the same name.
LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
ForRedeclaration);
- LookupQualifiedName(PrevR, CurContext->getRedeclContext());
- NamedDecl *PrevDecl = PrevR.getAsSingle<NamedDecl>();
- if (PrevDecl && !isVisible(PrevDecl))
- PrevDecl = nullptr;
+ LookupName(PrevR, S);
- NamedDecl *ND = R.getFoundDecl();
+ // Check we're not shadowing a template parameter.
+ if (PrevR.isSingleResult() && PrevR.getFoundDecl()->isTemplateParameter()) {
+ DiagnoseTemplateParameterShadow(AliasLoc, PrevR.getFoundDecl());
+ PrevR.clear();
+ }
- if (PrevDecl) {
+ // Filter out any other lookup result from an enclosing scope.
+ FilterLookupForScope(PrevR, CurContext, S, /*ConsiderLinkage*/false,
+ /*AllowInlineNamespace*/false);
+
+ // Find the previous declaration and check that we can redeclare it.
+ NamespaceAliasDecl *Prev = nullptr;
+ if (NamedDecl *PrevDecl = PrevR.getAsSingle<NamedDecl>()) {
if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
// We already have an alias with the same name that points to the same
// namespace; check that it matches.
- if (!AD->getNamespace()->Equals(getNamespaceDecl(ND))) {
+ if (AD->getNamespace()->Equals(getNamespaceDecl(ND))) {
+ Prev = AD;
+ } else if (isVisible(PrevDecl)) {
Diag(AliasLoc, diag::err_redefinition_different_namespace_alias)
<< Alias;
Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias)
<< AD->getNamespace();
return nullptr;
}
- } else {
+ } else if (isVisible(PrevDecl)) {
unsigned DiagID = isa<NamespaceDecl>(PrevDecl)
? diag::err_redefinition
: diag::err_redefinition_different_kind;
@@ -8721,8 +8731,8 @@
NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,
Alias, SS.getWithLocInContext(Context),
IdentLoc, ND);
- if (PrevDecl)
- AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl));
+ if (Prev)
+ AliasDecl->setPreviousDecl(Prev);
PushOnScopeChains(AliasDecl, S);
return AliasDecl;