diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 67ce84288fe8..8906d9c798bc 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -523,6 +523,13 @@ class CXXRecordDecl : public RecordDecl { return getVBasesSlowCase(); } + ArrayRef bases() const { + return llvm::makeArrayRef(getBases(), NumBases); + } + ArrayRef vbases() const { + return llvm::makeArrayRef(getVBases(), NumVBases); + } + private: CXXBaseSpecifier *getBasesSlowCase() const; CXXBaseSpecifier *getVBasesSlowCase() const; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 696c8cdf108b..adec5001e98c 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -491,9 +491,7 @@ namespace clang { // ID 30 used to be a decl update record. These are now in the DECLTYPES // block. - /// \brief Record code for the table of offsets to CXXBaseSpecifier - /// sets. - CXX_BASE_SPECIFIER_OFFSETS = 31, + // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records. /// \brief Record code for \#pragma diagnostic mappings. DIAG_PRAGMA_MAPPINGS = 32, diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 18064a781f89..a80989d88611 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1687,11 +1687,6 @@ public: /// redeclaration chain for \p D. void CompleteRedeclChain(const Decl *D) override; - /// \brief Read a CXXBaseSpecifiers ID form the given record and - /// return its global bit offset. - uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, - unsigned &Idx); - CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; /// \brief Resolve the offset of a statement into a statement. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index c554380e0f0c..5ca94b2c3613 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -409,35 +409,6 @@ private: /// file. unsigned NumVisibleDeclContexts; - /// \brief The offset of each CXXBaseSpecifier set within the AST. - SmallVector CXXBaseSpecifiersOffsets; - - /// \brief The first ID number we can use for our own base specifiers. - serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID; - - /// \brief The base specifiers ID that will be assigned to the next new - /// set of C++ base specifiers. - serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID; - - /// \brief A set of C++ base specifiers that is queued to be written into the - /// AST file. - struct QueuedCXXBaseSpecifiers { - QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { } - - QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID, - CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd) - : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { } - - serialization::CXXBaseSpecifiersID ID; - CXXBaseSpecifier const * Bases; - CXXBaseSpecifier const * BasesEnd; - }; - - /// \brief Queue of C++ base specifiers to be written to the AST file, - /// in the order they should be written. - SmallVector CXXBaseSpecifiersToWrite; - /// \brief A mapping from each known submodule to its ID number, which will /// be a positive integer. llvm::DenseMap SubmoduleIDs; @@ -466,7 +437,6 @@ private: void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, bool isModule); - void WriteCXXBaseSpecifiersOffsets(); unsigned TypeExtQualAbbrev; unsigned TypeFunctionProtoAbbrev; @@ -574,11 +544,6 @@ public: /// \brief Emit a CXXTemporary. void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record); - /// \brief Emit a set of C++ base specifiers to the record. - void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd, - RecordDataImpl &Record); - /// \brief Get the unique number used to refer to the given selector. serialization::SelectorID getSelectorRef(Selector Sel); @@ -666,16 +631,6 @@ public: /// within the method pool/selector table. void SetSelectorOffset(Selector Sel, uint32_t Offset); - /// \brief Flush all of the C++ base specifier sets that have been added - /// via \c AddCXXBaseSpecifiersRef(). - void FlushCXXBaseSpecifiers(); - - /// \brief Flush all pending records that are tacked onto the end of - /// decl and decl update records. - void FlushPendingAfterDecl() { - FlushCXXBaseSpecifiers(); - } - /// \brief Record an ID for the given switch-case statement. unsigned RecordSwitchCaseID(SwitchCase *S); @@ -877,11 +832,11 @@ public: return Writer->AddCXXTemporary(Temp, *Record); } + /// \brief Emit a C++ base specifier. + void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base); + /// \brief Emit a set of C++ base specifiers. - void AddCXXBaseSpecifiersRef(const CXXBaseSpecifier *BasesBegin, - const CXXBaseSpecifier *BasesEnd) { - return Writer->AddCXXBaseSpecifiersRef(BasesBegin, BasesEnd, *Record); - } + void AddCXXBaseSpecifiers(ArrayRef Bases); /// \brief Emit a reference to a type. void AddTypeRef(QualType T) { @@ -947,9 +902,6 @@ public: return Writer->AddUnresolvedSet(Set, *Record); } - /// \brief Emit a C++ base specifier. - void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base); - /// \brief Emit a CXXCtorInitializer array. void AddCXXCtorInitializers(ArrayRef CtorInits); diff --git a/clang/include/clang/Serialization/Module.h b/clang/include/clang/Serialization/Module.h index 951837df138e..aa0392f0ecfb 100644 --- a/clang/include/clang/Serialization/Module.h +++ b/clang/include/clang/Serialization/Module.h @@ -399,13 +399,6 @@ public: /// as a local ID (for this module file). llvm::DenseMap GlobalToLocalDeclIDs; - /// \brief The number of C++ base specifier sets in this AST file. - unsigned LocalNumCXXBaseSpecifiers; - - /// \brief Offset of each C++ base specifier set within the bitstream, - /// indexed by the C++ base specifier set ID (-1). - const uint32_t *CXXBaseSpecifiersOffsets; - /// \brief Array of file-level DeclIDs sorted by file. const serialization::DeclID *FileSortedDecls; unsigned NumFileSortedDecls; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 947df5e44489..5c4371bfefbf 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3053,17 +3053,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.ObjCCategories.swap(Record); 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 *)Blob.data(); - break; - } - case DIAG_PRAGMA_MAPPINGS: if (F.PragmaDiagMappings.empty()) F.PragmaDiagMappings.swap(Record); @@ -6312,18 +6301,6 @@ ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) { return ReadCXXCtorInitializers(*Loc.F, Record, Idx); } -uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, - const RecordData &Record, - unsigned &Idx) { - if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXBaseSpecifiers) { - Error("malformed AST file: missing C++ base specifier"); - return 0; - } - - unsigned LocalID = Record[Idx++]; - return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]); -} - CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { RecordLocation Loc = getLocalBitOffset(Offset); BitstreamCursor &Cursor = Loc.F->DeclsCursor; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 4316be1d006a..03d1b115d023 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1479,10 +1479,10 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.NumBases = Record[Idx++]; if (Data.NumBases) - Data.Bases = Reader.readCXXBaseSpecifiers(F, Record, Idx); + Data.Bases = ReadGlobalOffset(F, Record, Idx); Data.NumVBases = Record[Idx++]; if (Data.NumVBases) - Data.VBases = Reader.readCXXBaseSpecifiers(F, Record, Idx); + Data.VBases = ReadGlobalOffset(F, Record, Idx); Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx); Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 0f9677715ff3..2fec5c234930 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -961,7 +961,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(UPDATE_VISIBLE); RECORD(DECL_UPDATE_OFFSETS); RECORD(DECL_UPDATES); - RECORD(CXX_BASE_SPECIFIER_OFFSETS); RECORD(DIAG_PRAGMA_MAPPINGS); RECORD(CUDA_SPECIAL_DECL_REFS); RECORD(HEADER_SEARCH_TABLE); @@ -2724,26 +2723,6 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record); } -void ASTWriter::WriteCXXBaseSpecifiersOffsets() { - if (CXXBaseSpecifiersOffsets.empty()) - return; - - // Create a blob abbreviation for the C++ base specifiers offsets. - using namespace llvm; - - auto *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(CXX_BASE_SPECIFIER_OFFSETS)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); - unsigned BaseSpecifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); - - // Write the base specifier offsets table. - RecordData::value_type Record[] = {CXX_BASE_SPECIFIER_OFFSETS, - CXXBaseSpecifiersOffsets.size()}; - Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, - bytes(CXXBaseSpecifiersOffsets)); -} - //===----------------------------------------------------------------------===// // Type Serialization //===----------------------------------------------------------------------===// @@ -4095,7 +4074,6 @@ ASTWriter::ASTWriter( FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), - NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0), TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), @@ -4496,7 +4474,6 @@ uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteTypeDeclOffsets(); if (!DeclUpdatesOffsetsRecord.empty()) Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); - WriteCXXBaseSpecifiersOffsets(); WriteFileDeclIDsMap(); WriteSourceManagerBlock(Context.getSourceManager(), PP); WriteComments(); @@ -4778,8 +4755,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { OffsetsRecord.push_back(GetDeclRef(D)); OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); - - FlushPendingAfterDecl(); } } @@ -4877,16 +4852,6 @@ void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record AddDeclRef(Temp->getDestructor(), Record); } -void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd, - RecordDataImpl &Record) { - assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded"); - CXXBaseSpecifiersToWrite.push_back( - QueuedCXXBaseSpecifiers(NextCXXBaseSpecifiersID, - Bases, BasesEnd)); - Record.push_back(NextCXXBaseSpecifiersID++); -} - void ASTRecordWriter::AddTemplateArgumentLocInfo( TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) { switch (Kind) { @@ -5421,43 +5386,23 @@ void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) { : SourceLocation()); } -void ASTWriter::FlushCXXBaseSpecifiers() { - RecordData Record; - unsigned N = CXXBaseSpecifiersToWrite.size(); - for (unsigned I = 0; I != N; ++I) { - Record.clear(); +static uint64_t EmitCXXBaseSpecifiers(ASTWriter &W, + ArrayRef Bases) { + ASTWriter::RecordData Record; + ASTRecordWriter Writer(W, Record); + Writer.push_back(Bases.size()); - const CXXBaseSpecifier *B = CXXBaseSpecifiersToWrite[I].Bases, - *BEnd = CXXBaseSpecifiersToWrite[I].BasesEnd; + for (auto &Base : Bases) + Writer.AddCXXBaseSpecifier(Base); - // Write the base specifier set. - ASTRecordWriter Writer(*this, Record); - Writer.push_back(BEnd - B); - for (; B != BEnd; ++B) - Writer.AddCXXBaseSpecifier(*B); - uint64_t Offset = Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS); - - // Record the offset of this base-specifier set. - // - // FIXME: We don't need an indirect lookup table for these; instead, write - // the base specifier record prior to the decl record and store its offset - // from the decl record rather than its ID. - unsigned Index = CXXBaseSpecifiersToWrite[I].ID - 1; - if (Index == CXXBaseSpecifiersOffsets.size()) - CXXBaseSpecifiersOffsets.push_back(Offset); - else { - if (Index > CXXBaseSpecifiersOffsets.size()) - CXXBaseSpecifiersOffsets.resize(Index + 1); - CXXBaseSpecifiersOffsets[Index] = Offset; - } - } - - assert(N == CXXBaseSpecifiersToWrite.size() && - "added more base specifiers while writing base specifiers"); - CXXBaseSpecifiersToWrite.clear(); + return Writer.Emit(serialization::DECL_CXX_BASE_SPECIFIERS); } // FIXME: Move this out of the main ASTRecordWriter interface. +void ASTRecordWriter::AddCXXBaseSpecifiers(ArrayRef Bases) { + AddOffset(EmitCXXBaseSpecifiers(*Writer, Bases)); +} + static uint64_t EmitCXXCtorInitializers(ASTWriter &W, ArrayRef CtorInits) { @@ -5550,13 +5495,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Record->push_back(Data.NumBases); if (Data.NumBases > 0) - AddCXXBaseSpecifiersRef(Data.getBases(), Data.getBases() + Data.NumBases); - + AddCXXBaseSpecifiers(Data.bases()); + // FIXME: Make VBases lazily computed when needed to avoid storing them. Record->push_back(Data.NumVBases); if (Data.NumVBases > 0) - AddCXXBaseSpecifiersRef(Data.getVBases(), - Data.getVBases() + Data.NumVBases); + AddCXXBaseSpecifiers(Data.vbases()); AddUnresolvedSet(Data.Conversions.get(*Writer->Context)); AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context)); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 94a593fe486c..e2b03ba98ee7 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -49,14 +49,7 @@ namespace clang { if (!Code) llvm::report_fatal_error(StringRef("unexpected declaration kind '") + D->getDeclKindName() + "'"); - - auto Offset = Record.Emit(Code, AbbrevToUse); - - // Flush any base specifiers and ctor initializers that - // were written as part of this declaration. - Writer.FlushPendingAfterDecl(); - - return Offset; + return Record.Emit(Code, AbbrevToUse); } void Visit(Decl *D); diff --git a/clang/lib/Serialization/Module.cpp b/clang/lib/Serialization/Module.cpp index 872a447429ff..ca0cb3c8ea17 100644 --- a/clang/lib/Serialization/Module.cpp +++ b/clang/lib/Serialization/Module.cpp @@ -37,7 +37,6 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation) LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0), SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr), LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0), - LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(nullptr), FileSortedDecls(nullptr), NumFileSortedDecls(0), ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0), LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)