|
@@ -123,9 +123,6 @@ namespace clang {
|
|
/// \brief RAII class used to capture the first ID within a redeclaration
|
|
/// \brief RAII class used to capture the first ID within a redeclaration
|
|
/// chain and to introduce it into the list of pending redeclaration chains
|
|
/// chain and to introduce it into the list of pending redeclaration chains
|
|
/// on destruction.
|
|
/// on destruction.
|
|
- ///
|
|
|
|
- /// The caller can choose not to introduce this ID into the list of pending
|
|
|
|
- /// redeclaration chains by calling \c suppress().
|
|
|
|
class RedeclarableResult {
|
|
class RedeclarableResult {
|
|
ASTReader &Reader;
|
|
ASTReader &Reader;
|
|
GlobalDeclID FirstID;
|
|
GlobalDeclID FirstID;
|
|
@@ -149,9 +146,11 @@ namespace clang {
|
|
}
|
|
}
|
|
|
|
|
|
~RedeclarableResult() {
|
|
~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.
|
|
/// \brief Retrieve the first ID.
|
|
@@ -160,12 +159,6 @@ namespace clang {
|
|
/// \brief Get a known declaration that this should be merged with, if
|
|
/// \brief Get a known declaration that this should be merged with, if
|
|
/// any.
|
|
/// any.
|
|
Decl *getKnownMergeTarget() const { return MergeWith; }
|
|
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
|
|
/// \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.
|
|
// and is used for space optimization.
|
|
if (FirstDeclID == 0)
|
|
if (FirstDeclID == 0)
|
|
FirstDeclID = ThisDeclID;
|
|
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));
|
|
T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
|
|
@@ -2109,17 +2104,6 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
|
|
RedeclarableResult &Redecl,
|
|
RedeclarableResult &Redecl,
|
|
DeclID TemplatePatternID) {
|
|
DeclID TemplatePatternID) {
|
|
T *D = static_cast<T*>(DBase);
|
|
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 modules are not available, there is no reason to perform this merge.
|
|
if (!Reader.getContext().getLangOpts().Modules)
|
|
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
|
|
// that. We accept the linear algorithm here because the number of
|
|
// unique canonical declarations of an entity should always be tiny.
|
|
// unique canonical declarations of an entity should always be tiny.
|
|
if (DCanon == D) {
|
|
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.
|
|
// unmergeable contexts.
|
|
FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
|
|
FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
|
|
AnonymousDeclNumber, TypedefNameForLinkage);
|
|
AnonymousDeclNumber, TypedefNameForLinkage);
|
|
- // FIXME: We may still need to pull in the redeclaration chain; there can
|
|
|
|
- // be redeclarations via 'decltype'.
|
|
|
|
Result.suppress();
|
|
Result.suppress();
|
|
return Result;
|
|
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.
|
|
/// \brief Read the declaration at the given offset from the AST file.
|
|
Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
|
Decl *ASTReader::ReadDeclRecord(DeclID ID) {
|
|
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
|
|
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.
|
|
// 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())
|
|
if (MergedPos != MergedDecls.end())
|
|
SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
|
|
SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
|
|
-
|
|
|
|
|
|
+
|
|
// Build up the list of redeclarations.
|
|
// Build up the list of redeclarations.
|
|
RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
|
|
RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
|
|
ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visit, &Visitor);
|
|
ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visit, &Visitor);
|
|
-
|
|
|
|
|
|
+
|
|
// Retrieve the chains.
|
|
// Retrieve the chains.
|
|
ArrayRef<Decl *> Chain = Visitor.getChain();
|
|
ArrayRef<Decl *> Chain = Visitor.getChain();
|
|
if (Chain.empty())
|
|
if (Chain.empty())
|