diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-12-22 21:40:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-12-22 21:40:42 +0000 |
commit | c3cfd2ab3338d47861ece597212f21b972ebe727 (patch) | |
tree | 836c68f3c7a01079a4e278b86a9a8c1d6421dbb0 /lib/Serialization/ASTReaderDecl.cpp | |
parent | e89fd1b30ae0c9f396b183f338d563757c26d3a8 (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.cpp | 38 |
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()); |