@@ -30,6 +30,38 @@ struct TargetProtocolConformanceDescriptor;
30
30
template <typename Runtime>
31
31
struct TargetGenericContext ;
32
32
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
+
33
65
template <typename Runtime>
34
66
struct TargetGenericContextDescriptorHeader {
35
67
// / The number of (source-written) generic parameters, and thus
@@ -39,8 +71,8 @@ struct TargetGenericContextDescriptorHeader {
39
71
// /
40
72
// / A GenericParamDescriptor corresponds to a type metadata pointer
41
73
// / 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.
44
76
uint16_t NumParams;
45
77
46
78
// / The number of GenericRequirementDescriptors in this generic
@@ -66,18 +98,22 @@ struct TargetGenericContextDescriptorHeader {
66
98
// / hasKeyArgument()).
67
99
uint16_t NumKeyArguments;
68
100
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
70
102
// / layout, in words. The idea was that extra arguments would
71
103
// / include generic parameters and conformances that are not part
72
104
// / 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 ;
78
110
79
111
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;
81
117
}
82
118
83
119
// / Return the total size of the argument layout, in words.
@@ -163,7 +199,7 @@ class TargetGenericRequirementDescriptor {
163
199
return offsetof (typename std::remove_reference<decltype (*this )>::type, Type);
164
200
}
165
201
166
- // / Retreive the offset to the Type field
202
+ // / Retreive the offset to the Param field
167
203
constexpr inline auto
168
204
getParamOffset () const -> typename Runtime::StoredSize {
169
205
return offsetof (typename std::remove_reference<decltype (*this )>::type, Param);
@@ -199,6 +235,7 @@ class TargetGenericRequirementDescriptor {
199
235
case GenericRequirementKind::Protocol:
200
236
case GenericRequirementKind::SameConformance:
201
237
case GenericRequirementKind::SameType:
238
+ case GenericRequirementKind::SameShape:
202
239
return true ;
203
240
}
204
241
@@ -208,6 +245,25 @@ class TargetGenericRequirementDescriptor {
208
245
using GenericRequirementDescriptor =
209
246
TargetGenericRequirementDescriptor<InProcess>;
210
247
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
+
211
267
// / An array of generic parameter descriptors, all
212
268
// / GenericParamDescriptor::implicit(), which is by far
213
269
// / the most common case. Some generic context storage can
@@ -243,14 +299,21 @@ class RuntimeGenericSignature {
243
299
TargetGenericContextDescriptorHeader<Runtime> Header;
244
300
const GenericParamDescriptor *Params;
245
301
const TargetGenericRequirementDescriptor<Runtime> *Requirements;
302
+ GenericParamPackShapeHeader PackShapeHeader;
303
+ const GenericParamPackShapeDescriptor *PackShapeDescriptors;
304
+
246
305
public:
247
306
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 ) {}
249
309
250
310
RuntimeGenericSignature (const TargetGenericContextDescriptorHeader<Runtime> &header,
251
311
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) {}
254
317
255
318
llvm::ArrayRef<GenericParamDescriptor> getParams () const {
256
319
return llvm::makeArrayRef (Params, Header.NumParams );
@@ -260,6 +323,10 @@ class RuntimeGenericSignature {
260
323
return llvm::makeArrayRef (Requirements, Header.NumRequirements );
261
324
}
262
325
326
+ llvm::ArrayRef<GenericParamPackShapeDescriptor> getPackShapeDescriptors () const {
327
+ return llvm::makeArrayRef (PackShapeDescriptors, PackShapeHeader.NumTypePacks );
328
+ }
329
+
263
330
size_t getArgumentLayoutSizeInWords () const {
264
331
return Header.getArgumentLayoutSizeInWords ();
265
332
}
@@ -350,6 +417,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
350
417
TargetGenericContextHeaderType<Runtime>,
351
418
GenericParamDescriptor,
352
419
TargetGenericRequirementDescriptor<Runtime>,
420
+ GenericParamPackShapeHeader,
421
+ GenericParamPackShapeDescriptor,
353
422
FollowingTrailingObjects...>
354
423
{
355
424
protected:
@@ -362,6 +431,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
362
431
GenericContextHeaderType,
363
432
GenericParamDescriptor,
364
433
GenericRequirementDescriptor,
434
+ GenericParamPackShapeHeader,
435
+ GenericParamPackShapeDescriptor,
365
436
FollowingTrailingObjects...>;
366
437
friend TrailingObjects;
367
438
@@ -415,6 +486,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
415
486
return {this ->template getTrailingObjects <GenericRequirementDescriptor>(),
416
487
getGenericContextHeader ().NumRequirements };
417
488
}
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
+ }
418
506
419
507
// / Return the amount of space that the generic arguments take up in
420
508
// / metadata of this type.
@@ -427,7 +515,9 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
427
515
if (!asSelf ()->isGeneric ()) return RuntimeGenericSignature<Runtime>();
428
516
return {getGenericContextHeader (),
429
517
getGenericParams ().data (),
430
- getGenericRequirements ().data ()};
518
+ getGenericRequirements ().data (),
519
+ getGenericParamPackShapeHeader (),
520
+ getGenericParamPackShapeDescriptors ().data ()};
431
521
}
432
522
433
523
protected:
@@ -443,6 +533,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
443
533
return asSelf ()->isGeneric () ? getGenericContextHeader ().NumRequirements : 0 ;
444
534
}
445
535
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
+
446
553
#if defined(_MSC_VER) && _MSC_VER < 1920
447
554
#undef OverloadToken
448
555
#endif
0 commit comments