diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 100 |
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()) |