summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp100
1 files changed, 29 insertions, 71 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 375bdfb392e..5aeb3d1e517 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -123,9 +123,6 @@ namespace clang {
/// \brief RAII class used to capture the first ID within a redeclaration
/// chain and to introduce it into the list of pending redeclaration chains
/// on destruction.
- ///
- /// The caller can choose not to introduce this ID into the list of pending
- /// redeclaration chains by calling \c suppress().
class RedeclarableResult {
ASTReader &Reader;
GlobalDeclID FirstID;
@@ -149,9 +146,11 @@ namespace clang {
}
~RedeclarableResult() {
- if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) &&
- Reader.PendingDeclChainsKnown.insert(FirstID).second)
- Reader.PendingDeclChains.push_back(FirstID);
+ if (FirstID && Owning && isRedeclarableDeclKind(DeclKind)) {
+ auto Canon = Reader.GetDecl(FirstID)->getCanonicalDecl();
+ if (Reader.PendingDeclChainsKnown.insert(Canon).second)
+ Reader.PendingDeclChains.push_back(Canon);
+ }
}
/// \brief Retrieve the first ID.
@@ -160,12 +159,6 @@ namespace clang {
/// \brief Get a known declaration that this should be merged with, if
/// any.
Decl *getKnownMergeTarget() const { return MergeWith; }
-
- /// \brief Do not introduce this declaration ID into the set of pending
- /// declaration chains.
- void suppress() {
- Owning = false;
- }
};
/// \brief Class used to capture the result of searching for an existing
@@ -2076,12 +2069,14 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// and is used for space optimization.
if (FirstDeclID == 0)
FirstDeclID = ThisDeclID;
- else if (Record[Idx++]) {
- // We need to merge with FirstDeclID. Read it now to ensure that it is
- // before us in the redecl chain, then forget we saw it so that we will
- // merge with it.
- MergeWith = Reader.GetDecl(FirstDeclID);
- FirstDeclID = ThisDeclID;
+ else if (unsigned N = Record[Idx++]) {
+ // We have some declarations that must be before us in our redeclaration
+ // chain. Read them now, and remember that we ought to merge with one of
+ // them.
+ // FIXME: Provide a known merge target to the second and subsequent such
+ // declaration.
+ for (unsigned I = 0; I != N; ++I)
+ MergeWith = ReadDecl(Record, Idx/*, MergeWith*/);
}
T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
@@ -2109,17 +2104,6 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
RedeclarableResult &Redecl,
DeclID TemplatePatternID) {
T *D = static_cast<T*>(DBase);
- T *DCanon = D->getCanonicalDecl();
- if (D != DCanon &&
- // IDs < NUM_PREDEF_DECL_IDS are not loaded from an AST file.
- Redecl.getFirstID() >= NUM_PREDEF_DECL_IDS &&
- (!Reader.getContext().getLangOpts().Modules ||
- Reader.getOwningModuleFile(DCanon) == Reader.getOwningModuleFile(D))) {
- // All redeclarations between this declaration and its originally-canonical
- // declaration get pulled in when we load DCanon; we don't need to
- // perform any more merging now.
- Redecl.suppress();
- }
// If modules are not available, there is no reason to perform this merge.
if (!Reader.getContext().getLangOpts().Modules)
@@ -2215,10 +2199,9 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
// that. We accept the linear algorithm here because the number of
// unique canonical declarations of an entity should always be tiny.
if (DCanon == D) {
- SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
- if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
- == Merged.end())
- Merged.push_back(Redecl.getFirstID());
+ Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID());
+ if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second)
+ Reader.PendingDeclChains.push_back(ExistingCanon);
}
}
}
@@ -2697,8 +2680,6 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
// unmergeable contexts.
FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
AnonymousDeclNumber, TypedefNameForLinkage);
- // FIXME: We may still need to pull in the redeclaration chain; there can
- // be redeclarations via 'decltype'.
Result.suppress();
return Result;
}
@@ -2930,29 +2911,6 @@ void ASTReader::markIncompleteDeclChain(Decl *D) {
}
}
-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;
-}
-
/// \brief Read the declaration at the given offset from the AST file.
Decl *ASTReader::ReadDeclRecord(DeclID ID) {
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
@@ -3362,25 +3320,25 @@ namespace {
};
}
-void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
- Decl *D = GetDecl(ID);
- Decl *CanonDecl = D->getCanonicalDecl();
-
+void ASTReader::loadPendingDeclChain(Decl *CanonDecl) {
+ // The decl might have been merged into something else after being added to
+ // our list. If it was, just skip it.
+ if (!CanonDecl->isCanonicalDecl())
+ return;
+
// Determine the set of declaration IDs we'll be searching for.
- SmallVector<DeclID, 1> SearchDecls;
- GlobalDeclID CanonID = 0;
- if (D == CanonDecl) {
- SearchDecls.push_back(ID); // Always first.
- CanonID = ID;
- }
- MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID);
+ SmallVector<DeclID, 16> SearchDecls;
+ GlobalDeclID CanonID = CanonDecl->getGlobalID();
+ if (CanonID)
+ SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first.
+ MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl);
if (MergedPos != MergedDecls.end())
SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
-
+
// Build up the list of redeclarations.
RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visit, &Visitor);
-
+
// Retrieve the chains.
ArrayRef<Decl *> Chain = Visitor.getChain();
if (Chain.empty())
OpenPOWER on IntegriCloud