Skip to content

Commit b6d1326

Browse files
committed
Draft
1 parent 8af8602 commit b6d1326

File tree

10 files changed

+233
-127
lines changed

10 files changed

+233
-127
lines changed

clang/include/clang/AST/DeclID.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ class LocalDeclID : public DeclIDBase {
197197

198198
static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
199199
DeclID ID);
200+
static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
201+
unsigned ModuleFileIndex, unsigned LocalDeclID);
200202

201203
LocalDeclID &operator++() {
202204
++ID;

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ using unaligned_decl_id_t =
261261
serialization::DeclID, llvm::endianness::native,
262262
llvm::support::unaligned>;
263263

264+
/// The number of slots needed to record a DeclID in bitstreams.
265+
const unsigned int DeclIDRefSize = 2;
266+
264267
/// The number of predefined preprocessed entity IDs.
265268
const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
266269

clang/include/clang/Serialization/ASTReader.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ class ASTReader
600600

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

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

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

967966
/// The IDs of all decls to be checked for deferred diags.
968967
///

clang/include/clang/Serialization/ASTRecordReader.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,26 @@ class ASTRecordReader
187187
/// Reads a declaration from the given position in a record in the
188188
/// given module, advancing Idx.
189189
Decl *readDecl() {
190+
#ifndef NDEBUG
191+
unsigned OldIdx = Idx;
192+
Decl *D = Reader->ReadDecl(*F, Record, Idx);
193+
assert(Idx - OldIdx == serialization::DeclIDRefSize);
194+
return D;
195+
#endif
190196
return Reader->ReadDecl(*F, Record, Idx);
191197
}
192198
Decl *readDeclRef() {
193199
return readDecl();
194200
}
195201

202+
template <class DeclKind, class Func> void readDeclArray(Func &&ConsumeFunc) {
203+
unsigned LengthOfArray = readInt();
204+
unsigned End = Idx + LengthOfArray;
205+
206+
while (Idx < End)
207+
ConsumeFunc(readDeclAs<DeclKind>());
208+
}
209+
196210
/// Reads a declaration from the given position in the record,
197211
/// advancing Idx.
198212
///

clang/include/clang/Serialization/ASTRecordWriter.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,39 @@ class ASTRecordWriter
234234

235235
/// Emit a reference to a declaration.
236236
void AddDeclRef(const Decl *D) {
237+
#ifndef NDEBUG
238+
unsigned OldSize = size();
239+
Writer->AddDeclRef(D, *Record);
240+
assert(size() - OldSize == serialization::DeclIDRefSize);
241+
return;
242+
#endif
237243
return Writer->AddDeclRef(D, *Record);
238244
}
239245
void writeDeclRef(const Decl *D) {
240246
AddDeclRef(D);
241247
}
242248

249+
void writeNullDeclRef() {
250+
#ifndef NDEBUG
251+
unsigned OldSize = size();
252+
#endif
253+
254+
push_back(0);
255+
push_back(0);
256+
257+
#ifndef NDEBUG
258+
assert(size() - OldSize == serialization::DeclIDRefSize);
259+
#endif
260+
}
261+
262+
template <class DeclKind> void writeDeclArray(ArrayRef<DeclKind *> Array) {
263+
unsigned ElementNum = Array.size();
264+
push_back(ElementNum * serialization::DeclIDRefSize);
265+
266+
for (DeclKind *D : Array)
267+
AddDeclRef(D);
268+
}
269+
243270
/// Emit a declaration name.
244271
void AddDeclarationName(DeclarationName Name) {
245272
writeDeclarationName(Name);

clang/lib/Serialization/ASTReader.cpp

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -935,9 +935,8 @@ LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF, DeclID Value) {
935935
return ID;
936936
}
937937

938-
static LocalDeclID getLocalDeclID(ASTReader &Reader, ModuleFile &MF,
939-
unsigned ModuleFileIndex,
940-
unsigned LocalDeclID) {
938+
LocalDeclID LocalDeclID::get(ASTReader &Reader, ModuleFile &MF,
939+
unsigned ModuleFileIndex, unsigned LocalDeclID) {
941940
DeclID Value = (DeclID)ModuleFileIndex << 32 | (DeclID)LocalDeclID;
942941
return LocalDeclID::get(Reader, MF, Value);
943942
}
@@ -1303,9 +1302,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
13031302
auto &Lex = LexicalDecls[DC];
13041303
if (!Lex.first) {
13051304
Lex = std::make_pair(
1306-
&M, llvm::ArrayRef(
1307-
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
1308-
Blob.size() / sizeof(DeclID)));
1305+
&M, llvm::ArrayRef(reinterpret_cast<const uint32_t *>(Blob.data()),
1306+
Blob.size() / sizeof(uint32_t)));
13091307
}
13101308
DC->setHasExternalLexicalStorage(true);
13111309
return false;
@@ -3426,8 +3424,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
34263424
case TU_UPDATE_LEXICAL: {
34273425
DeclContext *TU = ContextObj->getTranslationUnitDecl();
34283426
LexicalContents Contents(
3429-
reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
3430-
static_cast<unsigned int>(Blob.size() / sizeof(DeclID)));
3427+
reinterpret_cast<const uint32_t *>(Blob.data()),
3428+
static_cast<unsigned int>(Blob.size() / sizeof(uint32_t)));
34313429
TULexicalDecls.push_back(std::make_pair(&F, Contents));
34323430
TU->setHasExternalLexicalStorage(true);
34333431
break;
@@ -3713,16 +3711,16 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
37133711
break;
37143712

37153713
case VTABLE_USES:
3716-
if (Record.size() % 3 != 0)
3717-
return llvm::createStringError(std::errc::illegal_byte_sequence,
3718-
"Invalid VTABLE_USES record");
3719-
37203714
// Later tables overwrite earlier ones.
37213715
// FIXME: Modules will have some trouble with this. This is clearly not
37223716
// the right way to do this.
37233717
VTableUses.clear();
37243718

37253719
for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) {
3720+
if (Idx > N)
3721+
return llvm::createStringError(std::errc::illegal_byte_sequence,
3722+
"Invalid VTABLE_USES record");
3723+
37263724
VTableUses.push_back(
37273725
{ReadDeclID(F, Record, Idx),
37283726
ReadSourceLocation(F, Record, Idx).getRawEncoding(),
@@ -3731,21 +3729,20 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
37313729
break;
37323730

37333731
case PENDING_IMPLICIT_INSTANTIATIONS:
3734-
3735-
if (Record.size() % 2 != 0)
3736-
return llvm::createStringError(
3737-
std::errc::illegal_byte_sequence,
3738-
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
3739-
37403732
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
3733+
if (I > N)
3734+
return llvm::createStringError(
3735+
std::errc::illegal_byte_sequence,
3736+
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
3737+
37413738
PendingInstantiations.push_back(
37423739
{ReadDeclID(F, Record, I),
37433740
ReadSourceLocation(F, Record, I).getRawEncoding()});
37443741
}
37453742
break;
37463743

37473744
case SEMA_DECL_REFS:
3748-
if (Record.size() != 3)
3745+
if (Record.size() != 3 * serialization::DeclIDRefSize)
37493746
return llvm::createStringError(std::errc::illegal_byte_sequence,
37503747
"Invalid SEMA_DECL_REFS block");
37513748
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
@@ -3803,11 +3800,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
38033800
}
38043801

38053802
case DECL_UPDATE_OFFSETS:
3806-
if (Record.size() % 2 != 0)
3807-
return llvm::createStringError(
3808-
std::errc::illegal_byte_sequence,
3809-
"invalid DECL_UPDATE_OFFSETS block in AST file");
38103803
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
3804+
if (I > N)
3805+
return llvm::createStringError(
3806+
std::errc::illegal_byte_sequence,
3807+
"invalid DECL_UPDATE_OFFSETS block in AST file");
38113808
GlobalDeclID ID = ReadDeclID(F, Record, I);
38123809
DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I++]));
38133810

