@@ -1311,13 +1311,11 @@ void LazySpecializationInfoLookupTrait::ReadDataInto(internal_key_type,
1311
1311
using namespace llvm::support;
1312
1312
1313
1313
for (unsigned NumDecls =
1314
- DataLen / serialization::reader::LazySpecializationInfo::Length ;
1314
+ DataLen / sizeof( serialization::reader::LazySpecializationInfo) ;
1315
1315
NumDecls; --NumDecls) {
1316
1316
LocalDeclID LocalID =
1317
1317
LocalDeclID::get(Reader, F, endian::readNext<DeclID, llvm::endianness::little, unaligned>(d));
1318
- const bool IsPartial =
1319
- endian::readNext<bool, llvm::endianness::little, unaligned>(d);
1320
- Val.insert({Reader.getGlobalDeclID(F, LocalID), IsPartial});
1318
+ Val.insert(Reader.getGlobalDeclID(F, LocalID));
1321
1319
}
1322
1320
}
1323
1321
@@ -1410,14 +1408,16 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
1410
1408
}
1411
1409
1412
1410
void ASTReader::AddSpecializations(const Decl *D, const unsigned char *Data,
1413
- ModuleFile &M) {
1411
+ ModuleFile &M, bool IsPartial ) {
1414
1412
D = D->getCanonicalDecl();
1415
- SpecializationsLookups[D].Table.add(
1416
- &M, Data, reader::LazySpecializationInfoLookupTrait(*this, M));
1413
+ auto &SpecLookups =
1414
+ IsPartial ? PartialSpecializationsLookups : SpecializationsLookups;
1415
+ SpecLookups[D].Table.add(&M, Data,
1416
+ reader::LazySpecializationInfoLookupTrait(*this, M));
1417
1417
}
1418
1418
1419
1419
bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
1420
- uint64_t Offset, Decl *D) {
1420
+ uint64_t Offset, Decl *D, bool IsPartial ) {
1421
1421
assert(Offset != 0);
1422
1422
1423
1423
SavedStreamPosition SavedPosition(Cursor);
@@ -1441,13 +1441,14 @@ bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
1441
1441
return true;
1442
1442
}
1443
1443
unsigned RecCode = MaybeRecCode.get();
1444
- if (RecCode != DECL_SPECIALIZATIONS) {
1444
+ if (RecCode != DECL_SPECIALIZATIONS &&
1445
+ RecCode != DECL_PARTIAL_SPECIALIZATIONS) {
1445
1446
Error("Expected decl specs block");
1446
1447
return true;
1447
1448
}
1448
1449
1449
1450
auto *Data = (const unsigned char *)Blob.data();
1450
- AddSpecializations(D, Data, M);
1451
+ AddSpecializations(D, Data, M, IsPartial );
1451
1452
return false;
1452
1453
}
1453
1454
@@ -3556,6 +3557,19 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
3556
3557
break;
3557
3558
}
3558
3559
3560
+ case CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION: {
3561
+ unsigned Idx = 0;
3562
+ GlobalDeclID ID = ReadDeclID(F, Record, Idx);
3563
+ auto *Data = (const unsigned char *)Blob.data();
3564
+ PendingPartialSpecializationsUpdates[ID].push_back(UpdateData{&F, Data});
3565
+ // If we've already loaded the decl, perform the updates when we finish
3566
+ // loading this block.
3567
+ if (Decl *D = GetExistingDecl(ID))
3568
+ PendingUpdateRecords.push_back(
3569
+ PendingUpdateRecord(ID, D, /*JustLoaded=*/false));
3570
+ break;
3571
+ }
3572
+
3559
3573
case IDENTIFIER_TABLE:
3560
3574
F.IdentifierTableData =
3561
3575
reinterpret_cast<const unsigned char *>(Blob.data());
@@ -8136,11 +8150,12 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
8136
8150
return ReadStmtFromStream(*Loc.F);
8137
8151
}
8138
8152
8139
- bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8153
+ bool ASTReader::LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups,
8154
+ const Decl *D) {
8140
8155
assert(D);
8141
8156
8142
- auto It = SpecializationsLookups .find(D);
8143
- if (It == SpecializationsLookups .end())
8157
+ auto It = SpecLookups .find(D);
8158
+ if (It == SpecLookups .end())
8144
8159
return false;
8145
8160
8146
8161
// Get Decl may violate the iterator from SpecializationsLookups so we store
@@ -8150,48 +8165,71 @@ bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8150
8165
8151
8166
// Since we've loaded all the specializations, we can erase it from
8152
8167
// the lookup table.
8153
- if (!OnlyPartial)
8154
- SpecializationsLookups.erase(It);
8168
+ SpecLookups.erase(It);
8155
8169
8156
8170
bool NewSpecsFound = false;
8157
8171
Deserializing LookupResults(this);
8158
- for (auto &Info : Infos)
8159
- if (!OnlyPartial || Info.IsPartial) {
8160
- if (GetExistingDecl(Info.ID))
8161
- continue;
8162
- NewSpecsFound = true;
8163
- GetDecl(Info.ID);
8164
- }
8172
+ for (auto &Info : Infos) {
8173
+ if (GetExistingDecl(Info))
8174
+ continue;
8175
+ NewSpecsFound = true;
8176
+ GetDecl(Info);
8177
+ }
8165
8178
8166
8179
return NewSpecsFound;
8167
8180
}
8168
8181
8169
- bool ASTReader::LoadExternalSpecializations(
8170
- const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
8182
+ bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
8171
8183
assert(D);
8172
8184
8173
- auto It = SpecializationsLookups.find(D);
8174
- if (It == SpecializationsLookups.end())
8185
+ bool NewSpecsFound =
8186
+ LoadExternalSpecializationsImpl(PartialSpecializationsLookups, D);
8187
+ if (OnlyPartial)
8188
+ return NewSpecsFound;
8189
+
8190
+ NewSpecsFound |= LoadExternalSpecializationsImpl(SpecializationsLookups, D);
8191
+ return NewSpecsFound;
8192
+ }
8193
+
8194
+ bool ASTReader::LoadExternalSpecializationsImpl(
8195
+ SpecLookupTableTy &SpecLookups, const Decl *D,
8196
+ ArrayRef<TemplateArgument> TemplateArgs) {
8197
+ assert(D);
8198
+
8199
+ auto It = SpecLookups.find(D);
8200
+ if (It == SpecLookups.end())
8175
8201
return false;
8176
8202
8177
8203
Deserializing LookupResults(this);
8178
8204
auto HashValue = StableHashForTemplateArguments(TemplateArgs);
8179
8205
8180
- // Get Decl may violate the iterator from SpecializationsLookups
8206
+ // Get Decl may violate the iterator from SpecLookups
8181
8207
llvm::SmallVector<serialization::reader::LazySpecializationInfo, 8> Infos =
8182
8208
It->second.Table.find(HashValue);
8183
8209
8184
8210
bool NewSpecsFound = false;
8185
8211
for (auto &Info : Infos) {
8186
- if (GetExistingDecl(Info.ID ))
8212
+ if (GetExistingDecl(Info))
8187
8213
continue;
8188
8214
NewSpecsFound = true;
8189
- GetDecl(Info.ID );
8215
+ GetDecl(Info);
8190
8216
}
8191
8217
8192
8218
return NewSpecsFound;
8193
8219
}
8194
8220
8221
+ bool ASTReader::LoadExternalSpecializations(
8222
+ const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
8223
+ assert(D);
8224
+
8225
+ bool NewDeclsFound = LoadExternalSpecializationsImpl(
8226
+ PartialSpecializationsLookups, D, TemplateArgs);
8227
+ NewDeclsFound |=
8228
+ LoadExternalSpecializationsImpl(SpecializationsLookups, D, TemplateArgs);
8229
+
8230
+ return NewDeclsFound;
8231
+ }
8232
+
8195
8233
void ASTReader::FindExternalLexicalDecls(
8196
8234
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
8197
8235
SmallVectorImpl<Decl *> &Decls) {
@@ -8372,10 +8410,19 @@ ASTReader::getLoadedLookupTables(DeclContext *Primary) const {
8372
8410
}
8373
8411
8374
8412
serialization::reader::LazySpecializationInfoLookupTable *
8375
- ASTReader::getLoadedSpecializationsLookupTables(const Decl *D) {
8413
+ ASTReader::getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial) {
8414
+ assert(D->isCanonicalDecl());
8415
+ auto &LookupTable =
8416
+ IsPartial ? PartialSpecializationsLookups : SpecializationsLookups;
8417
+ auto I = LookupTable.find(D);
8418
+ return I == LookupTable.end() ? nullptr : &I->second;
8419
+ }
8420
+
8421
+ bool ASTReader::haveUnloadedSpecializations(const Decl *D) const {
8376
8422
assert(D->isCanonicalDecl());
8377
- auto I = SpecializationsLookups.find(D);
8378
- return I == SpecializationsLookups.end() ? nullptr : &I->second;
8423
+ return (PartialSpecializationsLookups.find(D) !=
8424
+ PartialSpecializationsLookups.end()) ||
8425
+ (SpecializationsLookups.find(D) != SpecializationsLookups.end());
8379
8426
}
8380
8427
8381
8428
/// Under non-PCH compilation the consumer receives the objc methods
0 commit comments