Skip to content

[Serialization] Storing DeclID separately #95897

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
@@ -285,6 +285,9 @@ using unaligned_decl_id_t =
serialization::DeclID, llvm::endianness::native,
llvm::support::unaligned>;

/// The number of slots needed to record a DeclID in bitstreams.
const unsigned int DeclIDSerialiazedSize = 2;

/// The number of predefined preprocessed entity IDs.
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;

5 changes: 2 additions & 3 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
@@ -592,7 +592,7 @@ class ASTReader

/// An array of lexical contents of a declaration context, as a sequence of
/// Decl::Kind, DeclID pairs.
using LexicalContents = ArrayRef<serialization::unaligned_decl_id_t>;
using LexicalContents = ArrayRef<uint32_t>;

/// Map from a DeclContext to its lexical contents.
llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
@@ -945,8 +945,7 @@ class ASTReader
SmallVector<uint64_t, 8> DelayedDeleteExprs;

// A list of late parsed template function data with their module files.
SmallVector<std::pair<ModuleFile *, SmallVector<uint64_t, 1>>, 4>
LateParsedTemplates;
SmallVector<std::pair<ModuleFile *, RecordData>, 4> LateParsedTemplates;

/// The IDs of all decls to be checked for deferred diags.
///
19 changes: 19 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
@@ -86,6 +86,11 @@ class ASTRecordReader
/// Skips the specified number of values.
void skipInts(unsigned N) { Idx += N; }

/// Skips the specified number of DeclIDs.
void skipDeclRefs(unsigned N) {
Idx += N * serialization::DeclIDSerialiazedSize;
}

/// Retrieve the global submodule ID its local ID number.
serialization::SubmoduleID
getGlobalSubmoduleID(unsigned LocalID) {
@@ -187,12 +192,26 @@ class ASTRecordReader
/// Reads a declaration from the given position in a record in the
/// given module, advancing Idx.
Decl *readDecl() {
#ifndef NDEBUG
unsigned OldIdx = Idx;
Decl *D = Reader->ReadDecl(*F, Record, Idx);
assert(Idx - OldIdx == serialization::DeclIDSerialiazedSize);
return D;
#endif
return Reader->ReadDecl(*F, Record, Idx);
}
Decl *readDeclRef() {
return readDecl();
}

template <class DeclKind, class Func> void readDeclArray(Func &&ConsumeFunc) {
unsigned LengthOfArray = readInt();
unsigned End = Idx + LengthOfArray;

while (Idx < End)
ConsumeFunc(readDeclAs<DeclKind>());
}

/// Reads a declaration from the given position in the record,
/// advancing Idx.
///
27 changes: 27 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
@@ -234,12 +234,39 @@ class ASTRecordWriter

/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
#ifndef NDEBUG
unsigned OldSize = size();
Writer->AddDeclRef(D, *Record);
assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
return;
#endif
return Writer->AddDeclRef(D, *Record);
}
void writeDeclRef(const Decl *D) {
AddDeclRef(D);
}

void writeNullDeclRef() {
#ifndef NDEBUG
unsigned OldSize = size();
#endif

push_back(0);
push_back(0);

#ifndef NDEBUG
assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
#endif
}

template <class DeclKind> void writeDeclArray(ArrayRef<DeclKind *> Array) {
unsigned ElementNum = Array.size();
push_back(ElementNum * serialization::DeclIDSerialiazedSize);

for (DeclKind *D : Array)
AddDeclRef(D);
}

/// Emit a declaration name.
void AddDeclarationName(DeclarationName Name) {
writeDeclarationName(Name);
44 changes: 23 additions & 21 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
@@ -1306,9 +1306,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
auto &Lex = LexicalDecls[DC];
if (!Lex.first) {
Lex = std::make_pair(
&M, llvm::ArrayRef(
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
Blob.size() / sizeof(DeclID)));
&M, llvm::ArrayRef(reinterpret_cast<const uint32_t *>(Blob.data()),
Blob.size() / sizeof(uint32_t)));
}
DC->setHasExternalLexicalStorage(true);
return false;
@@ -3422,8 +3421,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
case TU_UPDATE_LEXICAL: {
DeclContext *TU = ContextObj->getTranslationUnitDecl();
LexicalContents Contents(
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
static_cast<unsigned int>(Blob.size() / sizeof(DeclID)));
reinterpret_cast<const uint32_t *>(Blob.data()),
static_cast<unsigned int>(Blob.size() / sizeof(uint32_t)));
TULexicalDecls.push_back(std::make_pair(&F, Contents));
TU->setHasExternalLexicalStorage(true);
break;
@@ -3696,7 +3695,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case VTABLE_USES:
if (Record.size() % 3 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1 + 1) != 0)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"Invalid VTABLE_USES record");

