@@ -1311,13 +1311,11 @@ void LazySpecializationInfoLookupTrait::ReadDataInto(internal_key_type,
13111311 using namespace llvm ::support;
13121312
13131313 for (unsigned NumDecls =
1314- DataLen / serialization::reader::LazySpecializationInfo::Length ;
1314+ DataLen / sizeof ( serialization::reader::LazySpecializationInfo) ;
13151315 NumDecls; --NumDecls) {
13161316 LocalDeclID LocalID =
13171317 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));
13211319 }
13221320}
13231321
@@ -1410,14 +1408,16 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M,
14101408}
14111409
14121410void ASTReader::AddSpecializations (const Decl *D, const unsigned char *Data,
1413- ModuleFile &M) {
1411+ ModuleFile &M, bool IsPartial ) {
14141412 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));
14171417}
14181418
14191419bool ASTReader::ReadSpecializations (ModuleFile &M, BitstreamCursor &Cursor,
1420- uint64_t Offset, Decl *D) {
1420+ uint64_t Offset, Decl *D, bool IsPartial ) {
14211421 assert (Offset != 0 );
14221422
14231423 SavedStreamPosition SavedPosition (Cursor);
@@ -1441,13 +1441,14 @@ bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor,
14411441 return true ;
14421442 }
14431443 unsigned RecCode = MaybeRecCode.get ();
1444- if (RecCode != DECL_SPECIALIZATIONS) {
1444+ if (RecCode != DECL_SPECIALIZATIONS &&
1445+ RecCode != DECL_PARTIAL_SPECIALIZATIONS) {
14451446 Error (" Expected decl specs block" );
14461447 return true ;
14471448 }
14481449
14491450 auto *Data = (const unsigned char *)Blob.data ();
1450- AddSpecializations (D, Data, M);
1451+ AddSpecializations (D, Data, M, IsPartial );
14511452 return false ;
14521453}
14531454
@@ -3556,6 +3557,19 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
35563557 break ;
35573558 }
35583559
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+
35593573 case IDENTIFIER_TABLE:
35603574 F.IdentifierTableData =
35613575 reinterpret_cast <const unsigned char *>(Blob.data ());
@@ -8136,11 +8150,12 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
81368150 return ReadStmtFromStream (*Loc.F );
81378151}
81388152
8139- bool ASTReader::LoadExternalSpecializations (const Decl *D, bool OnlyPartial) {
8153+ bool ASTReader::LoadExternalSpecializationsImpl (SpecLookupTableTy &SpecLookups,
8154+ const Decl *D) {
81408155 assert (D);
81418156
8142- auto It = SpecializationsLookups .find (D);
8143- if (It == SpecializationsLookups .end ())
8157+ auto It = SpecLookups .find (D);
8158+ if (It == SpecLookups .end ())
81448159 return false ;
81458160
81468161 // Get Decl may violate the iterator from SpecializationsLookups so we store
@@ -8150,48 +8165,71 @@ bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) {
81508165
81518166 // Since we've loaded all the specializations, we can erase it from
81528167 // the lookup table.
8153- if (!OnlyPartial)
8154- SpecializationsLookups.erase (It);
8168+ SpecLookups.erase (It);
81558169
81568170 bool NewSpecsFound = false ;
81578171 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+ }
81658178
81668179 return NewSpecsFound;
81678180}
81688181
8169- bool ASTReader::LoadExternalSpecializations (
8170- const Decl *D, ArrayRef<TemplateArgument> TemplateArgs) {
8182+ bool ASTReader::LoadExternalSpecializations (const Decl *D, bool OnlyPartial) {
81718183 assert (D);
81728184
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 ())
81758201 return false ;
81768202
81778203 Deserializing LookupResults (this );
81788204 auto HashValue = StableHashForTemplateArguments (TemplateArgs);
81798205
8180- // Get Decl may violate the iterator from SpecializationsLookups
8206+ // Get Decl may violate the iterator from SpecLookups
81818207 llvm::SmallVector<serialization::reader::LazySpecializationInfo, 8 > Infos =
81828208 It->second .Table .find (HashValue);
81838209
81848210 bool NewSpecsFound = false ;
81858211 for (auto &Info : Infos) {
8186- if (GetExistingDecl (Info. ID ))
8212+ if (GetExistingDecl (Info))
81878213 continue ;
81888214 NewSpecsFound = true ;
8189- GetDecl (Info. ID );
8215+ GetDecl (Info);
81908216 }
81918217
81928218 return NewSpecsFound;
81938219}
81948220
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+
81958233void ASTReader::FindExternalLexicalDecls (
81968234 const DeclContext *DC, llvm::function_ref<bool (Decl::Kind)> IsKindWeWant,
81978235 SmallVectorImpl<Decl *> &Decls) {
@@ -8372,10 +8410,19 @@ ASTReader::getLoadedLookupTables(DeclContext *Primary) const {
83728410}
83738411
83748412serialization::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 {
83768422 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 ());
83798426}
83808427
83818428// / Under non-PCH compilation the consumer receives the objc methods
0 commit comments