21
21
#include " swift/ABI/TargetLayout.h"
22
22
#include " swift/ABI/MetadataValues.h"
23
23
#include " swift/ABI/MetadataRef.h"
24
+ #include " swift/ABI/SuppressibleProtocols.h"
24
25
#include " swift/ABI/TrailingObjects.h"
25
26
#include " swift/Demangling/Demangle.h"
26
27
@@ -103,6 +104,10 @@ struct TargetGenericContextDescriptorHeader {
103
104
bool hasArguments () const {
104
105
return getNumArguments () > 0 ;
105
106
}
107
+
108
+ bool hasConditionalSuppressedProtocols () const {
109
+ return Flags.hasConditionalSuppressedProtocols ();
110
+ }
106
111
};
107
112
using GenericContextDescriptorHeader =
108
113
TargetGenericContextDescriptorHeader<InProcess>;
@@ -137,6 +142,20 @@ class TargetGenericRequirementDescriptor {
137
142
// /
138
143
// / Only valid if the requirement has Layout kind.
139
144
GenericRequirementLayoutKind Layout;
145
+
146
+ // / The set of suppressible protocols whose check is suppressed, along
147
+ // / with the index of the generic parameter being suppressed.
148
+ // /
149
+ // / The index is technically redundant with the subject type, but its
150
+ // / storage is effectively free because this union is 32 bits anyway. The
151
+ // / index 0xFFFF is reserved for "not a generic parameter", in case we
152
+ // / need to use that in the future.
153
+ // /
154
+ // / Only valid if the requirement has SuppressedProtocols kind.
155
+ struct {
156
+ uint16_t GenericParamIndex;
157
+ SuppressibleProtocolSet Protocols;
158
+ } SuppressedProtocols;
140
159
};
141
160
142
161
constexpr GenericRequirementFlags getFlags () const {
@@ -204,6 +223,18 @@ class TargetGenericRequirementDescriptor {
204
223
return Layout;
205
224
}
206
225
226
+ // / Retrieve the set of suppressed protocols.
227
+ SuppressibleProtocolSet getSuppressedProtocols () const {
228
+ assert (getKind () == GenericRequirementKind::SuppressedProtocols);
229
+ return SuppressedProtocols.Protocols ;
230
+ }
231
+
232
+ // / Retrieve the suppressible protocol kind.
233
+ uint16_t getSuppressedProtocolsGenericParamIndex () const {
234
+ assert (getKind () == GenericRequirementKind::SuppressedProtocols);
235
+ return SuppressedProtocols.GenericParamIndex ;
236
+ }
237
+
207
238
// / Determine whether this generic requirement has a known kind.
208
239
// /
209
240
// / \returns \c false for any future generic requirement kinds.
@@ -215,6 +246,7 @@ class TargetGenericRequirementDescriptor {
215
246
case GenericRequirementKind::SameConformance:
216
247
case GenericRequirementKind::SameType:
217
248
case GenericRequirementKind::SameShape:
249
+ case GenericRequirementKind::SuppressedProtocols:
218
250
return true ;
219
251
}
220
252
@@ -266,6 +298,26 @@ struct GenericPackShapeDescriptor {
266
298
uint16_t Unused;
267
299
};
268
300
301
+ // / A count for the number of requirements for the number of requirements
302
+ // / for a given conditional conformance to a suppressible protocols.
303
+ struct ConditionalSuppressibleProtocolsRequirementCount {
304
+ uint16_t count;
305
+ };
306
+
307
+ // / A suppressible protocol set used for the conditional conformances in a
308
+ // / generic context.
309
+ struct ConditionalSuppressibleProtocolSet : SuppressibleProtocolSet {
310
+ using SuppressibleProtocolSet::SuppressibleProtocolSet;
311
+ };
312
+
313
+ // / A generic requirement for describing a conditional conformance to a
314
+ // / suppressible protocol.
315
+ // /
316
+ // / This type is equivalent to a `TargetGenericRequirementDescriptor`, and
317
+ // / differs only because it needs to occur alongside
318
+ template <typename Runtime>
319
+ struct TargetConditionalSuppressibleProtocolRequirement : TargetGenericRequirementDescriptor<Runtime> { };
320
+
269
321
// / An array of generic parameter descriptors, all
270
322
// / GenericParamDescriptor::implicit(), which is by far
271
323
// / the most common case. Some generic context storage can
@@ -306,7 +358,8 @@ class RuntimeGenericSignature {
306
358
307
359
public:
308
360
RuntimeGenericSignature ()
309
- : Header{0 , 0 , 0 , 0 }, Params(nullptr ), Requirements(nullptr ),
361
+ : Header{0 , 0 , 0 , GenericContextDescriptorFlags (false , false )},
362
+ Params (nullptr ), Requirements(nullptr ),
310
363
PackShapeHeader{0 , 0 }, PackShapeDescriptors(nullptr ) {}
311
364
312
365
RuntimeGenericSignature (const TargetGenericContextDescriptorHeader<Runtime> &header,
@@ -425,20 +478,27 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
425
478
TargetGenericRequirementDescriptor<Runtime>,
426
479
GenericPackShapeHeader,
427
480
GenericPackShapeDescriptor,
481
+ ConditionalSuppressibleProtocolSet,
482
+ ConditionalSuppressibleProtocolsRequirementCount,
483
+ TargetConditionalSuppressibleProtocolRequirement<Runtime>,
428
484
FollowingTrailingObjects...>
429
485
{
430
486
protected:
431
487
using Self = TargetSelf<Runtime>;
432
488
using GenericContextHeaderType = TargetGenericContextHeaderType<Runtime>;
433
489
using GenericRequirementDescriptor =
434
490
TargetGenericRequirementDescriptor<Runtime>;
435
-
491
+ using GenericConditionalSuppressibleProtocolRequirement =
492
+ TargetConditionalSuppressibleProtocolRequirement<Runtime>;
436
493
using TrailingObjects = swift::ABI::TrailingObjects<Self,
437
494
GenericContextHeaderType,
438
495
GenericParamDescriptor,
439
496
GenericRequirementDescriptor,
440
497
GenericPackShapeHeader,
441
498
GenericPackShapeDescriptor,
499
+ ConditionalSuppressibleProtocolSet,
500
+ ConditionalSuppressibleProtocolsRequirementCount,
501
+ GenericConditionalSuppressibleProtocolRequirement,
442
502
FollowingTrailingObjects...>;
443
503
friend TrailingObjects;
444
504
@@ -467,7 +527,84 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
467
527
// / HeaderType ought to be convertible to GenericContextDescriptorHeader.
468
528
return getFullGenericContextHeader ();
469
529
}
470
-
530
+
531
+ bool hasConditionalSuppressedProtocols () const {
532
+ if (!asSelf ()->isGeneric ())
533
+ return false ;
534
+
535
+ return getGenericContextHeader ().hasConditionalSuppressedProtocols ();
536
+ }
537
+
538
+ const SuppressibleProtocolSet &
539
+ getConditionalSuppressedProtocols () const {
540
+ assert (hasConditionalSuppressedProtocols ());
541
+ return *this ->template
542
+ getTrailingObjects<ConditionalSuppressibleProtocolSet>();
543
+ }
544
+
545
+ // / Retrieve the counts for # of conditional suppressible protocols for each
546
+ // / conditional conformance to a suppressible protocol.
547
+ // /
548
+ // / The counts are cumulative, so the first entry in the array is the
549
+ // / number of requirements for the first conditional conformance. The
550
+ // / second entry in the array is the number of requirements in the first
551
+ // / and second conditional conformances. The last entry is, therefore, the
552
+ // / total count of requirements in the structure.
553
+ llvm::ArrayRef<ConditionalSuppressibleProtocolsRequirementCount>
554
+ getConditionalSuppressibleProtocolRequirementCounts () const {
555
+ if (!asSelf ()->hasConditionalSuppressedProtocols ())
556
+ return {};
557
+
558
+ return {
559
+ this ->template
560
+ getTrailingObjects<ConditionalSuppressibleProtocolsRequirementCount>(),
561
+ getNumConditionalSuppressibleProtocolsRequirementCounts ()
562
+ };
563
+ }
564
+
565
+ // / Retrieve the array of requirements for conditional conformances to
566
+ // / the ith conditional conformance to a suppressible protocol.
567
+ llvm::ArrayRef<GenericConditionalSuppressibleProtocolRequirement>
568
+ getConditionalSuppressibleProtocolRequirementsAt (unsigned i) const {
569
+ auto counts = getConditionalSuppressibleProtocolRequirementCounts ();
570
+ assert (i < counts.size ());
571
+
572
+ unsigned startIndex = (i == 0 ) ? 0 : counts[i-1 ].count ;
573
+ unsigned endIndex = counts[i].count ;
574
+
575
+ auto basePtr =
576
+ this ->template
577
+ getTrailingObjects<GenericConditionalSuppressibleProtocolRequirement>();
578
+ return { basePtr + startIndex, basePtr + endIndex };
579
+ }
580
+
581
+ // / Retrieve the array of requirements for conditional conformances to
582
+ // / the ith conditional conformance to a suppressible protocol.
583
+ llvm::ArrayRef<GenericConditionalSuppressibleProtocolRequirement>
584
+ getConditionalSuppressibleProtocolRequirementsFor (
585
+ SuppressibleProtocolKind kind
586
+ ) const {
587
+ if (!asSelf ()->hasConditionalSuppressedProtocols ())
588
+ return { };
589
+
590
+ auto conditionallySuppressed = getConditionalSuppressedProtocols ();
591
+ if (!conditionallySuppressed.contains (kind))
592
+ return { };
593
+
594
+ // Count the number of "set" bits up to (but not including) the
595
+ // bit we're looking at.
596
+ unsigned targetBit = static_cast <uint8_t >(kind);
597
+ auto suppressedBits = conditionallySuppressed.rawBits ();
598
+ unsigned priorBits = 0 ;
599
+ for (unsigned i = 0 ; i != targetBit; ++i) {
600
+ if (suppressedBits & 0x01 )
601
+ ++priorBits;
602
+ suppressedBits = suppressedBits >> 1 ;
603
+ }
604
+
605
+ return getConditionalSuppressibleProtocolRequirementsAt (priorBits);
606
+ }
607
+
471
608
const TargetGenericContext<Runtime> *getGenericContext () const {
472
609
if (!asSelf ()->isGeneric ())
473
610
return nullptr ;
@@ -549,6 +686,32 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
549
686
return getGenericPackShapeHeader ().NumPacks ;
550
687
}
551
688
689
+ size_t numTrailingObjects (
690
+ OverloadToken<ConditionalSuppressibleProtocolSet>
691
+ ) const {
692
+ return asSelf ()->hasConditionalSuppressedProtocols () ? 1 : 0 ;
693
+ }
694
+
695
+ unsigned getNumConditionalSuppressibleProtocolsRequirementCounts () const {
696
+ if (!asSelf ()->hasConditionalSuppressedProtocols ())
697
+ return 0 ;
698
+
699
+ return countBitsUsed (getConditionalSuppressedProtocols ().rawBits ());
700
+ }
701
+
702
+ size_t numTrailingObjects (
703
+ OverloadToken<ConditionalSuppressibleProtocolsRequirementCount>
704
+ ) const {
705
+ return getNumConditionalSuppressibleProtocolsRequirementCounts ();
706
+ }
707
+
708
+ size_t numTrailingObjects (
709
+ OverloadToken<GenericConditionalSuppressibleProtocolRequirement>
710
+ ) const {
711
+ auto counts = getConditionalSuppressibleProtocolRequirementCounts ();
712
+ return counts.empty () ? 0 : counts.back ().count ;
713
+ }
714
+
552
715
#if defined(_MSC_VER) && _MSC_VER < 1920
553
716
#undef OverloadToken
554
717
#endif
0 commit comments