@@ -1321,13 +1321,11 @@ void LazySpecializationInfoLookupTrait::ReadDataInto(internal_key_type,
1321
1321
using namespace llvm::support;
1322
1322
1323
1323
for (unsigned NumDecls =
1324
- DataLen / serialization::reader::LazySpecializationInfo::Length ;
1324
+ DataLen / sizeof( serialization::reader::LazySpecializationInfo) ;
1325
1325
NumDecls; --NumDecls) {
1326
1326
LocalDeclID LocalID =
1327
1327
LocalDeclID::get(Reader, F, endian::readNext<DeclID, llvm::endianness::little, unaligned>(d));
1328
- const bool IsPartial =
1329
- endian::readNext<bool, llvm::endianness::little, unaligned>(d);
1330
- Val.insert({Reader.getGlobalDeclID(F, LocalID), IsPartial});
1328
+ Val.insert(Reader.getGlobalDeclID(F, LocalID));
1331
1329
}
1332
1330
}
1333
1331
@@ -1420,14 +1418,15 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
1420
1418
}
1421
1419
1422
1420
void ASTReader::AddSpecializations(const Decl *D, const unsigned char *Data,
1423
- ModuleFile &M) {
1421
+ ModuleFile &M, bool IsPartial ) {
1424
1422
D = D->getCanonicalDecl();
1425
- SpecializationsLookups[D].Table.add(
1423
+ auto &SpecLookups = IsPartial ? PartialSpecializationsLookups : SpecializationsLookups;
1424
+ SpecLookups[D].Table.add(
1426
1425
&M, Data, reader::LazySpecializationInfoLookupTrait(*this, M));
1427
1426
}
1428
1427
1429
1428
bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
1430
- uint64_t Offset, Decl *D) {
1429
+ uint64_t Offset, Decl *D, bool IsPartial ) {
1431
1430
assert(Offset != 0);
1432
1431
1433
1432
SavedStreamPosition SavedPosition(Cursor);
@@ -1451,13 +1450,14 @@ bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
1451
1450
return true;
1452
1451
}
1453
1452
unsigned RecCode = MaybeRecCode.get();
1454
- if (RecCode != DECL_SPECIALIZATIONS) {
1453
+ if (RecCode != DECL_SPECIALIZATIONS &&
1454
+ RecCode != DECL_PARTIAL_SPECIALIZATIONS) {
1455
1455
Error("Expected decl specs block");
1456
1456
return true;
1457
1457
}
1458
1458
1459
1459
auto *Data = (const unsigned char *)Blob.data();
1460
- AddSpecializations(D, Data, M);
1460
+ AddSpecializations(D, Data, M, IsPartial );
1461
1461
return false;
1462
1462
}
1463
1463
@@ -3565,6 +3565,19 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
3565
3565
break;
3566
3566
}
3567
3567
3568
+ case CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION: {
3569
+ unsigned Idx = 0;
3570
+ GlobalDeclID ID = ReadDeclID(F, Record, Idx);
3571
+ auto *Data = (const unsigned char *)Blob.data();
3572
+ PendingPartialSpecializationsUpdates[ID].push_back(UpdateData{&F, Data});
3573
+ // If we've already loaded the decl, perform the updates when we finish
3574
+ // loading this block.
3575
+ if (Decl *D = GetExistingDecl(ID))
3576
+ PendingUpdateRecords.push_back(
3577
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
3578
+ break;
3579
+ }
3580
+
3568
3581
case IDENTIFIER_TABLE:
3569
3582
F.IdentifierTableData =
3570
3583
reinterpret_cast<const unsigned char *>(Blob.data());
@@ -8156,11 +8169,11 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
8156
8169
return ReadStmtFromStream(*Loc.F);
8157
8170
}
8158
8171
8159
- bool ASTReader::LoadExternalSpecializations( const Decl *D, bool OnlyPartial ) {
8172
+ bool ASTReader::LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups, const Decl *D) {
8160
8173
assert(D);
8161
8174
8162
- auto It = SpecializationsLookups .find(D);
8163
- if (It == SpecializationsLookups .end())
8175
+ auto It = SpecLookups .find(D);
8176
+ if (It == SpecLookups .end())
8164
8177
return false;
8165
8178
8166
8179
// Get Decl may violate the iterator from SpecializationsLookups so we store
@@ -8170,48 +8183,67 @@ bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8170
8183
8171
8184
// Since we've loaded all the specializations, we can erase it from
8172
8185
// the lookup table.
8173
- if (!OnlyPartial)
8174
- SpecializationsLookups.erase(It);
8186
+ SpecLookups.erase(It);
8175
8187
8176
8188
bool NewSpecsFound = false;
8177
8189
Deserializing LookupResults(this);
8178
- for (auto &Info : Infos)
8179
- if (!OnlyPartial || Info.IsPartial) {
8180
- if (GetExistingDecl(Info.ID))
8181
- continue;
8182
- NewSpecsFound = true;
8183
- GetDecl(Info.ID);
8184
- }
8190
+ for (auto &Info : Infos) {
8191
+ if (GetExistingDecl(Info))
8192
+ continue;
8193
+ NewSpecsFound = true;
8194
+ GetDecl(Info);
8195
+ }
8185
8196
8186
8197
return NewSpecsFound;
8187
8198
}
8188
8199
8189
- bool ASTReader::LoadExternalSpecializations(
8190
- const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
8200
+ bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8191
8201
assert(D);
8192
8202
8193
- auto It = SpecializationsLookups.find(D);
8194
- if (It == SpecializationsLookups.end())
8203
+ bool NewSpecsFound = LoadExternalSpecializationsImpl(PartialSpecializationsLookups, D);
8204
+ if (OnlyPartial)
8205
+ return NewSpecsFound;
8206
+
8207
+ NewSpecsFound |= LoadExternalSpecializationsImpl(SpecializationsLookups, D);
8208
+ return NewSpecsFound;
8209
+ }
8210
+
8211
+ bool ASTReader::LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups, const Decl *D,
8212
+ ArrayRef<TemplateArgument> TemplateArgs) {
8213
+ assert(D);
8214
+
8215
+ auto It = SpecLookups.find(D);
8216
+ if (It == SpecLookups.end())
8195
8217
return false;
8196
8218
8197
8219
Deserializing LookupResults(this);
8198
8220
auto HashValue = StableHashForTemplateArguments(TemplateArgs);
8199
8221
8200
- // Get Decl may violate the iterator from SpecializationsLookups
8222
+ // Get Decl may violate the iterator from SpecLookups
8201
8223
llvm::SmallVector<serialization::reader::LazySpecializationInfo, 8> Infos =
8202
8224
It->second.Table.find(HashValue);
8203
8225
8204
8226
bool NewSpecsFound = false;
8205
8227
for (auto &Info : Infos) {
8206
- if (GetExistingDecl(Info.ID ))
8228
+ if (GetExistingDecl(Info))
8207
8229
continue;
8208
8230
NewSpecsFound = true;
8209
- GetDecl(Info.ID );
8231
+ GetDecl(Info);
8210
8232
}
8211
8233
8212
8234
return NewSpecsFound;
8213
8235
}
8214
8236
8237
+ bool ASTReader::LoadExternalSpecializations(
8238
+ const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
8239
+ assert(D);
8240
+
8241
+ bool NewDeclsFound = LoadExternalSpecializationsImpl(PartialSpecializationsLookups, D, TemplateArgs);
8242
+ NewDeclsFound |= LoadExternalSpecializationsImpl(SpecializationsLookups, D, TemplateArgs);
8243
+
8244
+ return NewDeclsFound;
8245
+ }
8246
+
8215
8247
void ASTReader::FindExternalLexicalDecls(
8216
8248
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
8217
8249
SmallVectorImpl<Decl *> &Decls) {
@@ -8392,10 +8424,17 @@ ASTReader::getLoadedLookupTables(DeclContext *Primary) const {
8392
8424
}
8393
8425
8394
8426
serialization::reader::LazySpecializationInfoLookupTable *
8395
- ASTReader::getLoadedSpecializationsLookupTables(const Decl *D) {
8427
+ ASTReader::getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial) {
8428
+ assert(D->isCanonicalDecl());
8429
+ auto &LookupTable = IsPartial ? PartialSpecializationsLookups : SpecializationsLookups;
8430
+ auto I = LookupTable.find(D);
8431
+ return I == LookupTable.end() ? nullptr : &I->second;
8432
+ }
8433
+
8434
+ bool ASTReader::haveUnloadedSpecializations(const Decl *D) const {
8396
8435
assert(D->isCanonicalDecl());
8397
- auto I = SpecializationsLookups.find(D);
8398
- return I == SpecializationsLookups.end() ? nullptr : &I->second ;
8436
+ return (PartialSpecializationsLookups.find(D) != PartialSpecializationsLookups.end()) ||
8437
+ ( SpecializationsLookups.find(D) != SpecializationsLookups.end()) ;
8399
8438
}
8400
8439
8401
8440
/// Under non-PCH compilation the consumer receives the objc methods
0 commit comments