summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-09-03 23:11:22 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-09-03 23:11:22 +0000
commitc8c799318ef2bc679174eca23d34bcfe4aabe63d (patch)
treecd67455431c19cd3389f7c8055710df42c11a843 /lib/Sema/SemaDeclCXX.cpp
parentbf6d49bed14689730ea752c8926bd65321cb5561 (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.cpp63
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;