Skip to content

Commit 4836917

Browse files
authored
Merge pull request #42417 from slavapestov/serialize-primary-associated-types-5.7
Serialization: Round-trip primary associated type list [5.7]
2 parents d1a9c63 + 2479dd8 commit 4836917

File tree

14 files changed

+172
-50
lines changed

14 files changed

+172
-50
lines changed

include/swift/AST/Decl.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
527527
IsComputingSemanticMembers : 1
528528
);
529529

530-
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+1+1+8,
530+
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+8,
531531
/// Whether the \c RequiresClass bit is valid.
532532
RequiresClassValid : 1,
533533

@@ -562,6 +562,9 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
562562
/// Whether we have a lazy-loaded list of associated types.
563563
HasLazyAssociatedTypes : 1,
564564

565+
/// Whether we have a lazy-loaded list of primary associated types.
566+
HasLazyPrimaryAssociatedTypes : 1,
567+
565568
: NumPadBits,
566569

567570
/// If this is a compiler-known protocol, this will be a KnownProtocolKind
@@ -4440,6 +4443,10 @@ class ProtocolDecl final : public NominalTypeDecl {
44404443
return Bits.ProtocolDecl.HasLazyRequirementSignature;
44414444
}
44424445

4446+
bool hasLazyPrimaryAssociatedTypes() const {
4447+
return Bits.ProtocolDecl.HasLazyPrimaryAssociatedTypes;
4448+
}
4449+
44434450
friend class SuperclassDeclRequest;
44444451
friend class SuperclassTypeRequest;
44454452
friend class StructuralRequirementsRequest;
@@ -4452,6 +4459,7 @@ class ProtocolDecl final : public NominalTypeDecl {
44524459
friend class ExistentialConformsToSelfRequest;
44534460
friend class ExistentialRequiresAnyRequest;
44544461
friend class InheritedProtocolsRequest;
4462+
friend class PrimaryAssociatedTypesRequest;
44554463

44564464
public:
44574465
ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc,
@@ -4676,6 +4684,9 @@ class ProtocolDecl final : public NominalTypeDecl {
46764684
void setLazyAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
46774685
uint64_t associatedTypesData);
46784686

4687+
void setLazyPrimaryAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
4688+
uint64_t associatedTypesData);
4689+
46794690
public:
46804691
// Implement isa/cast/dyncast/etc.
46814692
static bool classof(const Decl *D) {

include/swift/AST/LazyResolver.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class LazyProtocolData : public LazyIterableDeclContextData {
6464
uint64_t requirementSignatureData = 0;
6565
/// The context data used for loading the list of associated types.
6666
uint64_t associatedTypesData = 0;
67+
/// The context data used for loading the list of primary associated types.
68+
uint64_t primaryAssociatedTypesData = 0;
6769
};
6870

6971
/// A class that can lazily load members from a serialized format.
@@ -107,6 +109,11 @@ class alignas(void*) LazyMemberLoader {
107109
loadAssociatedTypes(const ProtocolDecl *proto, uint64_t contextData,
108110
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) = 0;
109111

112+
/// Loads the primary associated types of a protocol.
113+
virtual void
114+
loadPrimaryAssociatedTypes(const ProtocolDecl *proto, uint64_t contextData,
115+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) = 0;
116+
110117
/// Returns the replaced decl for a given @_dynamicReplacement(for:) attribute.
111118
virtual ValueDecl *
112119
loadDynamicallyReplacedFunctionDecl(const DynamicReplacementAttr *DRA,

lib/AST/Decl.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5559,8 +5559,8 @@ ProtocolDecl::setLazyRequirementSignature(LazyMemberLoader *lazyLoader,
55595559
}
55605560

55615561
void
5562-
ProtocolDecl::setLazyAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
5563-
uint64_t associatedTypesData) {
5562+
ProtocolDecl::setLazyAssociatedTypeMembers(
5563+
LazyMemberLoader *lazyLoader, uint64_t associatedTypesData) {
55645564
assert(!Bits.ProtocolDecl.HasAssociatedTypes);
55655565
assert(!Bits.ProtocolDecl.HasLazyAssociatedTypes);
55665566

@@ -5570,6 +5570,17 @@ ProtocolDecl::setLazyAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
55705570
Bits.ProtocolDecl.HasLazyAssociatedTypes = true;
55715571
}
55725572

5573+
void
5574+
ProtocolDecl::setLazyPrimaryAssociatedTypeMembers(
5575+
LazyMemberLoader *lazyLoader, uint64_t associatedTypesData) {
5576+
assert(!Bits.ProtocolDecl.HasLazyPrimaryAssociatedTypes);
5577+
5578+
auto contextData = static_cast<LazyProtocolData *>(
5579+
getASTContext().getOrCreateLazyContextData(this, lazyLoader));
5580+
contextData->primaryAssociatedTypesData = associatedTypesData;
5581+
Bits.ProtocolDecl.HasLazyPrimaryAssociatedTypes = true;
5582+
}
5583+
55735584
void ProtocolDecl::computeKnownProtocolKind() const {
55745585
auto module = getModuleContext();
55755586
if (module != module->getASTContext().getStdlibModule() &&

lib/ClangImporter/ImporterImpl.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,8 +1590,15 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
15901590
llvm_unreachable("unimplemented for ClangImporter");
15911591
}
15921592

1593-
void loadAssociatedTypes(const ProtocolDecl *decl, uint64_t contextData,
1594-
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override {
1593+
void loadAssociatedTypes(
1594+
const ProtocolDecl *decl, uint64_t contextData,
1595+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override {
1596+
llvm_unreachable("unimplemented for ClangImporter");
1597+
}
1598+
1599+
void loadPrimaryAssociatedTypes(
1600+
const ProtocolDecl *decl, uint64_t contextData,
1601+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override {
15951602
llvm_unreachable("unimplemented for ClangImporter");
15961603
}
15971604

lib/Sema/TypeCheckDecl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,18 @@ ArrayRef<AssociatedTypeDecl *>
703703
PrimaryAssociatedTypesRequest::evaluate(Evaluator &evaluator,
704704
ProtocolDecl *decl) const {
705705
SmallVector<AssociatedTypeDecl *, 2> assocTypes;
706+
707+
if (decl->hasLazyPrimaryAssociatedTypes()) {
708+
auto &ctx = decl->getASTContext();
709+
auto contextData = static_cast<LazyProtocolData *>(
710+
ctx.getOrCreateLazyContextData(decl, nullptr));
711+
712+
contextData->loader->loadPrimaryAssociatedTypes(
713+
decl, contextData->primaryAssociatedTypesData, assocTypes);
714+
715+
return decl->getASTContext().AllocateCopy(assocTypes);
716+
}
717+
706718
llvm::SmallDenseSet<Identifier, 2> assocTypeNames;
707719

708720
for (auto pair : decl->getPrimaryAssociatedTypeNames()) {

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ DECL(PATTERN_BINDING)
128128
DECL(PROTOCOL)
129129
TRAILING_INFO(DEFAULT_WITNESS_TABLE)
130130
TRAILING_INFO(ASSOCIATED_TYPE)
131+
TRAILING_INFO(PRIMARY_ASSOCIATED_TYPE)
131132
DECL(PREFIX_OPERATOR)
132133
DECL(POSTFIX_OPERATOR)
133134
DECL(INFIX_OPERATOR)

lib/Serialization/Deserialization.cpp

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -991,42 +991,37 @@ void ModuleFile::readAssociatedTypes(
991991
}
992992
}
993993

994-
/// Advances past any records that might be part of a protocol requirement
995-
/// signature, which consists of generic requirements together with protocol
996-
/// typealias records.
997-
static llvm::Error skipRequirementSignature(llvm::BitstreamCursor &Cursor) {
994+
void ModuleFile::readPrimaryAssociatedTypes(
995+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
996+
llvm::BitstreamCursor &Cursor) {
998997
using namespace decls_block;
999998

1000999
BCOffsetRAII lastRecordOffset(Cursor);
1000+
SmallVector<uint64_t, 8> scratch;
1001+
StringRef blobData;
10011002

10021003
while (true) {
1003-
Expected<llvm::BitstreamEntry> maybeEntry =
1004-
Cursor.advance(AF_DontPopBlockAtEnd);
1005-
if (!maybeEntry)
1006-
return maybeEntry.takeError();
1007-
llvm::BitstreamEntry entry = maybeEntry.get();
1004+
lastRecordOffset.reset();
1005+
1006+
llvm::BitstreamEntry entry =
1007+
fatalIfUnexpected(Cursor.advance(AF_DontPopBlockAtEnd));
10081008
if (entry.Kind != llvm::BitstreamEntry::Record)
10091009
break;
10101010

1011-
Expected<unsigned> maybeRecordID = Cursor.skipRecord(entry.ID);
1012-
if (!maybeRecordID)
1013-
return maybeRecordID.takeError();
1014-
switch (maybeRecordID.get()) {
1015-
case REQUIREMENT_SIGNATURE:
1011+
scratch.clear();
1012+
unsigned recordID = fatalIfUnexpected(
1013+
Cursor.readRecord(entry.ID, scratch, &blobData));
1014+
if (recordID != PRIMARY_ASSOCIATED_TYPE)
10161015
break;
10171016

1018-
default:
1019-
// This record is not a generic requirement.
1020-
return llvm::Error::success();
1021-
}
1017+
DeclID declID;
1018+
PrimaryAssociatedTypeLayout::readRecord(scratch, declID);
10221019

1023-
lastRecordOffset.reset();
1020+
assocTypes.push_back(cast<AssociatedTypeDecl>(getDecl(declID)));
10241021
}
1025-
return llvm::Error::success();
10261022
}
10271023

1028-
/// Advances past any lazy associated type member records.
1029-
static llvm::Error skipAssociatedTypeMembers(llvm::BitstreamCursor &Cursor) {
1024+
static llvm::Error skipRecords(llvm::BitstreamCursor &Cursor, unsigned kind) {
10301025
using namespace decls_block;
10311026

10321027
BCOffsetRAII lastRecordOffset(Cursor);
@@ -1043,20 +1038,39 @@ static llvm::Error skipAssociatedTypeMembers(llvm::BitstreamCursor &Cursor) {
10431038
Expected<unsigned> maybeRecordID = Cursor.skipRecord(entry.ID);
10441039
if (!maybeRecordID)
10451040
return maybeRecordID.takeError();
1046-
switch (maybeRecordID.get()) {
1047-
case ASSOCIATED_TYPE:
1048-
break;
1049-
1050-
default:
1051-
// This record is not an associated type.
1041+
if (maybeRecordID.get() != kind)
10521042
return llvm::Error::success();
1053-
}
10541043

10551044
lastRecordOffset.reset();
10561045
}
1046+
10571047
return llvm::Error::success();
10581048
}
10591049

1050+
/// Advances past any records that might be part of a protocol requirement
1051+
/// signature, which consists of generic requirements together with protocol
1052+
/// typealias records.
1053+
static llvm::Error skipRequirementSignature(llvm::BitstreamCursor &Cursor) {
1054+
using namespace decls_block;
1055+
1056+
return skipRecords(Cursor, REQUIREMENT_SIGNATURE);
1057+
}
1058+
1059+
/// Advances past any lazy associated type member records.
1060+
static llvm::Error skipAssociatedTypeMembers(llvm::BitstreamCursor &Cursor) {
1061+
using namespace decls_block;
1062+
1063+
return skipRecords(Cursor, ASSOCIATED_TYPE);
1064+
}
1065+
1066+
/// Advances past any lazy primary associated type member records.
1067+
static llvm::Error skipPrimaryAssociatedTypeMembers(
1068+
llvm::BitstreamCursor &Cursor) {
1069+
using namespace decls_block;
1070+
1071+
return skipRecords(Cursor, PRIMARY_ASSOCIATED_TYPE);
1072+
}
1073+
10601074
GenericSignature ModuleFile::getGenericSignature(
10611075
serialization::GenericSignatureID ID) {
10621076
auto signature = getGenericSignatureChecked(ID);
@@ -3749,16 +3763,21 @@ class DeclDeserializer {
37493763
proto->setImplicit();
37503764
proto->setIsObjC(isObjC);
37513765

3752-
proto->setLazyRequirementSignature(&MF,
3753-
MF.DeclTypeCursor.GetCurrentBitNo());
3766+
proto->setLazyRequirementSignature(
3767+
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
37543768
if (llvm::Error Err = skipRequirementSignature(MF.DeclTypeCursor))
37553769
MF.fatal(std::move(Err));
37563770

3757-
proto->setLazyAssociatedTypeMembers(&MF,
3758-
MF.DeclTypeCursor.GetCurrentBitNo());
3771+
proto->setLazyAssociatedTypeMembers(
3772+
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
37593773
if (llvm::Error Err = skipAssociatedTypeMembers(MF.DeclTypeCursor))
37603774
MF.fatal(std::move(Err));
37613775

3776+
proto->setLazyPrimaryAssociatedTypeMembers(
3777+
&MF, MF.DeclTypeCursor.GetCurrentBitNo());
3778+
if (llvm::Error Err = skipPrimaryAssociatedTypeMembers(MF.DeclTypeCursor))
3779+
MF.fatal(std::move(Err));
3780+
37623781
proto->setMemberLoader(&MF, MF.DeclTypeCursor.GetCurrentBitNo());
37633782

37643783
return proto;
@@ -6987,6 +7006,14 @@ void ModuleFile::loadAssociatedTypes(const ProtocolDecl *decl,
69877006
readAssociatedTypes(assocTypes, DeclTypeCursor);
69887007
}
69897008

7009+
void ModuleFile::loadPrimaryAssociatedTypes(const ProtocolDecl *decl,
7010+
uint64_t contextData,
7011+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) {
7012+
BCOffsetRAII restoreOffset(DeclTypeCursor);
7013+
fatalIfNotSuccess(DeclTypeCursor.JumpToBit(contextData));
7014+
readPrimaryAssociatedTypes(assocTypes, DeclTypeCursor);
7015+
}
7016+
69907017
static Optional<ForeignErrorConvention::Kind>
69917018
decodeRawStableForeignErrorConventionKind(uint8_t kind) {
69927019
switch (kind) {

lib/Serialization/ModuleFile.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,14 @@ class ModuleFile
414414
llvm::BitstreamCursor &Cursor);
415415

416416
/// Read a list of associated type declarations in a protocol.
417-
void readAssociatedTypes(SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
418-
llvm::BitstreamCursor &Cursor);
417+
void readAssociatedTypes(
418+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
419+
llvm::BitstreamCursor &Cursor);
420+
421+
/// Read a list of primary associated type declarations in a protocol.
422+
void readPrimaryAssociatedTypes(
423+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
424+
llvm::BitstreamCursor &Cursor);
419425

420426
/// Populates the protocol's default witness table.
421427
///
@@ -747,8 +753,14 @@ class ModuleFile
747753
SmallVectorImpl<ProtocolTypeAlias> &typeAliases) override;
748754

749755
void
750-
loadAssociatedTypes(const ProtocolDecl *proto, uint64_t contextData,
751-
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override;
756+
loadAssociatedTypes(
757+
const ProtocolDecl *proto, uint64_t contextData,
758+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override;
759+
760+
void
761+
loadPrimaryAssociatedTypes(
762+
const ProtocolDecl *proto, uint64_t contextData,
763+
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) override;
752764

753765
Optional<StringRef> getGroupNameById(unsigned Id) const;
754766
Optional<StringRef> getSourceFileNameById(unsigned Id) const;

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 684; // Cond. available underlying types for opaque
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 685; // Primary associated types
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1657,6 +1657,11 @@ namespace decls_block {
16571657
DeclIDField // associated type decl
16581658
>;
16591659

1660+
using PrimaryAssociatedTypeLayout = BCRecordLayout<
1661+
PRIMARY_ASSOCIATED_TYPE,
1662+
DeclIDField // associated type decl
1663+
>;
1664+
16601665
/// Specifies the private discriminator string for a private declaration. This
16611666
/// identifies the declaration's original source file in some opaque way.
16621667
using PrivateDiscriminatorLayout = BCRecordLayout<

lib/Serialization/Serialization.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,8 @@ void Serializer::serializeGenericRequirements(
13961396
}
13971397
}
13981398

1399-
void Serializer::writeAssociatedTypes(ArrayRef<AssociatedTypeDecl *> assocTypes) {
1399+
void Serializer::writeAssociatedTypes(
1400+
ArrayRef<AssociatedTypeDecl *> assocTypes) {
14001401
using namespace decls_block;
14011402

14021403
auto assocTypeAbbrCode = DeclTypeAbbrCodes[AssociatedTypeLayout::Code];
@@ -1408,6 +1409,19 @@ void Serializer::writeAssociatedTypes(ArrayRef<AssociatedTypeDecl *> assocTypes)
14081409
}
14091410
}
14101411

1412+
void Serializer::writePrimaryAssociatedTypes(
1413+
ArrayRef<AssociatedTypeDecl *> assocTypes) {
1414+
using namespace decls_block;
1415+
1416+
auto assocTypeAbbrCode = DeclTypeAbbrCodes[PrimaryAssociatedTypeLayout::Code];
1417+
1418+
for (auto *assocType : assocTypes) {
1419+
PrimaryAssociatedTypeLayout::emitRecord(
1420+
Out, ScratchRecord, assocTypeAbbrCode,
1421+
addDeclRef(assocType));
1422+
}
1423+
}
1424+
14111425
void Serializer::writeRequirementSignature(
14121426
const RequirementSignature &requirementSig) {
14131427
using namespace decls_block;
@@ -3706,6 +3720,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
37063720
writeGenericParams(proto->getGenericParams());
37073721
S.writeRequirementSignature(proto->getRequirementSignature());
37083722
S.writeAssociatedTypes(proto->getAssociatedTypeMembers());
3723+
S.writePrimaryAssociatedTypes(proto->getPrimaryAssociatedTypes());
37093724
writeMembers(id, proto->getAllMembers(), true);
37103725
writeDefaultWitnessTable(proto);
37113726
}
@@ -5044,6 +5059,7 @@ void Serializer::writeAllDeclsAndTypes() {
50445059
registerDeclTypeAbbr<PatternBindingLayout>();
50455060
registerDeclTypeAbbr<ProtocolLayout>();
50465061
registerDeclTypeAbbr<AssociatedTypeLayout>();
5062+
registerDeclTypeAbbr<PrimaryAssociatedTypeLayout>();
50475063
registerDeclTypeAbbr<DefaultWitnessTableLayout>();
50485064
registerDeclTypeAbbr<PrefixOperatorLayout>();
50495065
registerDeclTypeAbbr<PostfixOperatorLayout>();

0 commit comments

Comments
 (0)