diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-12-03 23:24:04 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-12-03 23:24:04 +0000 |
commit | 2b2a17675243c6f9283d353984d882792805803f (patch) | |
tree | 13b75e4bd97fcacbf9034629bc97b9e4005d41ae /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 391a98afd54acf7205b726196eb646e2d91963d4 (diff) | |
download | bcm5719-llvm-2b2a17675243c6f9283d353984d882792805803f.tar.gz bcm5719-llvm-2b2a17675243c6f9283d353984d882792805803f.zip |
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
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index eb010e9e39a..3745641eb01 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8682,29 +8682,39 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, } } 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(); + } + + // Filter out any other lookup result from an enclosing scope. + FilterLookupForScope(PrevR, CurContext, S, /*ConsiderLinkage*/false, + /*AllowInlineNamespace*/false); - if (PrevDecl) { + // 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 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, 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; |