forked from OSchip/llvm-project
[modules] Remove CXX_BASE_SPECIFIERS_OFFSETS table. Instead of storing an ID of
a table entry in the corresponding decl, store an offset from the current record to the relevant CXX_BASE_SPECIFIERS record. This results in fewer indirections and a minor .pcm file size reduction. llvm-svn: 266266
This commit is contained in:
parent
42b5969862
commit
645d2cfd9c
|
@ -523,6 +523,13 @@ class CXXRecordDecl : public RecordDecl {
|
|||
return getVBasesSlowCase();
|
||||
}
|
||||
|
||||
ArrayRef<CXXBaseSpecifier> bases() const {
|
||||
return llvm::makeArrayRef(getBases(), NumBases);
|
||||
}
|
||||
ArrayRef<CXXBaseSpecifier> vbases() const {
|
||||
return llvm::makeArrayRef(getVBases(), NumVBases);
|
||||
}
|
||||
|
||||
private:
|
||||
CXXBaseSpecifier *getBasesSlowCase() const;
|
||||
CXXBaseSpecifier *getVBasesSlowCase() const;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -409,35 +409,6 @@ private:
|
|||
/// file.
|
||||
unsigned NumVisibleDeclContexts;
|
||||
|
||||
/// \brief The offset of each CXXBaseSpecifier set within the AST.
|
||||
SmallVector<uint32_t, 16> 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<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
|
||||
|
||||
/// \brief A mapping from each known submodule to its ID number, which will
|
||||
/// be a positive integer.
|
||||
llvm::DenseMap<Module *, unsigned> 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<CXXBaseSpecifier> 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<CXXCtorInitializer*> CtorInits);
|
||||
|
||||
|
|
|
@ -399,13 +399,6 @@ public:
|
|||
/// as a local ID (for this module file).
|
||||
llvm::DenseMap<ModuleFile *, serialization::DeclID> 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<CXXBaseSpecifier> 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<CXXBaseSpecifier> Bases) {
|
||||
AddOffset(EmitCXXBaseSpecifiers(*Writer, Bases));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
EmitCXXCtorInitializers(ASTWriter &W,
|
||||
ArrayRef<CXXCtorInitializer *> 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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue