@@ -115,6 +115,11 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
115
115
// / Retrieve the state of this conformance.
116
116
ProtocolConformanceState getState () const ;
117
117
118
+ // / Get the kind of source from which this conformance comes.
119
+ ConformanceEntryKind getSourceKind () const ;
120
+ // / Get the protocol conformance which implied this implied conformance.
121
+ NormalProtocolConformance *getImplyingConformance () const ;
122
+
118
123
// / Determine whether this conformance is complete.
119
124
bool isComplete () const {
120
125
return getState () == ProtocolConformanceState::Complete;
@@ -349,6 +354,20 @@ class NormalProtocolConformance : public ProtocolConformance,
349
354
// / Also stores the "invalid" bit.
350
355
llvm::PointerIntPair<Context, 1 , bool > ContextAndInvalid;
351
356
357
+ // / \brief The reason that this conformance exists.
358
+ // /
359
+ // / Either Explicit (e.g. 'struct Foo: Protocol {}' or 'extension Foo:
360
+ // / Protocol {}'), Synthesized (e.g. RawRepresentable for 'enum Foo: Int {}')
361
+ // / or Implied (e.g. 'Foo : Protocol' in 'protocol Other: Protocol {} struct
362
+ // / Foo: Other {}'). In only the latter case, the conformance is non-null and
363
+ // / points to the conformance that implies this one.
364
+ // /
365
+ // / This should never be Inherited: that is handled by
366
+ // / InheritedProtocolConformance.
367
+ llvm::PointerIntPair<NormalProtocolConformance *, 2 , ConformanceEntryKind>
368
+ SourceKindAndImplyingConformance = {nullptr ,
369
+ ConformanceEntryKind::Explicit};
370
+
352
371
// / \brief The mapping of individual requirements in the protocol over to
353
372
// / the declarations that satisfy those requirements.
354
373
mutable WitnessMap Mapping;
@@ -447,6 +466,28 @@ class NormalProtocolConformance : public ProtocolConformance,
447
466
SignatureConformances = {};
448
467
}
449
468
469
+ // / Get the kind of source from which this conformance comes.
470
+ ConformanceEntryKind getSourceKind () const {
471
+ return SourceKindAndImplyingConformance.getInt ();
472
+ }
473
+
474
+ // / Get the protocol conformance which implied this implied conformance.
475
+ NormalProtocolConformance *getImplyingConformance () const {
476
+ assert (getSourceKind () == ConformanceEntryKind::Implied);
477
+ return SourceKindAndImplyingConformance.getPointer ();
478
+ }
479
+
480
+ void setSourceKindAndImplyingConformance (
481
+ ConformanceEntryKind sourceKind,
482
+ NormalProtocolConformance *implyingConformance) {
483
+ assert (sourceKind != ConformanceEntryKind::Inherited &&
484
+ " a normal conformance cannot be inherited" );
485
+ assert ((sourceKind == ConformanceEntryKind::Implied) ==
486
+ (bool )implyingConformance &&
487
+ " an implied conformance needs something that implies it" );
488
+ SourceKindAndImplyingConformance = {implyingConformance, sourceKind};
489
+ }
490
+
450
491
// / Determine whether this conformance is lazily loaded.
451
492
// /
452
493
// / This only matters to the AST verifier.
@@ -666,6 +707,15 @@ class SpecializedProtocolConformance : public ProtocolConformance,
666
707
return GenericConformance->getState ();
667
708
}
668
709
710
+ // / Get the kind of source from which this conformance comes.
711
+ ConformanceEntryKind getSourceKind () const {
712
+ return GenericConformance->getSourceKind ();
713
+ }
714
+ // / Get the protocol conformance which implied this implied conformance.
715
+ NormalProtocolConformance *getImplyingConformance () const {
716
+ return GenericConformance->getImplyingConformance ();
717
+ }
718
+
669
719
bool hasTypeWitness (AssociatedTypeDecl *assocType,
670
720
LazyResolver *resolver = nullptr ) const ;
671
721
@@ -768,6 +818,13 @@ class InheritedProtocolConformance : public ProtocolConformance,
768
818
return InheritedConformance->getState ();
769
819
}
770
820
821
+ // / Get the kind of source from which this conformance comes.
822
+ ConformanceEntryKind getSourceKind () const {
823
+ return ConformanceEntryKind::Inherited;
824
+ }
825
+ // / Get the protocol conformance which implied this implied conformance.
826
+ NormalProtocolConformance *getImplyingConformance () const { return nullptr ; }
827
+
771
828
bool hasTypeWitness (AssociatedTypeDecl *assocType,
772
829
LazyResolver *resolver = nullptr ) const {
773
830
return InheritedConformance->hasTypeWitness (assocType, resolver);
0 commit comments