2121#include " swift/ABI/TargetLayout.h"
2222#include " swift/ABI/MetadataValues.h"
2323#include " swift/ABI/MetadataRef.h"
24+ #include " swift/ABI/SuppressibleProtocols.h"
2425#include " swift/ABI/TrailingObjects.h"
2526#include " swift/Demangling/Demangle.h"
2627
@@ -103,6 +104,10 @@ struct TargetGenericContextDescriptorHeader {
103104 bool hasArguments () const {
104105 return getNumArguments () > 0 ;
105106 }
107+
108+ bool hasConditionalSuppressedProtocols () const {
109+ return Flags.hasConditionalSuppressedProtocols ();
110+ }
106111};
107112using GenericContextDescriptorHeader =
108113 TargetGenericContextDescriptorHeader<InProcess>;
@@ -137,6 +142,20 @@ class TargetGenericRequirementDescriptor {
137142 // /
138143 // / Only valid if the requirement has Layout kind.
139144 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;
140159 };
141160
142161 constexpr GenericRequirementFlags getFlags () const {
@@ -204,6 +223,18 @@ class TargetGenericRequirementDescriptor {
204223 return Layout;
205224 }
206225
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+
207238 // / Determine whether this generic requirement has a known kind.
208239 // /
209240 // / \returns \c false for any future generic requirement kinds.
@@ -215,6 +246,7 @@ class TargetGenericRequirementDescriptor {
215246 case GenericRequirementKind::SameConformance:
216247 case GenericRequirementKind::SameType:
217248 case GenericRequirementKind::SameShape:
249+ case GenericRequirementKind::SuppressedProtocols:
218250 return true ;
219251 }
220252
@@ -266,6 +298,26 @@ struct GenericPackShapeDescriptor {
266298 uint16_t Unused;
267299};
268300
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+
269321// / An array of generic parameter descriptors, all
270322// / GenericParamDescriptor::implicit(), which is by far
271323// / the most common case. Some generic context storage can
@@ -306,7 +358,8 @@ class RuntimeGenericSignature {
306358
307359public:
308360 RuntimeGenericSignature ()
309- : Header{0 , 0 , 0 , 0 }, Params(nullptr ), Requirements(nullptr ),
361+ : Header{0 , 0 , 0 , GenericContextDescriptorFlags (false , false )},
362+ Params (nullptr ), Requirements(nullptr ),
310363 PackShapeHeader{0 , 0 }, PackShapeDescriptors(nullptr ) {}
311364
312365 RuntimeGenericSignature (const TargetGenericContextDescriptorHeader<Runtime> &header,
@@ -425,20 +478,27 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
425478 TargetGenericRequirementDescriptor<Runtime>,
426479 GenericPackShapeHeader,
427480 GenericPackShapeDescriptor,
481+ ConditionalSuppressibleProtocolSet,
482+ ConditionalSuppressibleProtocolsRequirementCount,
483+ TargetConditionalSuppressibleProtocolRequirement<Runtime>,
428484 FollowingTrailingObjects...>
429485{
430486protected:
431487 using Self = TargetSelf<Runtime>;
432488 using GenericContextHeaderType = TargetGenericContextHeaderType<Runtime>;
433489 using GenericRequirementDescriptor =
434490 TargetGenericRequirementDescriptor<Runtime>;
435-
491+ using GenericConditionalSuppressibleProtocolRequirement =
492+ TargetConditionalSuppressibleProtocolRequirement<Runtime>;
436493 using TrailingObjects = swift::ABI::TrailingObjects<Self,
437494 GenericContextHeaderType,
438495 GenericParamDescriptor,
439496 GenericRequirementDescriptor,
440497 GenericPackShapeHeader,
441498 GenericPackShapeDescriptor,
499+ ConditionalSuppressibleProtocolSet,
500+ ConditionalSuppressibleProtocolsRequirementCount,
501+ GenericConditionalSuppressibleProtocolRequirement,
442502 FollowingTrailingObjects...>;
443503 friend TrailingObjects;
444504
@@ -467,7 +527,84 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
467527 // / HeaderType ought to be convertible to GenericContextDescriptorHeader.
468528 return getFullGenericContextHeader ();
469529 }
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+
471608 const TargetGenericContext<Runtime> *getGenericContext () const {
472609 if (!asSelf ()->isGeneric ())
473610 return nullptr ;
@@ -549,6 +686,32 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
549686 return getGenericPackShapeHeader ().NumPacks ;
550687 }
551688
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+
552715#if defined(_MSC_VER) && _MSC_VER < 1920
553716#undef OverloadToken
554717#endif
0 commit comments