@@ -3714,8 +3713,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case PENDING_IMPLICIT_INSTANTIATIONS:

if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
@@ -3728,7 +3726,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case SEMA_DECL_REFS:
if (Record.size() != 3)
if (Record.size() != 3 * serialization::DeclIDSerialiazedSize)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"Invalid SEMA_DECL_REFS block");
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
@@ -3786,7 +3784,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
}

case DECL_UPDATE_OFFSETS:
if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"invalid DECL_UPDATE_OFFSETS block in AST file");
@@ -3803,7 +3801,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
if (Record.size() % 3 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 2) != 0)
return llvm::createStringError(
std::errc::illegal_byte_sequence,
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
@@ -3898,7 +3896,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
break;

case UNDEFINED_BUT_USED:
if (Record.size() % 2 != 0)
if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
return llvm::createStringError(std::errc::illegal_byte_sequence,
"invalid undefined-but-used record");
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
@@ -7893,7 +7891,10 @@ GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
return GlobalDeclID(0);
}

return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++]));
uint32_t ModuleFileIndex = Record[Idx++];
uint32_t LocalDeclIndex = Record[Idx++];
return getGlobalDeclID(
F, LocalDeclID::get(*this, F, ModuleFileIndex, LocalDeclIndex));
}

/// Resolve the offset of a statement into a statement.
@@ -7922,25 +7923,26 @@ void ASTReader::FindExternalLexicalDecls(
SmallVectorImpl<Decl *> &Decls) {
bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};

