diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp | 437 |
1 files changed, 152 insertions, 285 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index 1a0c5b5..8fb110e 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" #include "llvm/Support/SaveAndRestore.h" + using namespace clang; using namespace clang::serialization; @@ -120,45 +121,20 @@ namespace clang { static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, unsigned Index, NamedDecl *D); - /// \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. + /// Results from loading a RedeclarableDecl. class RedeclarableResult { - ASTReader &Reader; GlobalDeclID FirstID; Decl *MergeWith; - mutable bool Owning; bool IsKeyDecl; - Decl::Kind DeclKind; - - void operator=(RedeclarableResult &) = delete; public: - RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID, - Decl *MergeWith, Decl::Kind DeclKind, - bool IsKeyDecl) - : Reader(Reader), FirstID(FirstID), MergeWith(MergeWith), - Owning(true), IsKeyDecl(IsKeyDecl), DeclKind(DeclKind) {} - - RedeclarableResult(RedeclarableResult &&Other) - : Reader(Other.Reader), FirstID(Other.FirstID), - MergeWith(Other.MergeWith), Owning(Other.Owning), - IsKeyDecl(Other.IsKeyDecl), DeclKind(Other.DeclKind) { - Other.Owning = false; - } - - ~RedeclarableResult() { - if (FirstID && Owning && isRedeclarableDeclKind(DeclKind)) { - auto Canon = Reader.GetDecl(FirstID)->getCanonicalDecl(); - if (Reader.PendingDeclChainsKnown.insert(Canon).second) - Reader.PendingDeclChains.push_back(Canon); - } - } + RedeclarableResult(GlobalDeclID FirstID, Decl *MergeWith, bool IsKeyDecl) + : FirstID(FirstID), MergeWith(MergeWith), IsKeyDecl(IsKeyDecl) {} /// \brief Retrieve the first ID. GlobalDeclID getFirstID() const { return FirstID; } - /// \brief Is this declaration the key declaration? + /// \brief Is this declaration a key declaration? bool isKeyDecl() const { return IsKeyDecl; } /// \brief Get a known declaration that this should be merged with, if @@ -185,7 +161,7 @@ namespace clang { public: FindExistingResult(ASTReader &Reader) : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false), - AnonymousDeclNumber(0), TypedefNameForLinkage(0) {} + AnonymousDeclNumber(0), TypedefNameForLinkage(nullptr) {} FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing, unsigned AnonymousDeclNumber, @@ -317,6 +293,7 @@ namespace clang { DeclID VisitTemplateDecl(TemplateDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); + void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D); void VisitVarTemplateDecl(VarTemplateDecl *D); void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); @@ -395,7 +372,7 @@ namespace clang { } } }; -} +} // end namespace clang namespace { /// Iterator over the redeclarations of a declaration that have already @@ -431,12 +408,12 @@ public: return A.Current != B.Current; } }; -} +} // end anonymous namespace + template<typename DeclT> llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) { - return llvm::iterator_range<MergedRedeclIterator<DeclT>>( - MergedRedeclIterator<DeclT>(D), - MergedRedeclIterator<DeclT>()); + return llvm::make_range(MergedRedeclIterator<DeclT>(D), + MergedRedeclIterator<DeclT>()); } uint64_t ASTDeclReader::GetCurrentCursorOffset() { @@ -465,8 +442,8 @@ void ASTDeclReader::Visit(Decl *D) { // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. if (NamedDeclForTagDecl) - cast<TagDecl>(D)->NamedDeclOrQualifier = - cast<NamedDecl>(Reader.GetDecl(NamedDeclForTagDecl)); + cast<TagDecl>(D)->TypedefNameDeclOrQualifier = + cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl)); } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { // if we have a fully initialized TypeDecl, we can safely read its type now. ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull(); @@ -499,6 +476,8 @@ void ASTDeclReader::VisitDecl(Decl *D) { // placeholder. GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); + if (!LexicalDCIDForTemplateParmDecl) + LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; Reader.addPendingDeclContextInfo(D, SemaDCIDForTemplateParmDecl, LexicalDCIDForTemplateParmDecl); @@ -506,6 +485,8 @@ void ASTDeclReader::VisitDecl(Decl *D) { } else { DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx); DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx); + if (!LexicalDC) + LexicalDC = SemaDC; DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC); // Avoid calling setLexicalDeclContext() directly because it uses // Decl::getASTContext() internally which is unsafe during derialization. @@ -619,16 +600,13 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { case 1: { // ExtInfo TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo(); ReadQualifierInfo(*Info, Record, Idx); - TD->NamedDeclOrQualifier = Info; + TD->TypedefNameDeclOrQualifier = Info; break; } case 2: // TypedefNameForAnonDecl NamedDeclForTagDecl = ReadDeclID(Record, Idx); TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx); break; - case 3: // DeclaratorForAnonDecl - NamedDeclForTagDecl = ReadDeclID(Record, Idx); - break; default: llvm_unreachable("unexpected tag info kind"); } @@ -771,8 +749,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // Template arguments. SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); - + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); + // Template args as written. SmallVector<TemplateArgumentLoc, 8> TemplArgLocs; SourceLocation LAngleLoc, RAngleLoc; @@ -909,6 +888,7 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { VisitTypedefNameDecl(D); + D->Variance = Record[Idx++]; D->Index = Record[Idx++]; D->VarianceLoc = ReadSourceLocation(Record, Idx); @@ -1121,7 +1101,6 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { D->IvarInitializers = Reader.ReadCXXCtorInitializersRef(F, Record, Idx); } - void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { VisitDecl(D); D->setAtLoc(ReadSourceLocation(Record, Idx)); @@ -1168,6 +1147,8 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { for (unsigned I = 0; I != FD->ChainingSize; ++I) FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx); + + mergeMergeable(FD); } ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { @@ -1208,8 +1189,9 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { }; switch ((VarKind)Record[Idx++]) { case VarNotTemplate: - // Only true variables (not parameters or implicit parameters) can be merged - if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam && + // Only true variables (not parameters or implicit parameters) can be + // merged; the other kinds are not really redeclarable at all. + if (!isa<ParmVarDecl>(VD) && !isa<ImplicitParamDecl>(VD) && !isa<VarTemplateSpecializationDecl>(VD)) mergeRedeclarable(VD, Redecl); break; @@ -1290,8 +1272,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr)); } - BD->setCaptures(Reader.getContext(), captures.begin(), - captures.end(), capturesCXXThis); + BD->setCaptures(Reader.getContext(), captures, capturesCXXThis); } void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) { @@ -1319,7 +1300,6 @@ void ASTDeclReader::VisitLabelDecl(LabelDecl *D) { D->setLocStart(ReadSourceLocation(Record, Idx)); } - void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); VisitNamedDecl(D); @@ -1506,21 +1486,14 @@ void ASTDeclReader::MergeDefinitionData( auto &DD = *D->DefinitionData.getNotUpdated(); if (DD.Definition != MergeDD.Definition) { - // If the new definition has new special members, let the name lookup - // code know that it needs to look in the new definition too. - // - // FIXME: We only need to do this if the merged definition declares members - // that this definition did not declare, or if it defines members that this - // definition did not define. - Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition); - DD.Definition->setHasExternalVisibleStorage(); - // Track that we merged the definitions. Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition, DD.Definition)); Reader.PendingDefinitions.erase(MergeDD.Definition); MergeDD.Definition->IsCompleteDefinition = false; mergeDefinitionVisibility(DD.Definition, MergeDD.Definition); + assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() && + "already loaded pending lookups for merged definition"); } auto PFDI = Reader.PendingFakeDefinitionData.find(&DD); @@ -1758,7 +1731,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) { VisitDecl(D); D->ImportedAndComplete.setPointer(readModule(Record, Idx)); D->ImportedAndComplete.setInt(Record[Idx++]); - SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1); + SourceLocation *StoredLocs = D->getTrailingObjects<SourceLocation>(); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = ReadSourceLocation(Record, Idx); ++Idx; // The number of stored source locations. @@ -1776,7 +1749,8 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { else D->Friend = GetTypeSourceInfo(Record, Idx); for (unsigned i = 0; i != D->NumTPLists; ++i) - D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx); + D->getTrailingObjects<TemplateParameterList *>()[i] = + Reader.ReadTemplateParameterList(F, Record, Idx); D->NextFriend = ReadDeclID(Record, Idx); D->UnsupportedFriend = (Record[Idx++] != 0); D->FriendLoc = ReadSourceLocation(Record, Idx); @@ -1887,6 +1861,10 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { } } +void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) { + llvm_unreachable("BuiltinTemplates are not serialized"); +} + /// TODO: Unify with ClassTemplateDecl version? /// May require unifying ClassTemplateDecl and /// VarTemplateDecl beyond TemplateDecl... @@ -1933,7 +1911,8 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( } SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); @@ -2060,7 +2039,8 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( } SmallVector<TemplateArgument, 8> TemplArgs; - Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx, + /*Canonicalize*/ true); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); @@ -2070,6 +2050,7 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( if (writtenAsCanonicalDecl) { VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(Record, Idx); if (D->isCanonicalDecl()) { // It's kept in the folding set. + // FIXME: If it's already present, merge it. if (VarTemplatePartialSpecializationDecl *Partial = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { CanonPattern->getCommonPtr()->PartialSpecializations @@ -2118,10 +2099,11 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); if (D->isExpandedParameterPack()) { - void **Data = reinterpret_cast<void **>(D + 1); + auto TypesAndInfos = + D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { - Data[2*I] = Reader.readType(F, Record, Idx).getAsOpaquePtr(); - Data[2*I + 1] = GetTypeSourceInfo(Record, Idx); + new (&TypesAndInfos[I].first) QualType(Reader.readType(F, Record, Idx)); + TypesAndInfos[I].second = GetTypeSourceInfo(Record, Idx); } } else { // Rest of NonTypeTemplateParmDecl. @@ -2137,7 +2119,8 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); if (D->isExpandedParameterPack()) { - void **Data = reinterpret_cast<void **>(D + 1); + TemplateParameterList **Data = + D->getTrailingObjects<TemplateParameterList *>(); for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); I != N; ++I) Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx); @@ -2178,23 +2161,37 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { DeclID FirstDeclID = ReadDeclID(Record, Idx); Decl *MergeWith = nullptr; + bool IsKeyDecl = ThisDeclID == FirstDeclID; + bool IsFirstLocalDecl = false; + + uint64_t RedeclOffset = 0; // 0 indicates that this declaration was the only declaration of its entity, // and is used for space optimization. if (FirstDeclID == 0) { FirstDeclID = ThisDeclID; IsKeyDecl = true; + IsFirstLocalDecl = true; } else if (unsigned N = Record[Idx++]) { - IsKeyDecl = false; + // This declaration was the first local declaration, but may have imported + // other declarations. + IsKeyDecl = N == 1; + IsFirstLocalDecl = true; // 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) + for (unsigned I = 0; I != N - 1; ++I) MergeWith = ReadDecl(Record, Idx/*, MergeWith*/); + + RedeclOffset = Record[Idx++]; + } else { + // This declaration was not the first local declaration. Read the first + // local declaration now, to trigger the import of other redeclarations. + (void)ReadDecl(Record, Idx); } T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); @@ -2206,14 +2203,17 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl); D->First = FirstDecl->getCanonicalDecl(); } - - // Note that this declaration has been deserialized. - Reader.RedeclsDeserialized.insert(static_cast<T *>(D)); - - // The result structure takes care to note that we need to load the - // other declaration chains for this ID. - return RedeclarableResult(Reader, FirstDeclID, MergeWith, - static_cast<T *>(D)->getKind(), IsKeyDecl); + + T *DAsT = static_cast<T*>(D); + + // Note that we need to load local redeclarations of this decl and build a + // decl chain for them. This must happen *after* we perform the preloading + // above; this ensures that the redeclaration chain is built in the correct + // order. + if (IsFirstLocalDecl) + Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset)); + + return RedeclarableResult(FirstDeclID, MergeWith, IsKeyDecl); } /// \brief Attempts to merge the given declaration (D) with another declaration @@ -2255,9 +2255,8 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, DeclID DsID, bool IsKeyDecl) { auto *DPattern = D->getTemplatedDecl(); auto *ExistingPattern = Existing->getTemplatedDecl(); - RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(), - /*MergeWith*/ExistingPattern, DPattern->getKind(), - IsKeyDecl); + RedeclarableResult Result(DPattern->getCanonicalDecl()->getGlobalID(), + /*MergeWith*/ ExistingPattern, IsKeyDecl); if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) { // Merge with any existing definition. @@ -2323,11 +2322,8 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing, TemplatePatternID, Redecl.isKeyDecl()); // If this declaration is a key declaration, make a note of that. - if (Redecl.isKeyDecl()) { + if (Redecl.isKeyDecl()) Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID()); - if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second) - Reader.PendingDeclChains.push_back(ExistingCanon); - } } } @@ -2626,6 +2622,13 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); } + // Indirect fields with the same target field match. + if (auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { + auto *IFDY = cast<IndirectFieldDecl>(Y); + return IFDX->getAnonField()->getCanonicalDecl() == + IFDY->getAnonField()->getCanonicalDecl(); + } + // Enumerators with the same name match. if (isa<EnumConstantDecl>(X)) // FIXME: Also check the value is odr-equivalent. @@ -2749,12 +2752,12 @@ static NamedDecl *getDeclForMerging(NamedDecl *Found, // declaration, then we want that inner declaration. Declarations from // AST files are handled via ImportedTypedefNamesForLinkage. if (Found->isFromASTFile()) - return 0; + return nullptr; if (auto *TND = dyn_cast<TypedefNameDecl>(Found)) return TND->getAnonDeclWithTypedefName(); - return 0; + return nullptr; } NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader, @@ -2924,6 +2927,7 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, D->RedeclLink.setPrevious(cast<DeclT>(Previous)); D->First = cast<DeclT>(Previous)->First; } + namespace clang { template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, @@ -2969,7 +2973,8 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, std::make_pair(Canon, IsUnresolved ? PrevFD : FD)); } } -} +} // end namespace clang + void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) { llvm_unreachable("attachPreviousDecl on non-redeclarable declaration"); } @@ -3319,37 +3324,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. if (DeclContext *DC = dyn_cast<DeclContext>(D)) { - // FIXME: This should really be - // DeclContext *LookupDC = DC->getPrimaryContext(); - // but that can walk the redeclaration chain, which might not work yet. - DeclContext *LookupDC = DC; - if (isa<NamespaceDecl>(DC)) - LookupDC = DC->getPrimaryContext(); std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC); - if (Offsets.first || Offsets.second) { - if (Offsets.first != 0) - DC->setHasExternalLexicalStorage(true); - if (Offsets.second != 0) - LookupDC->setHasExternalVisibleStorage(true); - if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets, - Loc.F->DeclContextInfos[DC])) - return nullptr; - } - - // Now add the pending visible updates for this decl context, if it has any. - DeclContextVisibleUpdatesPending::iterator I = - PendingVisibleUpdates.find(ID); - if (I != PendingVisibleUpdates.end()) { - // There are updates. This means the context has external visible - // storage, even if the original stored version didn't. - LookupDC->setHasExternalVisibleStorage(true); - for (const auto &Update : I->second) { - DeclContextInfo &Info = Update.second->DeclContextInfos[DC]; - delete Info.NameLookupTableData; - Info.NameLookupTableData = Update.first; - } - PendingVisibleUpdates.erase(I); - } + if (Offsets.first && + ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC)) + return nullptr; + if (Offsets.second && + ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID)) + return nullptr; } assert(Idx == Record.size()); @@ -3372,17 +3353,32 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { } void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { + // Load the pending visible updates for this decl context, if it has any. + auto I = PendingVisibleUpdates.find(ID); + if (I != PendingVisibleUpdates.end()) { + auto VisibleUpdates = std::move(I->second); + PendingVisibleUpdates.erase(I); + + auto *DC = cast<DeclContext>(D)->getPrimaryContext(); + for (const PendingVisibleUpdate &Update : VisibleUpdates) + Lookups[DC].Table.add( + Update.Mod, Update.Data, + reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod)); + DC->setHasExternalVisibleStorage(true); + } + // The declaration may have been modified by files later in the chain. // If this is the case, read the record containing the updates from each file // and pass it to ASTDeclReader to make the modifications. DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); if (UpdI != DeclUpdateOffsets.end()) { - FileOffsetsTy &UpdateOffsets = UpdI->second; + auto UpdateOffsets = std::move(UpdI->second); + DeclUpdateOffsets.erase(UpdI); + bool WasInteresting = isConsumerInterestedIn(D, false); - for (FileOffsetsTy::iterator - I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) { - ModuleFile *F = I->first; - uint64_t Offset = I->second; + for (auto &FileAndOffset : UpdateOffsets) { + ModuleFile *F = FileAndOffset.first; + uint64_t Offset = FileAndOffset.second; llvm::BitstreamCursor &Cursor = F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(Offset); @@ -3407,154 +3403,42 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { } } -namespace { - /// \brief Module visitor class that finds all of the redeclarations of a - /// redeclarable declaration. - class RedeclChainVisitor { - ASTReader &Reader; - SmallVectorImpl<DeclID> &SearchDecls; - llvm::SmallPtrSetImpl<Decl *> &Deserialized; - GlobalDeclID CanonID; - SmallVector<Decl *, 4> Chain; - - public: - RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls, - llvm::SmallPtrSetImpl<Decl *> &Deserialized, - GlobalDeclID CanonID) - : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized), - CanonID(CanonID) { - // Ensure that the canonical ID goes at the start of the chain. - addToChain(Reader.GetDecl(CanonID)); - } - - static ModuleManager::DFSPreorderControl - visitPreorder(ModuleFile &M, void *UserData) { - return static_cast<RedeclChainVisitor *>(UserData)->visitPreorder(M); - } - - static bool visitPostorder(ModuleFile &M, void *UserData) { - return static_cast<RedeclChainVisitor *>(UserData)->visitPostorder(M); - } - - void addToChain(Decl *D) { - if (!D) - return; - - if (Deserialized.erase(D)) - Chain.push_back(D); - } - - void searchForID(ModuleFile &M, GlobalDeclID GlobalID) { - // Map global ID of the first declaration down to the local ID - // used in this module file. - DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID); - if (!ID) - return; - - // If the search decl was from this module, add it to the chain before any - // of its redeclarations in this module or users of it, and after any from - // imported modules. - if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M)) - addToChain(Reader.GetDecl(GlobalID)); - - // Perform a binary search to find the local redeclarations for this - // declaration (if any). - const LocalRedeclarationsInfo Compare = { ID, 0 }; - const LocalRedeclarationsInfo *Result - = std::lower_bound(M.RedeclarationsMap, - M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, - Compare); - if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap || - Result->FirstID != ID) - return; - - // Dig out all of the redeclarations. - unsigned Offset = Result->Offset; - unsigned N = M.RedeclarationChains[Offset]; - M.RedeclarationChains[Offset++] = 0; // Don't try to deserialize again - for (unsigned I = 0; I != N; ++I) - addToChain(Reader.GetLocalDecl(M, M.RedeclarationChains[Offset++])); - } - - bool needsToVisitImports(ModuleFile &M, GlobalDeclID GlobalID) { - DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID); - if (!ID) - return false; - - const LocalRedeclarationsInfo Compare = {ID, 0}; - const LocalRedeclarationsInfo *Result = std::lower_bound( - M.RedeclarationsMap, - M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare); - if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap || - Result->FirstID != ID) { - return true; - } - unsigned Offset = Result->Offset; - unsigned N = M.RedeclarationChains[Offset]; - // We don't need to visit a module or any of its imports if we've already - // deserialized the redecls from this module. - return N != 0; - } +void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { + // Attach FirstLocal to the end of the decl chain. + Decl *CanonDecl = FirstLocal->getCanonicalDecl(); + if (FirstLocal != CanonDecl) { + Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); + ASTDeclReader::attachPreviousDecl( + *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl, + CanonDecl); + } - ModuleManager::DFSPreorderControl visitPreorder(ModuleFile &M) { - for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) { - if (needsToVisitImports(M, SearchDecls[I])) - return ModuleManager::Continue; - } - return ModuleManager::SkipImports; - } + if (!LocalOffset) { + ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal); + return; + } - bool visitPostorder(ModuleFile &M) { - // Visit each of the declarations. - for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) - searchForID(M, SearchDecls[I]); - return false; - } - - ArrayRef<Decl *> getChain() const { - return Chain; - } - }; -} + // Load the list of other redeclarations from this module file. + ModuleFile *M = getOwningModuleFile(FirstLocal); + assert(M && "imported decl from no module file"); -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; + llvm::BitstreamCursor &Cursor = M->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(LocalOffset); - // Determine the set of declaration IDs we'll be searching for. - SmallVector<DeclID, 16> SearchDecls; - GlobalDeclID CanonID = CanonDecl->getGlobalID(); - if (CanonID) - SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first. - KeyDeclsMap::iterator KeyPos = KeyDecls.find(CanonDecl); - if (KeyPos != KeyDecls.end()) - SearchDecls.append(KeyPos->second.begin(), KeyPos->second.end()); - - // Build up the list of redeclarations. - RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID); - ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visitPreorder, - &RedeclChainVisitor::visitPostorder, &Visitor); - - // Retrieve the chains. - ArrayRef<Decl *> Chain = Visitor.getChain(); - if (Chain.empty() || (Chain.size() == 1 && Chain[0] == CanonDecl)) - return; + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.readRecord(Code, Record); + (void)RecCode; + assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!"); - // Hook up the chains. - // - // FIXME: We have three different dispatches on decl kind here; maybe + // FIXME: We have several different dispatches on decl kind here; maybe // we should instead generate one loop per kind and dispatch up-front? - Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); - if (!MostRecent) - MostRecent = CanonDecl; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Chain[I] == CanonDecl) - continue; - - ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent, CanonDecl); - MostRecent = Chain[I]; + Decl *MostRecent = FirstLocal; + for (unsigned I = 0, N = Record.size(); I != N; ++I) { + auto *D = GetLocalDecl(*M, Record[N - I - 1]); + ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl); + MostRecent = D; } ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent); } @@ -3630,11 +3514,7 @@ namespace { } } - static bool visit(ModuleFile &M, void *UserData) { - return static_cast<ObjCCategoriesVisitor *>(UserData)->visit(M); - } - - bool visit(ModuleFile &M) { + bool operator()(ModuleFile &M) { // If we've loaded all of the category information we care about from // this module file, we're done. if (M.Generation <= PreviousGeneration) @@ -3672,14 +3552,14 @@ namespace { return true; } }; -} +} // end anonymous namespace void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration) { ObjCCategoriesVisitor Visitor(*this, ID, D, CategoriesDeserialized, PreviousGeneration); - ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor); + ModuleMgr.visit(Visitor); } template<typename DeclT, typename Fn> @@ -3716,17 +3596,6 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, // FIXME: We should call addHiddenDecl instead, to add the member // to its DeclContext. RD->addedMember(MD); - - // If we've added a new special member to a class definition that is not - // the canonical definition, then we need special member lookups in the - // canonical definition to also look into our class. - auto *DD = RD->DefinitionData.getNotUpdated(); - if (DD && DD->Definition != RD) { - auto &Merged = Reader.MergedLookups[DD->Definition]; - // FIXME: Avoid the linear-time scan here. - if (std::find(Merged.begin(), Merged.end(), RD) == Merged.end()) - Merged.push_back(RD); - } break; } @@ -3798,10 +3667,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, // Visible update is handled separately. uint64_t LexicalOffset = Record[Idx++]; if (!HadRealDefinition && LexicalOffset) { - RD->setHasExternalLexicalStorage(true); - Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor, - std::make_pair(LexicalOffset, 0), - ModuleFile.DeclContextInfos[RD]); + Reader.ReadLexicalDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor, + LexicalOffset, RD); Reader.PendingFakeDefinitionData.erase(OldDD); } |