diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 69 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 74 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Serialization/Module.cpp | 1 |
5 files changed, 62 insertions, 135 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index bcc7e7cf48f..9899eaf6989 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3100,22 +3100,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case LOCAL_REDECLARATIONS: { - F.RedeclarationChains.swap(Record); - break; - } - - case LOCAL_REDECLARATIONS_MAP: { - if (F.LocalNumRedeclarationsInMap != 0) { - Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file"); - return Failure; - } - - F.LocalNumRedeclarationsInMap = Record[0]; - F.RedeclarationsMap = (const LocalRedeclarationsInfo *)Blob.data(); - break; - } - case MACRO_OFFSET: { if (F.LocalNumMacros != 0) { Error("duplicate MACRO_OFFSET record in AST file"); @@ -8124,7 +8108,7 @@ void ASTReader::finishPendingActions() { // Load pending declaration chains. for (unsigned I = 0; I != PendingDeclChains.size(); ++I) - loadPendingDeclChain(PendingDeclChains[I]); + loadPendingDeclChain(PendingDeclChains[I].first, PendingDeclChains[I].second); PendingDeclChains.clear(); // Make the most recent of the top-level declarations visible. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index f4f39a8506b..00785aa1d05 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2156,6 +2156,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { 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) { @@ -2175,6 +2177,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { // declaration. 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. @@ -2198,7 +2202,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { // above; this ensures that the redeclaration chain is built in the correct // order. if (IsFirstLocalDecl) - Reader.PendingDeclChains.push_back(DAsT); + Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset)); return RedeclarableResult(FirstDeclID, MergeWith, IsKeyDecl); } @@ -3393,43 +3397,40 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { } } -void ASTReader::loadPendingDeclChain(Decl *FirstLocal) { - ModuleFile &M = *getOwningModuleFile(FirstLocal); - DeclID LocalID = - mapGlobalIDToModuleFileGlobalID(M, FirstLocal->getGlobalID()); - assert(LocalID && "looking for redecl chain in wrong module file"); - - // Perform a binary search to find the local redeclarations for this - // declaration (if any). - // FIXME: Just store an offset with the first declaration. - const LocalRedeclarationsInfo Compare = {LocalID, 0}; - const LocalRedeclarationsInfo *Result = std::lower_bound( - M.RedeclarationsMap, - M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare); +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); + } - // Pull out the list of redeclarations. - SmallVector<Decl*, 4> Chain; - if (Result != M.RedeclarationsMap + M.LocalNumRedeclarationsInMap && - Result->FirstID == LocalID) { - unsigned Offset = Result->Offset; - unsigned N = M.RedeclarationChains[Offset++]; - for (unsigned I = 0; I != N; ++I) - Chain.push_back(GetLocalDecl(M, M.RedeclarationChains[Offset++])); + if (!LocalOffset) { + ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal); + return; } - Chain.push_back(FirstLocal); - // Hook up the chain. - // - // FIXME: We have three different dispatches on decl kind here; maybe + // Load the list of other redeclarations from this module file. + ModuleFile *M = getOwningModuleFile(FirstLocal); + assert(M && "imported decl from no module file"); + + llvm::BitstreamCursor &Cursor = M->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(LocalOffset); + + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.readRecord(Code, Record); + (void)RecCode; + assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!"); + + // FIXME: We have several different dispatches on decl kind here; maybe // we should instead generate one loop per kind and dispatch up-front? - Decl *CanonDecl = FirstLocal->getCanonicalDecl(); - Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); - if (!MostRecent) - MostRecent = CanonDecl; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - auto *D = Chain[N - I - 1]; - if (D == CanonDecl) - continue; + 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; } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index ae326b2068b..d7803d166ee 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -911,7 +911,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(PPD_ENTITIES_OFFSETS); RECORD(REFERENCED_SELECTOR_POOL); RECORD(TU_UPDATE_LEXICAL); - RECORD(LOCAL_REDECLARATIONS_MAP); RECORD(SEMA_DECL_REFS); RECORD(WEAK_UNDECLARED_IDENTIFIERS); RECORD(PENDING_IMPLICIT_INSTANTIATIONS); @@ -933,7 +932,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(OBJC_CATEGORIES_MAP); RECORD(FILE_SORTED_DECLS); RECORD(IMPORTED_MODULES); - RECORD(LOCAL_REDECLARATIONS); RECORD(OBJC_CATEGORIES); RECORD(MACRO_OFFSET); RECORD(LATE_PARSED_TEMPLATE); @@ -997,6 +995,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(TYPE_ATOMIC); RECORD(TYPE_DECAYED); RECORD(TYPE_ADJUSTED); + RECORD(LOCAL_REDECLARATIONS); RECORD(DECL_TYPEDEF); RECORD(DECL_TYPEALIAS); RECORD(DECL_ENUM); @@ -3794,76 +3793,6 @@ void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { Stream.EmitRecord(OPENCL_EXTENSIONS, Record); } -void ASTWriter::WriteRedeclarations() { - RecordData LocalRedeclChains; - SmallVector<serialization::LocalRedeclarationsInfo, 2> LocalRedeclsMap; - - for (unsigned I = 0, N = Redeclarations.size(); I != N; ++I) { - const Decl *FirstLocal = Redeclarations[I]; - assert(!FirstLocal->isFromASTFile() && - (!FirstLocal->getPreviousDecl() || - FirstLocal->getPreviousDecl()->isFromASTFile() || - getDeclID(FirstLocal->getPreviousDecl()) < NUM_PREDEF_DECL_IDS) && - "not the first local declaration"); - assert(getDeclID(FirstLocal) >= NUM_PREDEF_DECL_IDS && - "should not have predefined decl as first decl"); - - unsigned Offset = LocalRedeclChains.size(); - unsigned Size = 0; - LocalRedeclChains.push_back(0); // Placeholder for the size. - - // Collect the set of local redeclarations of this declaration, from newest - // to oldest. - for (const Decl *Prev = FirstLocal->getMostRecentDecl(); Prev != FirstLocal; - Prev = Prev->getPreviousDecl()) { - if (!Prev->isFromASTFile()) { - AddDeclRef(Prev, LocalRedeclChains); - ++Size; - } - } - - // If we only have a single local declaration, there is no point in storing - // a redeclaration chain. - if (LocalRedeclChains.size() == 1) - continue; - - LocalRedeclChains[Offset] = Size; - - // Add the mapping from the first ID from the AST to the set of local - // declarations. - LocalRedeclarationsInfo Info = { getDeclID(FirstLocal), Offset }; - LocalRedeclsMap.push_back(Info); - - assert(N == Redeclarations.size() && - "Deserialized a declaration we shouldn't have"); - } - - if (LocalRedeclChains.empty()) - return; - - // Sort the local redeclarations map by the first declaration ID, - // since the reader will be performing binary searches on this information. - llvm::array_pod_sort(LocalRedeclsMap.begin(), LocalRedeclsMap.end()); - - // Emit the local redeclarations map. - using namespace llvm; - llvm::BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(LOCAL_REDECLARATIONS_MAP)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); - unsigned AbbrevID = Stream.EmitAbbrev(Abbrev); - - RecordData Record; - Record.push_back(LOCAL_REDECLARATIONS_MAP); - Record.push_back(LocalRedeclsMap.size()); - Stream.EmitRecordWithBlob(AbbrevID, Record, - reinterpret_cast<char*>(LocalRedeclsMap.data()), - LocalRedeclsMap.size() * sizeof(LocalRedeclarationsInfo)); - - // Emit the redeclaration chains. - Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedeclChains); -} - void ASTWriter::WriteObjCCategories() { SmallVector<ObjCCategoriesInfo, 2> CategoriesMap; RecordData Categories; @@ -4589,7 +4518,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, } WriteDeclReplacementsBlock(); - WriteRedeclarations(); WriteObjCCategories(); if(!WritingModule) WriteOptimizePragmaOptions(SemaRef); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 712eae186ca..3f8ddf1292e 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1565,8 +1565,6 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { // first local declaration in the chain. const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT); if (DAsT == FirstLocal) { - Writer.Redeclarations.push_back(DAsT); - // Emit a list of all imported first declarations so that we can be sure // that all redeclarations visible to this module are before D in the // redecl chain. @@ -1576,6 +1574,23 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false); // This is the number of imported first declarations + 1. Record[I] = Record.size() - I; + + // Collect the set of local redeclarations of this declaration, from + // newest to oldest. + RecordData LocalRedecls; + for (const Decl *Prev = FirstLocal->getMostRecentDecl(); + Prev != FirstLocal; Prev = Prev->getPreviousDecl()) + if (!Prev->isFromASTFile()) + Writer.AddDeclRef(Prev, LocalRedecls); + + // If we have any redecls, write them now as a separate record preceding + // the declaration itself. + if (LocalRedecls.empty()) + Record.push_back(0); + else { + Record.push_back(Writer.Stream.GetCurrentBitNo()); + Writer.Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedecls); + } } else { Record.push_back(0); Writer.AddDeclRef(FirstLocal, Record); @@ -2114,6 +2129,13 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { VisibleOffset = WriteDeclContextVisibleBlock(Context, DC); } + // Build a record for this declaration + Record.clear(); + W.Code = (serialization::DeclCode)0; + W.AbbrevToUse = 0; + W.Visit(D); + if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); + if (isReplacingADecl) { // We're replacing a decl in a previous file. ReplacedDecls.push_back(ReplacedDeclInfo(ID, Stream.GetCurrentBitNo(), @@ -2130,19 +2152,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { DeclOffsets[Index].setLocation(Loc); DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo(); } - + SourceManager &SM = Context.getSourceManager(); if (Loc.isValid() && SM.isLocalSourceLocation(Loc)) associateDeclWithFile(D, ID); } - // Build and emit a record for this declaration - Record.clear(); - W.Code = (serialization::DeclCode)0; - W.AbbrevToUse = 0; - W.Visit(D); - if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); - if (!W.Code) llvm::report_fatal_error(StringRef("unexpected declaration kind '") + D->getDeclKindName() + "'"); diff --git a/clang/lib/Serialization/Module.cpp b/clang/lib/Serialization/Module.cpp index 3b237d5529c..9111fc40a02 100644 --- a/clang/lib/Serialization/Module.cpp +++ b/clang/lib/Serialization/Module.cpp @@ -40,7 +40,6 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation) LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(nullptr), LocalNumCXXCtorInitializers(0), CXXCtorInitializersOffsets(nullptr), FileSortedDecls(nullptr), NumFileSortedDecls(0), - RedeclarationsMap(nullptr), LocalNumRedeclarationsInMap(0), ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0), LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0) {} |