@@ -3820,12 +3817,12 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
38203817
break;
38213818

38223819
case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
3823-
if (Record.size() % 3 != 0)
3824-
return llvm::createStringError(
3825-
std::errc::illegal_byte_sequence,
3826-
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
3827-
"file");
38283820
for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) {
3821+
if (I > N)
3822+
return llvm::createStringError(
3823+
std::errc::illegal_byte_sequence,
3824+
"invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
3825+
"file");
38293826
GlobalDeclID ID = ReadDeclID(F, Record, I);
38303827

38313828
uint64_t BaseOffset = F.DeclsBlockStartOffset;
@@ -3915,10 +3912,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
39153912
break;
39163913

39173914
case UNDEFINED_BUT_USED:
3918-
if (Record.size() % 2 != 0)
3919-
return llvm::createStringError(std::errc::illegal_byte_sequence,
3920-
"invalid undefined-but-used record");
39213915
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
3916+
if (I > N)
3917+
return llvm::createStringError(std::errc::illegal_byte_sequence,
3918+
"invalid undefined-but-used record");
3919+
39223920
UndefinedButUsed.push_back(
39233921
{ReadDeclID(F, Record, I),
39243922
ReadSourceLocation(F, Record, I).getRawEncoding()});
@@ -7880,7 +7878,7 @@ LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
78807878
if (!OrignalModuleFileIndex)
78817879
return LocalDeclID();
78827880

7883-
return getLocalDeclID(*this, M, OrignalModuleFileIndex, ID);
7881+
return LocalDeclID::get(*this, M, OrignalModuleFileIndex, ID);
78847882
}
78857883

