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
Show file tree
Hide file tree
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
Expand Up @@ -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;

Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>>
Expand Down Expand Up @@ -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.
///
Expand Down
19 changes: 19 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
///
Expand Down
27 changes: 27 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
44 changes: 23 additions & 21 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");

Expand All @@ -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");
Expand All @@ -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*/)
Expand Down Expand Up @@ -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");
Expand All @@ -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 "
Expand Down Expand Up @@ -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 */) {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 8 additions & 10 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
28 changes: 19 additions & 9 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
};

Expand Down Expand Up @@ -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;
Expand All @@ -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>();
Expand All @@ -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));

Expand Down Expand Up @@ -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) {
Expand Down
Loading
Loading