@@ -30,6 +30,38 @@ struct TargetProtocolConformanceDescriptor;
3030template <typename Runtime>
3131struct TargetGenericContext ;
3232
33+ class GenericContextDescriptorFlags {
34+ uint16_t Value;
35+
36+ public:
37+ constexpr GenericContextDescriptorFlags () : Value(0 ) {}
38+
39+ explicit constexpr GenericContextDescriptorFlags (uint16_t value)
40+ : Value(value) {}
41+
42+ constexpr GenericContextDescriptorFlags (bool hasTypePacks)
43+ : GenericContextDescriptorFlags(
44+ GenericContextDescriptorFlags ((uint16_t )0)
45+ .withHasTypePacks(hasTypePacks)) {}
46+
47+ // / Whether this generic context has at least one type parameter
48+ // / pack, in which case the generic context will have a trailing
49+ // / GenericParamPackShapeHeader.
50+ constexpr bool hasTypePacks () const {
51+ return (Value & 0x1 ) != 0 ;
52+ }
53+
54+ constexpr GenericContextDescriptorFlags
55+ withHasTypePacks (bool hasTypePacks) const {
56+ return GenericContextDescriptorFlags ((uint16_t )(
57+ (Value & ~0x1 ) | (hasTypePacks ? 0x1 : 0 )));
58+ }
59+
60+ constexpr uint16_t getIntValue () const {
61+ return Value;
62+ }
63+ };
64+
3365template <typename Runtime>
3466struct TargetGenericContextDescriptorHeader {
3567 // / The number of (source-written) generic parameters, and thus
@@ -39,8 +71,8 @@ struct TargetGenericContextDescriptorHeader {
3971 // /
4072 // / A GenericParamDescriptor corresponds to a type metadata pointer
4173 // / in the arguments layout when isKeyArgument() is true.
42- // / isKeyArgument() will be false if the parameter has been unified
43- // / unified with a different parameter or an associated type.
74+ // / isKeyArgument() will be false if the parameter has been made
75+ // / equivalent to a different parameter or a concrete type.
4476 uint16_t NumParams;
4577
4678 // / The number of GenericRequirementDescriptors in this generic
@@ -66,18 +98,22 @@ struct TargetGenericContextDescriptorHeader {
6698 // / hasKeyArgument()).
6799 uint16_t NumKeyArguments;
68100
69- // / In principle, the size of the "extra" area of the argument
101+ // / Originally this was the size of the "extra" area of the argument
70102 // / layout, in words. The idea was that extra arguments would
71103 // / include generic parameters and conformances that are not part
72104 // / of the identity of the context; however, it's unclear why we
73- // / would ever want such a thing. As a result, this section is
74- // / unused, and this field is always zero. It can be repurposed
75- // / as long as it remains zero in code which must be compatible
76- // / with existing Swift runtimes.
77- uint16_t NumExtraArguments ;
105+ // / would ever want such a thing. As a result, in pre-5.8 runtimes
106+ // / this field is always zero. New flags can only be added as long
107+ // / as they remains zero in code which must be compatible with
108+ // / older Swift runtimes.
109+ GenericContextDescriptorFlags Flags ;
78110
79111 uint32_t getNumArguments () const {
80- return NumKeyArguments + NumExtraArguments;
112+ // Note: this used to be NumKeyArguments + NumExtraArguments,
113+ // and flags was named NumExtraArguments, which is why Flags
114+ // must remain zero when backward deploying to Swift 5.7 or
115+ // earlier.
116+ return NumKeyArguments;
81117 }
82118
83119 // / Return the total size of the argument layout, in words.
@@ -163,7 +199,7 @@ class TargetGenericRequirementDescriptor {
163199 return offsetof (typename std::remove_reference<decltype (*this )>::type, Type);
164200 }
165201
166- // / Retreive the offset to the Type field
202+ // / Retreive the offset to the Param field
167203 constexpr inline auto
168204 getParamOffset () const -> typename Runtime::StoredSize {
169205 return offsetof (typename std::remove_reference<decltype (*this )>::type, Param);
@@ -199,6 +235,7 @@ class TargetGenericRequirementDescriptor {
199235 case GenericRequirementKind::Protocol:
200236 case GenericRequirementKind::SameConformance:
201237 case GenericRequirementKind::SameType:
238+ case GenericRequirementKind::SameShape:
202239 return true ;
203240 }
204241
@@ -208,6 +245,25 @@ class TargetGenericRequirementDescriptor {
208245using GenericRequirementDescriptor =
209246 TargetGenericRequirementDescriptor<InProcess>;
210247
248+ struct GenericParamPackShapeHeader {
249+ // / The number of generic parameters which are packs.
250+ // /
251+ // / Must equal the number of GenericParamDescriptors whose kind is
252+ // / GenericParamKind::TypePack.
253+ uint16_t NumTypePacks;
254+
255+ // / The number of equivalence classes in the same-shape relation.
256+ uint16_t NumShapeClasses;
257+ };
258+
259+ struct GenericParamPackShapeDescriptor {
260+ // / The equivalence class of this generic parameter pack under
261+ // / the same-shape relation.
262+ // /
263+ // / Must be less than GenericParamPackShapeHeader::NumShapeClasses.
264+ uint16_t ShapeClass;
265+ };
266+
211267// / An array of generic parameter descriptors, all
212268// / GenericParamDescriptor::implicit(), which is by far
213269// / the most common case. Some generic context storage can
@@ -243,14 +299,21 @@ class RuntimeGenericSignature {
243299 TargetGenericContextDescriptorHeader<Runtime> Header;
244300 const GenericParamDescriptor *Params;
245301 const TargetGenericRequirementDescriptor<Runtime> *Requirements;
302+ GenericParamPackShapeHeader PackShapeHeader;
303+ const GenericParamPackShapeDescriptor *PackShapeDescriptors;
304+
246305public:
247306 RuntimeGenericSignature ()
248- : Header{0 , 0 , 0 , 0 }, Params(nullptr ), Requirements(nullptr ) {}
307+ : Header{0 , 0 , 0 , 0 }, Params(nullptr ), Requirements(nullptr ),
308+ PackShapeHeader{0 , 0 }, PackShapeDescriptors(nullptr ) {}
249309
250310 RuntimeGenericSignature (const TargetGenericContextDescriptorHeader<Runtime> &header,
251311 const GenericParamDescriptor *params,
252- const TargetGenericRequirementDescriptor<Runtime> *requirements)
253- : Header(header), Params(params), Requirements(requirements) {}
312+ const TargetGenericRequirementDescriptor<Runtime> *requirements,
313+ const GenericParamPackShapeHeader &packShapeHeader,
314+ const GenericParamPackShapeDescriptor *packShapeDescriptors)
315+ : Header(header), Params(params), Requirements(requirements),
316+ PackShapeHeader (packShapeHeader), PackShapeDescriptors(packShapeDescriptors) {}
254317
255318 llvm::ArrayRef<GenericParamDescriptor> getParams () const {
256319 return llvm::makeArrayRef (Params, Header.NumParams );
@@ -260,6 +323,10 @@ class RuntimeGenericSignature {
260323 return llvm::makeArrayRef (Requirements, Header.NumRequirements );
261324 }
262325
326+ llvm::ArrayRef<GenericParamPackShapeDescriptor> getPackShapeDescriptors () const {
327+ return llvm::makeArrayRef (PackShapeDescriptors, PackShapeHeader.NumTypePacks );
328+ }
329+
263330 size_t getArgumentLayoutSizeInWords () const {
264331 return Header.getArgumentLayoutSizeInWords ();
265332 }
@@ -350,6 +417,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
350417 TargetGenericContextHeaderType<Runtime>,
351418 GenericParamDescriptor,
352419 TargetGenericRequirementDescriptor<Runtime>,
420+ GenericParamPackShapeHeader,
421+ GenericParamPackShapeDescriptor,
353422 FollowingTrailingObjects...>
354423{
355424protected:
@@ -362,6 +431,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
362431 GenericContextHeaderType,
363432 GenericParamDescriptor,
364433 GenericRequirementDescriptor,
434+ GenericParamPackShapeHeader,
435+ GenericParamPackShapeDescriptor,
365436 FollowingTrailingObjects...>;
366437 friend TrailingObjects;
367438
@@ -415,6 +486,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
415486 return {this ->template getTrailingObjects <GenericRequirementDescriptor>(),
416487 getGenericContextHeader ().NumRequirements };
417488 }
489+
490+ GenericParamPackShapeHeader getGenericParamPackShapeHeader () const {
491+ if (!asSelf ()->isGeneric ())
492+ return {0 , 0 };
493+ if (!getGenericContextHeader ().Flags .hasTypePacks ())
494+ return {0 , 0 };
495+ return *this ->template getTrailingObjects <GenericParamPackShapeHeader>();
496+ }
497+
498+ llvm::ArrayRef<GenericParamPackShapeDescriptor> getGenericParamPackShapeDescriptors () const {
499+ auto header = getGenericParamPackShapeHeader ();
500+ if (header.NumTypePacks == 0 )
501+ return {};
502+
503+ return {this ->template getTrailingObjects <GenericParamPackShapeDescriptor>(),
504+ header.NumTypePacks };
505+ }
418506
419507 // / Return the amount of space that the generic arguments take up in
420508 // / metadata of this type.
@@ -427,7 +515,9 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
427515 if (!asSelf ()->isGeneric ()) return RuntimeGenericSignature<Runtime>();
428516 return {getGenericContextHeader (),
429517 getGenericParams ().data (),
430- getGenericRequirements ().data ()};
518+ getGenericRequirements ().data (),
519+ getGenericParamPackShapeHeader (),
520+ getGenericParamPackShapeDescriptors ().data ()};
431521 }
432522
433523protected:
@@ -443,6 +533,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
443533 return asSelf ()->isGeneric () ? getGenericContextHeader ().NumRequirements : 0 ;
444534 }
445535
536+ size_t numTrailingObjects (OverloadToken<GenericParamPackShapeHeader>) const {
537+ if (!asSelf ()->isGeneric ())
538+ return 0 ;
539+
540+ return getGenericContextHeader ().Flags .hasTypePacks () ? 1 : 0 ;
541+ }
542+
543+ size_t numTrailingObjects (OverloadToken<GenericParamPackShapeDescriptor>) const {
544+ if (!asSelf ()->isGeneric ())
545+ return 0 ;
546+
547+ if (!getGenericContextHeader ().Flags .hasTypePacks ())
548+ return 0 ;
549+
550+ return getGenericParamPackShapeHeader ().NumTypePacks ;
551+ }
552+
446553#if defined(_MSC_VER) && _MSC_VER < 1920
447554#undef OverloadToken
448555#endif
0 commit comments