78867884
GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
@@ -7890,7 +7888,10 @@ GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
78907888
return GlobalDeclID(0);
78917889
}
78927890

7893-
return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++]));
7891+
uint32_t ModuleFileIndex = Record[Idx++];
7892+
uint32_t LocalDeclIndex = Record[Idx++];
7893+
return getGlobalDeclID(
7894+
F, LocalDeclID::get(*this, F, ModuleFileIndex, LocalDeclIndex));
78947895
}
78957896

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

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

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

79317933
// Don't add predefined declarations to the lexical context more
79327934
// than once.
79337935
if (ID < NUM_PREDEF_DECL_IDS) {
7934-
if (PredefsVisited[ID])
7936+
if (PredefsVisited[ID.getRawValue()])
79357937
continue;
79367938

7937-
PredefsVisited[ID] = true;
7939+
PredefsVisited[ID.getRawValue()] = true;
79387940
}
79397941

7940-
if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) {
7942+
if (Decl *D = GetLocalDecl(*M, ID)) {
79417943
assert(D->getKind() == K && "wrong kind for lexical decl");
79427944
if (!DC->isDeclInLexicalTraversal(D))
79437945
Decls.push_back(D);
@@ -8836,7 +8838,7 @@ void ASTReader::ReadLateParsedTemplates(
88368838
&LPTMap) {
88378839
for (auto &LPT : LateParsedTemplates) {
88388840
ModuleFile *FMod = LPT.first;
8839-
RecordDataImpl &LateParsed = LPT.second;
8841+
const RecordData &LateParsed = LPT.second;
88408842
for (unsigned Idx = 0, N = LateParsed.size(); Idx < N;
88418843
/* In loop */) {
88428844
FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx);

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,9 +1020,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
10201020
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
10211021
// Templates.
10221022
UnresolvedSet<8> Candidates;
1023-
unsigned NumCandidates = Record.readInt();
1024-
while (NumCandidates--)
1025-
Candidates.addDecl(readDeclAs<NamedDecl>());
1023+
Record.readDeclArray<NamedDecl>(
1024+
[&Candidates](NamedDecl *ND) { Candidates.addDecl(ND); });
10261025

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

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

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

@@ -4354,8 +4351,9 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
43544351
// FIXME: We have several different dispatches on decl kind here; maybe
43554352
// we should instead generate one loop per kind and dispatch up-front?
43564353
Decl *MostRecent = FirstLocal;
4357-
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
4358-
unsigned Idx = N - I - 1;
4354+
for (unsigned I = 0, N = Record.size(); I != N;
4355+
I += serialization::DeclIDRefSize) {
4356+
unsigned Idx = N - I - serialization::DeclIDRefSize;
43594357
auto *D = ReadDecl(*M, Record, Idx);
43604358
ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
43614359
MostRecent = D;

clang/lib/Serialization/ASTReaderStmt.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,12 +351,14 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
351351
S->setStartLoc(readSourceLocation());
352352
S->setEndLoc(readSourceLocation());
353353

354-
if (Record.size() - Record.getIdx() == 1) {
354+
unsigned NumDecls =
355+
(Record.size() - Record.getIdx()) / serialization::DeclIDRefSize;
356+
if (NumDecls == 1) {
355357
// Single declaration
356358
S->setDeclGroup(DeclGroupRef(readDecl()));
357359
} else {
358360
SmallVector<Decl *, 16> Decls;
359-
int N = Record.size() - Record.getIdx();
361+
int N = NumDecls;
360362
Decls.reserve(N);
361363
for (int I = 0; I < N; ++I)
362364
Decls.push_back(readDecl());

0 commit comments

Comments
 (0)