aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-22 21:40:42 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-22 21:40:42 +0000
commitc3cfd2ab3338d47861ece597212f21b972ebe727 (patch)
tree836c68f3c7a01079a4e278b86a9a8c1d6421dbb0 /lib/Serialization/ASTReaderDecl.cpp
parente89fd1b30ae0c9f396b183f338d563757c26d3a8 (diff)
Serialize the AST reader's mapping from canonical declarations to the
set of (previously-canonical) declaration IDs to the module file, so that future AST reader instances that load the module know which declarations are merged. This is important in the fairly tricky case where a declaration of an entity, e.g., @class X; occurs before the import of a module that also declares that entity. We merge the declarations, and record the fact that the declaration of X loaded from the module was merged into the (now canonical) declaration of X that we parsed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147181 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 2c8e6ea466..cb816632bd 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -676,9 +676,14 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
}
// If this declaration was the canonical declaration, make a note of
- // that.
- if (IDCanon == ID)
- Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID());
+ // that. We accept the linear algorithm here because the number of
+ // unique canonical declarations of an entity should always be tiny.
+ if (IDCanon == ID) {
+ SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
+ if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
+ == Merged.end())
+ Merged.push_back(Redecl.getFirstID());
+ }
}
}
}
@@ -1725,6 +1730,29 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
}
}
+ASTReader::MergedDeclsMap::iterator
+ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) {
+ // If we don't have any stored merged declarations, just look in the
+ // merged declarations set.
+ StoredMergedDeclsMap::iterator StoredPos = StoredMergedDecls.find(CanonID);
+ if (StoredPos == StoredMergedDecls.end())
+ return MergedDecls.find(Canon);
+
+ // Append the stored merged declarations to the merged declarations set.
+ MergedDeclsMap::iterator Pos = MergedDecls.find(Canon);
+ if (Pos == MergedDecls.end())
+ Pos = MergedDecls.insert(std::make_pair(Canon,
+ SmallVector<DeclID, 2>())).first;
+ Pos->second.append(StoredPos->second.begin(), StoredPos->second.end());
+ StoredMergedDecls.erase(StoredPos);
+
+ // Sort and uniquify the set of merged declarations.
+ llvm::array_pod_sort(Pos->second.begin(), Pos->second.end());
+ Pos->second.erase(std::unique(Pos->second.begin(), Pos->second.end()),
+ Pos->second.end());
+ return Pos;
+}
+
void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) {
Decl *previous = GetDecl(ID);
ASTDeclReader::attachPreviousDecl(D, previous);
@@ -2186,7 +2214,7 @@ static Decl *getMostRecentDecl(Decl *D) {
void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
Decl *D = GetDecl(ID);
Decl *CanonDecl = D->getCanonicalDecl();
-
+
// Determine the set of declaration IDs we'll be searching for.
llvm::SmallVector<DeclID, 1> SearchDecls;
GlobalDeclID CanonID = 0;
@@ -2194,7 +2222,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
SearchDecls.push_back(ID); // Always first.
CanonID = ID;
}
- MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl);
+ MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID);
if (MergedPos != MergedDecls.end())
SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());