diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-09 17:30:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-09 17:30:44 +0000 |
commit | c6c8e0ec96bb64f1b9f543d7c8317c6090f80a30 (patch) | |
tree | 39aea2b30aebc4a42f967293a8e28181ab8fc20e /lib/Serialization/ASTReaderDecl.cpp | |
parent | c02d62f0b82c144f7db2a71c3b4565de8c6163e5 (diff) |
Implement redeclaration merging for namespaces defined in distinct
modules. Teach name lookup into namespaces to search in each of the
merged DeclContexts as well as the (now-primary) DeclContext. This
supports the common case where two different modules put something
into the same namespace.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147778 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 56e2d085e3..ffd768a94d 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -369,6 +369,9 @@ void ASTDeclReader::VisitDecl(Decl *D) { // Determine whether this declaration is part of a (sub)module. If so, it // may not yet be visible. if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) { + // Store the owning submodule ID in the declaration. + D->setOwningModuleID(SubmoduleID); + // Module-private declarations are never visible, so there is no work to do. if (!D->isModulePrivate()) { if (Module *Owner = Reader.getSubmodule(SubmoduleID)) { @@ -972,7 +975,8 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { D->setInline(Record[Idx++]); D->LocStart = ReadSourceLocation(Record, Idx); D->RBraceLoc = ReadSourceLocation(Record, Idx); - + mergeRedeclarable(D, Redecl); + if (Redecl.getFirstID() == ThisDeclID) { // FIXME: If there's already an anonymous namespace, do we merge it with // this one? Or do we, when loading modules, just forget about anonymous @@ -1232,7 +1236,7 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { RedeclKind Kind = (RedeclKind)Record[Idx++]; // Determine the first declaration ID. - DeclID FirstDeclID; + DeclID FirstDeclID = 0; switch (Kind) { case FirstDeclaration: { FirstDeclID = ThisDeclID; @@ -1489,7 +1493,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { enum RedeclKind { FirstDeclaration = 0, FirstInFile, PointsToPrevious }; RedeclKind Kind = (RedeclKind)Record[Idx++]; - DeclID FirstDeclID; + DeclID FirstDeclID = 0; switch (Kind) { case FirstDeclaration: FirstDeclID = ThisDeclID; @@ -1545,6 +1549,13 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(ExistingCanon); + // When we merge a namespace, update its pointer to the first namespace. + if (NamespaceDecl *Namespace + = dyn_cast<NamespaceDecl>(static_cast<T*>(D))) { + Namespace->AnonOrFirstNamespaceAndInline.setPointer( + static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon))); + } + // Don't introduce DCanon into the set of pending declaration chains. Redecl.suppress(); @@ -1719,6 +1730,12 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType()); } + // Namespaces with the same name and inlinedness match. + if (NamespaceDecl *NamespaceX = dyn_cast<NamespaceDecl>(X)) { + NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y); + return NamespaceX->isInline() == NamespaceY->isInline(); + } + // FIXME: Many other cases to implement. return false; } |