auto Visit = [&] (ModuleFile *M, LexicalContents LexicalDecls) {
assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
auto Visit = [&](ModuleFile *M, LexicalContents LexicalDecls) {
assert(LexicalDecls.size() % 3 == 0 && "incorrect number of entries");
for (int I = 0, N = LexicalDecls.size(); I != N; I += 3) {
auto K = (Decl::Kind)+LexicalDecls[I];
if (!IsKindWeWant(K))
continue;

auto ID = (DeclID) + LexicalDecls[I + 1];
LocalDeclID ID =
LocalDeclID::get(*this, *M, LexicalDecls[I + 1], LexicalDecls[I + 2]);

// Don't add predefined declarations to the lexical context more
// than once.
if (ID < NUM_PREDEF_DECL_IDS) {
if (PredefsVisited[ID])
if (PredefsVisited[ID.getRawValue()])
continue;

PredefsVisited[ID] = true;
PredefsVisited[ID.getRawValue()] = true;
}

if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) {
if (Decl *D = GetLocalDecl(*M, ID)) {
assert(D->getKind() == K && "wrong kind for lexical decl");
if (!DC->isDeclInLexicalTraversal(D))
Decls.push_back(D);
@@ -8837,7 +8839,7 @@ void ASTReader::ReadLateParsedTemplates(
&LPTMap) {
for (auto &LPT : LateParsedTemplates) {
ModuleFile *FMod = LPT.first;
RecordDataImpl &LateParsed = LPT.second;
RecordData &LateParsed = LPT.second;
for (unsigned Idx = 0, N = LateParsed.size(); Idx < N;
/* In loop */) {
FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx);
18 changes: 8 additions & 10 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
@@ -1020,9 +1020,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
// Templates.
UnresolvedSet<8> Candidates;
unsigned NumCandidates = Record.readInt();
while (NumCandidates--)
Candidates.addDecl(readDeclAs<NamedDecl>());
Record.readDeclArray<NamedDecl>(
[&Candidates](NamedDecl *ND) { Candidates.addDecl(ND); });

// Templates args.
TemplateArgumentListInfo TemplArgsWritten;
@@ -1152,11 +1151,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setIsPureVirtual(Pure);

// Read in the parameters.
unsigned NumParams = Record.readInt();
SmallVector<ParmVarDecl *, 16> Params;
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(readDeclAs<ParmVarDecl>());
Record.readDeclArray<ParmVarDecl>(
[&Params](ParmVarDecl *ParmD) { Params.push_back(ParmD); });
FD->setParams(Reader.getContext(), Params);
}

@@ -2309,7 +2306,7 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
} else {
// We don't care about which declarations this used to override; we get
// the relevant information from the canonical declaration.
Record.skipInts(NumOverridenMethods);
Record.skipDeclRefs(NumOverridenMethods);
}
}

@@ -4354,8 +4351,9 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
// FIXME: We have several different dispatches on decl kind here; maybe
// we should instead generate one loop per kind and dispatch up-front?
Decl *MostRecent = FirstLocal;
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
unsigned Idx = N - I - 1;
for (unsigned I = 0, N = Record.size(); I != N;
I += serialization::DeclIDSerialiazedSize) {
unsigned Idx = N - I - serialization::DeclIDSerialiazedSize;
auto *D = ReadDecl(*M, Record, Idx);
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
MostRecent = D;
9 changes: 5 additions & 4 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
@@ -351,14 +351,15 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
S->setStartLoc(readSourceLocation());
S->setEndLoc(readSourceLocation());

if (Record.size() - Record.getIdx() == 1) {
unsigned NumDecls =
(Record.size() - Record.getIdx()) / serialization::DeclIDSerialiazedSize;
if (NumDecls == 1) {
// Single declaration
S->setDeclGroup(DeclGroupRef(readDecl()));
} else {
SmallVector<Decl *, 16> Decls;
int N = Record.size() - Record.getIdx();
Decls.reserve(N);
for (int I = 0; I < N; ++I)
Decls.reserve(NumDecls);
for (unsigned I = 0; I < NumDecls; ++I)
Decls.push_back(readDecl());
S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Record.getContext(),
Decls.data(),
28 changes: 19 additions & 9 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
@@ -3321,7 +3321,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
return 0;

uint64_t Offset = Stream.GetCurrentBitNo();
SmallVector<DeclID, 128> KindDeclPairs;
SmallVector<uint32_t, 128> KindDeclPairs;
for (const auto *D : DC->decls()) {
if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
continue;
@@ -3336,7 +3336,9 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
continue;

KindDeclPairs.push_back(D->getKind());
KindDeclPairs.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);
KindDeclPairs.push_back(ID.getModuleFileIndex());
KindDeclPairs.push_back(ID.getLocalDeclIndex());
}

++NumLexicalDeclContexts;
@@ -4451,8 +4453,9 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC)));

// Write the lookup table
RecordData::value_type Record[] = {UPDATE_VISIBLE,
getDeclID(cast<Decl>(DC)).getRawValue()};
LocalDeclID ID = getDeclID(cast<Decl>(DC));
RecordData::value_type Record[] = {UPDATE_VISIBLE, ID.getModuleFileIndex(),
ID.getLocalDeclIndex()};
Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
}

@@ -5243,9 +5246,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
RecordData SemaDeclRefs;
if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
auto AddEmittedDeclRefOrZero = [this, &SemaDeclRefs](Decl *D) {
if (!D || !wasDeclEmitted(D))
if (!D || !wasDeclEmitted(D)) {
SemaDeclRefs.push_back(0);
else
SemaDeclRefs.push_back(0);
} else
AddDeclRef(D, SemaDeclRefs);
};

@@ -5679,7 +5683,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
// Create a lexical update block containing all of the declarations in the
// translation unit that do not come from other AST files.
SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
for (const auto *D : TU->noload_decls()) {
if (D->isFromASTFile())
continue;
@@ -5689,7 +5693,9 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
continue;

NewGlobalKindDeclPairs.push_back(D->getKind());
NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);
NewGlobalKindDeclPairs.push_back(ID.getModuleFileIndex());
NewGlobalKindDeclPairs.push_back(ID.getLocalDeclIndex());
}

auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
@@ -5704,6 +5710,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
Abv = std::make_shared<llvm::BitCodeAbbrev>();
Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));

@@ -6195,7 +6202,10 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
}

void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
Record.push_back(GetDeclRef(D).getRawValue());
LocalDeclID ID = GetDeclRef(D);

Record.push_back(ID.getModuleFileIndex());
Record.push_back(ID.getLocalDeclIndex());
}

LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
Loading