Skip to content

Commit 480a917

Browse files
committed
Runtime: Sketch out metadata for variadic generic types
1 parent 2d15d1c commit 480a917

File tree

4 files changed

+91
-7
lines changed

4 files changed

+91
-7
lines changed

include/swift/ABI/GenericContext.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,25 @@ class TargetGenericRequirementDescriptor {
244244
using GenericRequirementDescriptor =
245245
TargetGenericRequirementDescriptor<InProcess>;
246246

247+
struct GenericParamPackShapeHeader {
248+
/// The number of generic parameters which are packs.
249+
///
250+
/// Must equal the number of GenericParamDescriptors whose kind is
251+
/// GenericParamKind::TypePack.
252+
uint16_t NumTypePacks;
253+
254+
/// The number of equivalence classes in the same-shape relation.
255+
uint16_t NumShapeClasses;
256+
};
257+
258+
struct GenericParamPackShapeDescriptor {
259+
/// The equivalence class of this generic parameter pack under
260+
/// the same-shape relation.
261+
///
262+
/// Must be less than GenericParamPackShapeHeader::NumShapeClasses.
263+
uint16_t ShapeClass;
264+
};
265+
247266
/// An array of generic parameter descriptors, all
248267
/// GenericParamDescriptor::implicit(), which is by far
249268
/// the most common case. Some generic context storage can
@@ -386,6 +405,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
386405
TargetGenericContextHeaderType<Runtime>,
387406
GenericParamDescriptor,
388407
TargetGenericRequirementDescriptor<Runtime>,
408+
GenericParamPackShapeHeader,
409+
GenericParamPackShapeDescriptor,
389410
FollowingTrailingObjects...>
390411
{
391412
protected:
@@ -398,6 +419,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
398419
GenericContextHeaderType,
399420
GenericParamDescriptor,
400421
GenericRequirementDescriptor,
422+
GenericParamPackShapeHeader,
423+
GenericParamPackShapeDescriptor,
401424
FollowingTrailingObjects...>;
402425
friend TrailingObjects;
403426

@@ -451,6 +474,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
451474
return {this->template getTrailingObjects<GenericRequirementDescriptor>(),
452475
getGenericContextHeader().NumRequirements};
453476
}
477+
478+
const GenericParamPackShapeHeader *getGenericParamPackShapeHeader() const {
479+
if (!asSelf()->isGeneric())
480+
return nullptr;
481+
if (!getGenericContextHeader().Flags.hasTypePacks())
482+
return nullptr;
483+
return this->template getTrailingObjects<GenericParamPackShapeHeader>();
484+
}
485+
486+
llvm::ArrayRef<GenericParamPackShapeDescriptor> getGenericParamPackShapeDescriptors() const {
487+
auto *header = getGenericParamPackShapeHeader();
488+
if (header == nullptr)
489+
return {};
490+
491+
return {this->template getTrailingObjects<GenericParamPackShapeDescriptor>(),
492+
header->NumTypePacks};
493+
}
454494

455495
/// Return the amount of space that the generic arguments take up in
456496
/// metadata of this type.
@@ -479,6 +519,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
479519
return asSelf()->isGeneric() ? getGenericContextHeader().NumRequirements : 0;
480520
}
481521

522+
size_t numTrailingObjects(OverloadToken<GenericParamPackShapeHeader>) const {
523+
if (!asSelf()->isGeneric())
524+
return 0;
525+
526+
return getGenericContextHeader().Flags.hasTypePacks() ? 1 : 0;
527+
}
528+
529+
size_t numTrailingObjects(OverloadToken<GenericParamPackShapeDescriptor>) const {
530+
if (!asSelf()->isGeneric())
531+
return 0;
532+
533+
if (!getGenericContextHeader().Flags.hasTypePacks())
534+
return 0;
535+
536+
return getGenericParamPackShapeHeader()->NumTypePacks;
537+
}
538+
482539
#if defined(_MSC_VER) && _MSC_VER < 1920
483540
#undef OverloadToken
484541
#endif

include/swift/ABI/MetadataValues.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,9 @@ enum class GenericParamKind : uint8_t {
17931793
/// A type parameter.
17941794
Type = 0,
17951795

1796+
/// A type parameter pack.
1797+
TypePack = 1,
1798+
17961799
Max = 0x3F,
17971800
};
17981801

@@ -1899,11 +1902,13 @@ class GenericRequirementFlags {
18991902
public:
19001903
constexpr GenericRequirementFlags(GenericRequirementKind kind,
19011904
bool hasKeyArgument,
1902-
bool hasExtraArgument)
1905+
bool hasExtraArgument,
1906+
bool isPackRequirement)
19031907
: GenericRequirementFlags(GenericRequirementFlags(0)
19041908
.withKind(kind)
19051909
.withKeyArgument(hasKeyArgument)
1906-
.withExtraArgument(hasExtraArgument))
1910+
.withExtraArgument(hasExtraArgument)
1911+
.withPackRequirement(isPackRequirement))
19071912
{}
19081913

