diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-10-29 22:39:52 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-10-29 22:39:52 +0000 |
commit | 7c789c1a3f77f24032aa0bed2afacdb9e094e952 (patch) | |
tree | 7891cd4684de4f541f141dad60c9698590ead702 /lib/Serialization/ASTReader.cpp | |
parent | 110e8e56af30363072c140285961592b0107f789 (diff) |
Make the deserialization of C++ base class specifiers lazy, improving
the performance of C++ PCH and reducing stack depth in the reader.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117732 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 6497b78772..aa76765dc9 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2069,6 +2069,17 @@ ASTReader::ReadASTBlock(PerFileData &F) { std::make_pair(&F, Record[I+1]); break; } + + case CXX_BASE_SPECIFIER_OFFSETS: { + if (F.LocalNumCXXBaseSpecifiers != 0) { + Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file"); + return Failure; + } + + F.LocalNumCXXBaseSpecifiers = Record[0]; + F.CXXBaseSpecifiersOffsets = (const uint32_t *)BlobStart; + break; + } } First = false; } @@ -3207,6 +3218,14 @@ TypeIdx ASTReader::GetTypeIdx(QualType T) const { return I->second; } +unsigned ASTReader::getTotalNumCXXBaseSpecifiers() const { + unsigned Result = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) + Result += Chain[I]->LocalNumCXXBaseSpecifiers; + + return Result; +} + TemplateArgumentLocInfo ASTReader::GetTemplateArgumentLocInfo(PerFileData &F, TemplateArgument::ArgKind Kind, @@ -3249,6 +3268,63 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } +uint64_t +ASTReader::GetCXXBaseSpecifiersOffset(serialization::CXXBaseSpecifiersID ID) { + if (ID == 0) + return 0; + + --ID; + uint64_t Offset = 0; + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (ID < Chain[I]->LocalNumCXXBaseSpecifiers) + return Offset + Chain[I]->CXXBaseSpecifiersOffsets[ID]; + + ID -= Chain[I]->LocalNumCXXBaseSpecifiers; + Offset += Chain[I]->SizeInBits; + } + + assert(false && "CXXBaseSpecifiers not found"); + return 0; +} + +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[I]->SizeInBits) { + F = Chain[I]; + break; + } + + Offset -= Chain[I]->SizeInBits; + } + + if (!F) { + Error("Malformed AST file: C++ base specifiers at impossible offset"); + return 0; + } + + llvm::BitstreamCursor &Cursor = F->DeclsCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(Offset); + ReadingKindTracker ReadingKind(Read_Decl, *this); + RecordData Record; + unsigned Code = Cursor.ReadCode(); + unsigned RecCode = Cursor.ReadRecord(Code, Record); + if (RecCode != DECL_CXX_BASE_SPECIFIERS) { + Error("Malformed AST file: missing C++ base specifiers"); + return 0; + } + + unsigned Idx = 0; + unsigned NumBases = Record[Idx++]; + 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); + return Bases; +} + TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() { if (!DeclsLoaded[0]) { ReadDeclRecord(0, 1); @@ -4411,7 +4487,8 @@ ASTReader::PerFileData::PerFileData(ASTFileType Ty) IdentifierLookupTable(0), LocalNumMacroDefinitions(0), MacroDefinitionOffsets(0), LocalNumSelectors(0), SelectorOffsets(0), SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), - DeclOffsets(0), LocalNumTypes(0), TypeOffsets(0), StatCache(0), + DeclOffsets(0), LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0), + LocalNumTypes(0), TypeOffsets(0), StatCache(0), NumPreallocatedPreprocessingEntities(0), NextInSource(0) {} |