diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-09-03 23:11:22 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-09-03 23:11:22 +0000 |
commit | c8c799318ef2bc679174eca23d34bcfe4aabe63d (patch) | |
tree | cd67455431c19cd3389f7c8055710df42c11a843 /lib/Sema/SemaDeclCXX.cpp | |
parent | bf6d49bed14689730ea752c8926bd65321cb5561 (diff) |
[modules] Make NamespaceAliasDecl redeclarable, as it should be. This fixes
merging of namespace aliases across modules and improves source fidelity.
Incidentally also fixes PR20816.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 5da6546105..858f2c70b0 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8264,49 +8264,50 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, return NewND; } -Decl *Sema::ActOnNamespaceAliasDef(Scope *S, - SourceLocation NamespaceLoc, - SourceLocation AliasLoc, - IdentifierInfo *Alias, - CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *Ident) { +Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, + SourceLocation AliasLoc, + IdentifierInfo *Alias, CXXScopeSpec &SS, + SourceLocation IdentLoc, + IdentifierInfo *Ident) { // Lookup the namespace name. LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName); LookupParsedName(R, S, &SS); + if (R.isAmbiguous()) + return nullptr; + + if (R.empty()) { + if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { + Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); + return nullptr; + } + } + assert(!R.isAmbiguous() && !R.empty()); + // Check if we have a previous declaration with the same name. - NamedDecl *PrevDecl - = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, - ForRedeclaration); + NamedDecl *PrevDecl = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, + ForRedeclaration); if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S)) PrevDecl = nullptr; if (PrevDecl) { if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) { // We already have an alias with the same name that points to the same - // namespace, so don't create a new one. - // FIXME: At some point, we'll want to create the (redundant) - // declaration to maintain better source information. - if (!R.isAmbiguous() && !R.empty() && - AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) + // namespace; check that it matches. + if (!AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) { + Diag(AliasLoc, diag::err_redefinition_different_namespace_alias) + << Alias; + Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias) + << AD->getNamespace(); return nullptr; - } - - unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition : - diag::err_redefinition_different_kind; - Diag(AliasLoc, DiagID) << Alias; - Diag(PrevDecl->getLocation(), diag::note_previous_definition); - return nullptr; - } - - if (R.isAmbiguous()) - return nullptr; - - if (R.empty()) { - if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { - Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); + } + } else { + unsigned DiagID = isa<NamespaceDecl>(PrevDecl) + ? diag::err_redefinition + : diag::err_redefinition_different_kind; + Diag(AliasLoc, DiagID) << Alias; + Diag(PrevDecl->getLocation(), diag::note_previous_definition); return nullptr; } } @@ -8315,6 +8316,8 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, Alias, SS.getWithLocInContext(Context), IdentLoc, R.getFoundDecl()); + if (PrevDecl) + AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl)); PushOnScopeChains(AliasDecl, S); return AliasDecl; |