diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-24 06:36:48 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-24 06:36:48 +0000 |
commit | c2bb81860b99e572477fab761ec4246933db29dd (patch) | |
tree | ac8b9c98fc73764801ec794b07228ffbc4d31c3b /clang/lib/Serialization/ASTWriter.cpp | |
parent | 20f3da11e8760c994a0c9db9cab08f7442937201 (diff) | |
download | bcm5719-llvm-c2bb81860b99e572477fab761ec4246933db29dd.tar.gz bcm5719-llvm-c2bb81860b99e572477fab761ec4246933db29dd.zip |
[modules] Deserialize CXXCtorInitializer list for a constructor lazily.
Previously we'd deserialize the list of mem-initializers for a constructor when
we deserialized the declaration of the constructor. That could trigger a
significant amount of unnecessary work (pulling in all base classes
recursively, for a start) and was causing problems for the modules buildbot due
to cyclic deserializations. We now deserialize these on demand.
This creates a certain amount of duplication with the handling of
CXXBaseSpecifiers; I'll look into reducing that next.
llvm-svn: 233052
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e992685a83d..ced3d297f98 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2694,6 +2694,29 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); } +void ASTWriter::WriteCXXCtorInitializersOffsets() { + if (CXXCtorInitializersOffsets.empty()) + return; + + RecordData Record; + + // Create a blob abbreviation for the C++ ctor initializer offsets. + using namespace llvm; + + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(CXX_CTOR_INITIALIZERS_OFFSETS)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned CtorInitializersOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + + // Write the base specifier offsets table. + Record.clear(); + Record.push_back(CXX_CTOR_INITIALIZERS_OFFSETS); + Record.push_back(CXXCtorInitializersOffsets.size()); + Stream.EmitRecordWithBlob(CtorInitializersOffsetAbbrev, Record, + data(CXXCtorInitializersOffsets)); +} + void ASTWriter::WriteCXXBaseSpecifiersOffsets() { if (CXXBaseSpecifiersOffsets.empty()) return; @@ -4154,7 +4177,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), - NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0), + NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1), + TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), @@ -4559,6 +4583,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, if (!DeclUpdatesOffsetsRecord.empty()) Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); WriteCXXBaseSpecifiersOffsets(); + WriteCXXCtorInitializersOffsets(); WriteFileDeclIDsMap(); WriteSourceManagerBlock(Context.getSourceManager(), PP); @@ -4818,11 +4843,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { Stream.EmitRecord(DECL_UPDATES, Record); - // Flush any statements that were written as part of this update record. - FlushStmts(); - - // Flush C++ base specifiers, if there are any. - FlushCXXBaseSpecifiers(); + FlushPendingAfterDecl(); } } @@ -4934,8 +4955,16 @@ void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record AddDeclRef(Temp->getDestructor(), Record); } +void ASTWriter::AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, + RecordDataImpl &Record) { + assert(!Inits.empty() && "Empty ctor initializer sets are not recorded"); + CXXCtorInitializersToWrite.push_back( + QueuedCXXCtorInitializers(NextCXXCtorInitializersID, Inits)); + Record.push_back(NextCXXCtorInitializersID++); +} + void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd, + CXXBaseSpecifier const *BasesEnd, RecordDataImpl &Record) { assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); CXXBaseSpecifiersToWrite.push_back( @@ -5496,7 +5525,8 @@ void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, void ASTWriter::FlushCXXBaseSpecifiers() { RecordData Record; - for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { + unsigned N = CXXBaseSpecifiersToWrite.size(); + for (unsigned I = 0; I != N; ++I) { Record.clear(); // Record the offset of this base-specifier set. @@ -5520,6 +5550,8 @@ void ASTWriter::FlushCXXBaseSpecifiers() { FlushStmts(); } + assert(N == CXXBaseSpecifiersToWrite.size() && + "added more base specifiers while writing base specifiers"); CXXBaseSpecifiersToWrite.clear(); } @@ -5561,6 +5593,35 @@ void ASTWriter::AddCXXCtorInitializers( } } +void ASTWriter::FlushCXXCtorInitializers() { + RecordData Record; + + unsigned N = CXXCtorInitializersToWrite.size(); + for (auto &Init : CXXCtorInitializersToWrite) { + Record.clear(); + + // Record the offset of this mem-initializer list. + unsigned Index = Init.ID - 1; + if (Index == CXXCtorInitializersOffsets.size()) + CXXCtorInitializersOffsets.push_back(Stream.GetCurrentBitNo()); + else { + if (Index > CXXCtorInitializersOffsets.size()) + CXXCtorInitializersOffsets.resize(Index + 1); + CXXCtorInitializersOffsets[Index] = Stream.GetCurrentBitNo(); + } + + AddCXXCtorInitializers(Init.Inits.data(), Init.Inits.size(), Record); + Stream.EmitRecord(serialization::DECL_CXX_CTOR_INITIALIZERS, Record); + + // Flush any expressions that were written as part of the initializers. + FlushStmts(); + } + + assert(N == CXXCtorInitializersToWrite.size() && + "added more ctor initializers while writing ctor initializers"); + CXXCtorInitializersToWrite.clear(); +} + void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { auto &Data = D->data(); Record.push_back(Data.IsLambda); |