diff options
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 102 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 19 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 5 |
4 files changed, 42 insertions, 91 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index c677ae284c..6591d1295a 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -450,6 +450,10 @@ private: /// That is, the entry I was created with -include-pch I+1. SmallVector<PerFileData*, 2> Chain; + /// \brief A map of global bit offsets to the module that stores entities + /// at those bit offsets. + ContinuousRangeMap<uint64_t, PerFileData*, 4> GlobalBitOffsetsMap; + /// \brief SLocEntries that we're going to preload. SmallVector<int, 64> PreloadSLocEntries; @@ -919,7 +923,8 @@ private: void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(unsigned Index, serialization::DeclID ID); RecordLocation DeclCursorForIndex(unsigned Index, serialization::DeclID ID); - + RecordLocation getLocalBitOffset(uint64_t GlobalOffset); + void PassInterestingDeclsToConsumer(); /// \brief Produce an error diagnostic and return true. diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 0ef94aae3b..e6d16fed3c 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1735,15 +1735,8 @@ void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, PerFileData &F, // Note that this identifier has a macro definition. II->setHasMacroDefinition(true); - // Adjust the offset based on our position in the chain. - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Chain[I] == &F) - break; - - Offset += Chain[I]->SizeInBits; - } - - UnreadMacroRecordOffsets[II] = Offset; + // Adjust the offset to a global offset. + UnreadMacroRecordOffsets[II] = F.GlobalBitOffset + Offset; } void ASTReader::ReadDefinedMacros() { @@ -1807,24 +1800,11 @@ void ASTReader::ReadDefinedMacros() { void ASTReader::LoadMacroDefinition( llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) { assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition"); - PerFileData *F = 0; uint64_t Offset = Pos->second; UnreadMacroRecordOffsets.erase(Pos); - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[I]->SizeInBits) { - F = Chain[I]; - break; - } - - Offset -= Chain[I]->SizeInBits; - } - if (!F) { - Error("Malformed macro record offset"); - return; - } - - ReadMacroRecord(*F, Offset); + RecordLocation Loc = getLocalBitOffset(Offset); + ReadMacroRecord(*Loc.F, Loc.Offset); } void ASTReader::LoadMacroDefinition(IdentifierInfo *II) { @@ -2027,7 +2007,7 @@ ASTReader::ReadASTBlock(PerFileData &F) { // If we have to ignore the dependency, we'll have to ignore this too. case IgnorePCH: return IgnorePCH; case Success: break; - } + } break; } @@ -2420,10 +2400,6 @@ ASTReader::ReadASTBlock(PerFileData &F) { -getTotalNumCXXBaseSpecifiers()))); NumCXXBaseSpecifiersLoaded += F.LocalNumCXXBaseSpecifiers; - - F.GlobalBitOffset = TotalModulesSizeInBits; - TotalModulesSizeInBits += F.SizeInBits; - break; } @@ -2705,7 +2681,7 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName, llvm::BitstreamCursor &Stream = F.Stream; Stream.init(F.StreamFile); F.SizeInBits = F.Buffer->getBufferSize() * 8; - + // Sniff for the signature. if (Stream.Read(8) != 'C' || Stream.Read(8) != 'P' || @@ -2764,7 +2740,12 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName, break; } } - + + // Once read, set the PerFileData bit base offset and update the size in + // bits of all files we've seen. + F.GlobalBitOffset = TotalModulesSizeInBits; + TotalModulesSizeInBits += F.SizeInBits; + GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F)); return Success; } @@ -3090,26 +3071,13 @@ void ASTReader::ReadPreprocessedEntities() { } PreprocessedEntity *ASTReader::ReadPreprocessedEntityAtOffset(uint64_t Offset) { - PerFileData *F = 0; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[I]->SizeInBits) { - F = Chain[I]; - break; - } - - Offset -= Chain[I]->SizeInBits; - } - - if (!F) { - Error("Malformed preprocessed entity offset"); - return 0; - } + RecordLocation Loc = getLocalBitOffset(Offset); // Keep track of where we are in the stream, then jump back there // after reading this entity. - SavedStreamPosition SavedPosition(F->PreprocessorDetailCursor); - F->PreprocessorDetailCursor.JumpToBit(Offset); - return LoadPreprocessedEntity(*F); + SavedStreamPosition SavedPosition(Loc.F->PreprocessorDetailCursor); + Loc.F->PreprocessorDetailCursor.JumpToBit(Loc.Offset); + return LoadPreprocessedEntity(*Loc.F); } HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { @@ -4006,25 +3974,10 @@ ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { } CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { - // Figure out which AST file contains this offset. - PerFileData *F = 0; - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - if (Offset < Chain[N - I - 1]->SizeInBits) { - F = Chain[N - I - 1]; - break; - } - - Offset -= Chain[N - I - 1]->SizeInBits; - } - - if (!F) { - Error("Malformed AST file: C++ base specifiers at impossible offset"); - return 0; - } - - llvm::BitstreamCursor &Cursor = F->DeclsCursor; + RecordLocation Loc = getLocalBitOffset(Offset); + llvm::BitstreamCursor &Cursor = Loc.F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Offset); + Cursor.JumpToBit(Loc.Offset); ReadingKindTracker ReadingKind(Read_Decl, *this); RecordData Record; unsigned Code = Cursor.ReadCode(); @@ -4039,7 +3992,7 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { void *Mem = Context->Allocate(sizeof(CXXBaseSpecifier) * NumBases); CXXBaseSpecifier *Bases = new (Mem) CXXBaseSpecifier [NumBases]; for (unsigned I = 0; I != NumBases; ++I) - Bases[I] = ReadCXXBaseSpecifier(*F, Record, Idx); + Bases[I] = ReadCXXBaseSpecifier(*Loc.F, Record, Idx); return Bases; } @@ -4099,17 +4052,9 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { ClearSwitchCaseIDs(); // Offset here is a global offset across the entire chain. - for (unsigned I = 0, N = Chain.size(); I != N; ++I) { - PerFileData &F = *Chain[N - I - 1]; - if (Offset < F.SizeInBits) { - // Since we know that this statement is part of a decl, make sure to use - // the decl cursor to read it. - F.DeclsCursor.JumpToBit(Offset); - return ReadStmtFromStream(F); - } - Offset -= F.SizeInBits; - } - llvm_unreachable("Broken chain"); + RecordLocation Loc = getLocalBitOffset(Offset); + Loc.F->DeclsCursor.JumpToBit(Loc.Offset); + return ReadStmtFromStream(*Loc.F); } ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC, @@ -4342,6 +4287,7 @@ dumpModuleIDOffsetMap(llvm::StringRef Name, void ASTReader::dump() { llvm::errs() << "*** AST File Remapping:\n"; + dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap); dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap); dumpModuleIDOffsetMap("Global type map", GlobalTypeMap); dumpModuleIDOffsetMap("Global declaration map", GlobalDeclMap); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 20b72ec4e2..841c4d7d1b 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -178,16 +178,7 @@ namespace clang { } uint64_t ASTDeclReader::GetCurrentCursorOffset() { - uint64_t Off = 0; - for (unsigned I = 0, N = Reader.Chain.size(); I != N; ++I) { - ASTReader::PerFileData &F = *Reader.Chain[N - I - 1]; - if (&Cursor == &F.DeclsCursor) { - Off += F.DeclsCursor.GetCurrentBitNo(); - break; - } - Off += F.SizeInBits; - } - return Off; + return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset; } void ASTDeclReader::Visit(Decl *D) { @@ -1419,6 +1410,14 @@ ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) { I->second.first->DeclOffsets[Index + I->second.second]); } +ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) { + ContinuousRangeMap<uint64_t, PerFileData*, 4>::iterator I + = GlobalBitOffsetsMap.find(GlobalOffset); + + assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map"); + return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset); +} + void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { assert(D && previous); if (TagDecl *TD = dyn_cast<TagDecl>(D)) { diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index aaf4678ba2..e6e88f8f87 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1803,6 +1803,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { unsigned IndexBase = Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0; RecordData Record; + uint64_t BitsInChain = Chain? Chain->TotalModulesSizeInBits : 0; for (PreprocessingRecord::iterator E = PPRec.begin(Chain), EEnd = PPRec.end(Chain); E != EEnd; ++E) { @@ -1819,7 +1820,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { // Notify the serialization listener that we're serializing this entity. if (SerializationListener) SerializationListener->SerializedPreprocessedEntity(*E, - Stream.GetCurrentBitNo()); + BitsInChain + Stream.GetCurrentBitNo()); unsigned Position = ID - FirstMacroID; if (Position != MacroDefinitionOffsets.size()) { @@ -1843,7 +1844,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { // Notify the serialization listener that we're serializing this entity. if (SerializationListener) SerializationListener->SerializedPreprocessedEntity(*E, - Stream.GetCurrentBitNo()); + BitsInChain + Stream.GetCurrentBitNo()); if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) { Record.push_back(IndexBase + NumPreprocessingRecords++); |