aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-09 17:30:44 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-09 17:30:44 +0000
commitc6c8e0ec96bb64f1b9f543d7c8317c6090f80a30 (patch)
tree39aea2b30aebc4a42f967293a8e28181ab8fc20e /lib/Serialization/ASTReaderDecl.cpp
parentc02d62f0b82c144f7db2a71c3b4565de8c6163e5 (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.cpp23
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;
}