19091914
constexpr bool hasKeyArgument() const {
@@ -1914,6 +1919,13 @@ class GenericRequirementFlags {
19141919
return (Value & 0x40u) != 0;
19151920
}
19161921

1922+
/// If this is true, the subject type of the requirement is a pack.
1923+
/// When the requirement is a conformance requirement, the corresponding
1924+
/// entry in the generic arguments array becomes a TargetWitnessTablePack.
1925+
constexpr bool isPackRequirement() const {
1926+
return (Value & 0x20u) != 0;
1927+
}
1928+
19171929
constexpr GenericRequirementKind getKind() const {
19181930
return GenericRequirementKind(Value & 0x1Fu);
19191931
}
@@ -1930,6 +1942,12 @@ class GenericRequirementFlags {
19301942
| (hasExtraArgument ? 0x40u : 0));
19311943
}
19321944

1945+
constexpr GenericRequirementFlags
1946+
withPackRequirement(bool isPackRequirement) const {
1947+
return GenericRequirementFlags((Value & 0xBFu)
1948+
| (isPackRequirement ? 0x20u : 0));
1949+
}
1950+
19331951
constexpr GenericRequirementFlags
19341952
withKind(GenericRequirementKind kind) const {
19351953
return assert((uint8_t(kind) & 0x1Fu) == uint8_t(kind)),

lib/IRGen/GenMeta.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6126,6 +6126,8 @@ GenericRequirementsMetadata irgen::addGenericRequirements(
61266126
assert(sig);
61276127
GenericRequirementsMetadata metadata;
61286128
for (auto &requirement : requirements) {
6129+
bool isPackRequirement = requirement.getFirstType()->isParameterPack();
6130+
61296131
switch (auto kind = requirement.getKind()) {
61306132
case RequirementKind::SameShape:
61316133
llvm_unreachable("Same-shape requirement not supported here");
@@ -6139,7 +6141,8 @@ GenericRequirementsMetadata irgen::addGenericRequirements(
61396141
// Encode the class constraint.
61406142
auto flags = GenericRequirementFlags(GenericRequirementKind::Layout,
61416143
/*key argument*/ false,
6142-
/*extra argument*/ false);
6144+
/*extra argument*/ false,
6145+
isPackRequirement);
61436146
addGenericRequirement(IGM, B, metadata, sig, flags,
61446147
requirement.getFirstType(),
61456148
[&]{ B.addInt32((uint32_t)GenericRequirementLayoutKind::Class); });
@@ -6165,7 +6168,8 @@ GenericRequirementsMetadata irgen::addGenericRequirements(
61656168
Lowering::TypeConverter::protocolRequiresWitnessTable(protocol);
61666169
auto flags = GenericRequirementFlags(GenericRequirementKind::Protocol,
61676170
/*key argument*/needsWitnessTable,
6168-
/*extra argument*/false);
6171+
/*extra argument*/false,
6172+
isPackRequirement);
61696173
auto descriptorRef =
61706174
IGM.getConstantReferenceForProtocolDescriptor(protocol);
61716175
addGenericRequirement(IGM, B, metadata, sig, flags,
@@ -6189,7 +6193,10 @@ GenericRequirementsMetadata irgen::addGenericRequirements(
61896193
? GenericRequirementKind::SameType
61906194
: GenericRequirementKind::BaseClass;
61916195

6192-
auto flags = GenericRequirementFlags(abiKind, false, false);
6196+
auto flags = GenericRequirementFlags(abiKind,
6197+
/*key argument*/false,
6198+
/*extra argument*/false,
6199+
isPackRequirement);
61936200
auto typeName =
61946201
IGM.getTypeRef(requirement.getSecondType(), nullptr,
61956202
MangledTypeRefRole::Metadata).first;

unittests/runtime/SpecifierDSL.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ inline void addSameTypeRequirement(AnyObjectBuilder &builder,
310310
ObjectRef<const char> type2) {
311311
auto flags = GenericRequirementFlags(GenericRequirementKind::SameType,
312312
/*key argument*/ false,
313-
/*extra argument*/ false);
313+
/*extra argument*/ false,
314+
/*is pack requirement*/ false);
314315
builder.add32(flags.getIntValue());
315316
builder.addRelativeReference(type1);
316317
builder.addRelativeReference(type2);
@@ -331,7 +332,8 @@ inline void addConformanceRequirement(AnyObjectBuilder &builder,
331332
bool isKeyArgument = true) {
332333
auto flags = GenericRequirementFlags(GenericRequirementKind::Protocol,
333334
isKeyArgument,
334-
/*extra argument*/ false);
335+
/*extra argument*/ false,
336+
/*is pack requirement*/ false);
335337
builder.add32(flags.getIntValue());
336338
builder.addRelativeReference(type);
337339
addProtocolDescriptorRef(builder, protocol);

0 commit comments

Comments
 (0)