@@ -74,6 +74,10 @@ class GenericSignatureBuilder {
74
74
using RequirementRHS =
75
75
llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
76
76
77
+ // / The location of a requirement as written somewhere in the source.
78
+ typedef llvm::PointerUnion<const TypeRepr *, const RequirementRepr *>
79
+ WrittenRequirementLoc;
80
+
77
81
class RequirementSource ;
78
82
79
83
class FloatingRequirementSource ;
@@ -479,7 +483,8 @@ class GenericSignatureBuilder {
479
483
// / Requirement sources are uniqued within a generic signature builder.
480
484
class GenericSignatureBuilder ::RequirementSource final
481
485
: public llvm::FoldingSetNode,
482
- private llvm::TrailingObjects<RequirementSource, PotentialArchetype *> {
486
+ private llvm::TrailingObjects<RequirementSource, ProtocolDecl *,
487
+ WrittenRequirementLoc> {
483
488
484
489
friend class FloatingRequirementSource ;
485
490
@@ -549,8 +554,6 @@ class GenericSignatureBuilder::RequirementSource final
549
554
// / The kind of storage we have.
550
555
enum class StorageKind : uint8_t {
551
556
RootArchetype,
552
- TypeRepr,
553
- RequirementRepr,
554
557
ProtocolDecl,
555
558
ProtocolConformance,
556
559
AssociatedTypeDecl,
@@ -559,17 +562,14 @@ class GenericSignatureBuilder::RequirementSource final
559
562
// / The kind of storage we have.
560
563
const StorageKind storageKind;
561
564
565
+ // / Whether there is a trailing written requirement location.
566
+ const bool hasTrailingWrittenRequirementLoc;
567
+
562
568
// / The actual storage, described by \c storageKind.
563
569
union {
564
570
// / The root archetype.
565
571
PotentialArchetype *rootArchetype;
566
572
567
- // / The type representation describing where the requirement came from.
568
- const TypeRepr *typeRepr;
569
-
570
- // / Where a requirement came from.
571
- const RequirementRepr *requirementRepr;
572
-
573
573
// / The protocol being described.
574
574
ProtocolDecl *protocol;
575
575
@@ -582,16 +582,14 @@ class GenericSignatureBuilder::RequirementSource final
582
582
583
583
friend TrailingObjects;
584
584
585
- // / The trailing potential archetype, for
586
- size_t numTrailingObjects (OverloadToken<PotentialArchetype *>) const {
585
+ // / The trailing protocol declaration, if there is one.
586
+ size_t numTrailingObjects (OverloadToken<ProtocolDecl *>) const {
587
587
switch (kind) {
588
588
case RequirementSignatureSelf:
589
589
return 1 ;
590
590
591
591
case Explicit:
592
592
case Inferred:
593
- return storageKind == StorageKind::RootArchetype ? 0 : 1 ;
594
-
595
593
case NestedTypeNameMatch:
596
594
case ProtocolRequirement:
597
595
case Superclass:
@@ -603,16 +601,25 @@ class GenericSignatureBuilder::RequirementSource final
603
601
llvm_unreachable (" Unhandled RequirementSourceKind in switch." );
604
602
}
605
603
604
+ // / The trailing written requirement location, if there is one.
605
+ size_t numTrailingObjects (OverloadToken<WrittenRequirementLoc>) const {
606
+ return hasTrailingWrittenRequirementLoc ? 1 : 0 ;
607
+ }
608
+
606
609
// / Determines whether we have been provided with an acceptable storage kind
607
610
// / for the given requirement source kind.
608
611
static bool isAcceptableStorageKind (Kind kind, StorageKind storageKind);
609
612
610
613
// / Retrieve the opaque storage as a single pointer, for use in uniquing.
611
- const void *getOpaqueStorage () const ;
614
+ const void *getOpaqueStorage1 () const ;
615
+
616
+ // / Retrieve the second opaque storage as a single pointer, for use in
617
+ // / uniquing.
618
+ const void *getOpaqueStorage2 () const ;
612
619
613
- // / Retrieve the extra opaque storage as a single pointer, for use in
620
+ // / Retrieve the third opaque storage as a single pointer, for use in
614
621
// / uniquing.
615
- const void *getExtraOpaqueStorage () const ;
622
+ const void *getOpaqueStorage3 () const ;
616
623
617
624
// / Whether this kind of requirement source is a root.
618
625
static bool isRootKind (Kind kind) {
@@ -640,53 +647,43 @@ class GenericSignatureBuilder::RequirementSource final
640
647
// / requirement source with one of the "root" kinds.
641
648
const RequirementSource * const parent;
642
649
643
- RequirementSource (Kind kind, const RequirementSource *parent,
644
- PotentialArchetype *rootArchetype)
645
- : kind(kind), storageKind(StorageKind::RootArchetype), parent(parent) {
646
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
647
- " Root RequirementSource should not have parent (or vice versa)" );
650
+ RequirementSource (Kind kind, PotentialArchetype *rootArchetype,
651
+ ProtocolDecl *protocol,
652
+ WrittenRequirementLoc writtenReqLoc)
653
+ : kind(kind), storageKind(StorageKind::RootArchetype),
654
+ hasTrailingWrittenRequirementLoc (!writtenReqLoc.isNull()),
655
+ parent(nullptr ) {
648
656
assert (isAcceptableStorageKind (kind, storageKind) &&
649
657
" RequirementSource kind/storageKind mismatch" );
650
658
651
659
storage.rootArchetype = rootArchetype;
660
+ if (kind == RequirementSignatureSelf)
661
+ getTrailingObjects<ProtocolDecl *>()[0 ] = protocol;
662
+ if (hasTrailingWrittenRequirementLoc)
663
+ getTrailingObjects<WrittenRequirementLoc>()[0 ] = writtenReqLoc;
652
664
}
653
665
654
666
RequirementSource (Kind kind, const RequirementSource *parent,
655
- const TypeRepr *typeRepr)
656
- : kind(kind), storageKind(StorageKind::TypeRepr), parent(parent) {
657
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
658
- " Root RequirementSource should not have parent (or vice versa)" );
659
- assert (isAcceptableStorageKind (kind, storageKind) &&
660
- " RequirementSource kind/storageKind mismatch" );
667
+ ProtocolDecl *protocol,
668
+ WrittenRequirementLoc writtenReqLoc)
669
+ : kind(kind), storageKind(StorageKind::ProtocolDecl),
670
+ hasTrailingWrittenRequirementLoc(!writtenReqLoc.isNull()),
661
671
662
- storage.typeRepr = typeRepr;
663
- }
664
-
665
- RequirementSource (Kind kind, const RequirementSource *parent,
666
- const RequirementRepr *requirementRepr)
667
- : kind(kind), storageKind(StorageKind::RequirementRepr), parent(parent) {
668
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
669
- " Root RequirementSource should not have parent (or vice versa)" );
670
- assert (isAcceptableStorageKind (kind, storageKind) &&
671
- " RequirementSource kind/storageKind mismatch" );
672
-
673
- storage.requirementRepr = requirementRepr;
674
- }
675
-
676
- RequirementSource (Kind kind, const RequirementSource *parent,
677
- ProtocolDecl *protocol)
678
- : kind(kind), storageKind(StorageKind::ProtocolDecl), parent(parent) {
672
+ parent(parent) {
679
673
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
680
674
" Root RequirementSource should not have parent (or vice versa)" );
681
675
assert (isAcceptableStorageKind (kind, storageKind) &&
682
676
" RequirementSource kind/storageKind mismatch" );
683
677
684
678
storage.protocol = protocol;
679
+ if (hasTrailingWrittenRequirementLoc)
680
+ getTrailingObjects<WrittenRequirementLoc>()[0 ] = writtenReqLoc;
685
681
}
686
682
687
683
RequirementSource (Kind kind, const RequirementSource *parent,
688
684
ProtocolConformance *conformance)
689
685
: kind(kind), storageKind(StorageKind::ProtocolConformance),
686
+ hasTrailingWrittenRequirementLoc(false ),
690
687
parent(parent) {
691
688
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
692
689
" Root RequirementSource should not have parent (or vice versa)" );
@@ -699,6 +696,7 @@ class GenericSignatureBuilder::RequirementSource final
699
696
RequirementSource (Kind kind, const RequirementSource *parent,
700
697
AssociatedTypeDecl *assocType)
701
698
: kind(kind), storageKind(StorageKind::AssociatedTypeDecl),
699
+ hasTrailingWrittenRequirementLoc(false ),
702
700
parent(parent) {
703
701
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
704
702
" Root RequirementSource should not have parent (or vice versa)" );
@@ -713,15 +711,9 @@ class GenericSignatureBuilder::RequirementSource final
713
711
static const RequirementSource *forAbstract (PotentialArchetype *root);
714
712
715
713
// / Retrieve a requirement source representing an explicit requirement
716
- // / stated in an 'inheritance' clause.
714
+ // / stated in an 'inheritance' or 'where' clause.
717
715
static const RequirementSource *forExplicit (PotentialArchetype *root,
718
- const TypeRepr *typeRepr);
719
-
720
- // / Retrieve a requirement source representing an explicit requirement
721
- // / stated in an 'where' clause.
722
- static const RequirementSource *forExplicit (
723
- PotentialArchetype *root,
724
- const RequirementRepr *requirementRepr);
716
+ WrittenRequirementLoc writtenLoc);
725
717
726
718
// / Retrieve a requirement source representing a requirement that is
727
719
// / inferred from some part of a generic declaration's signature, e.g., the
@@ -744,7 +736,9 @@ class GenericSignatureBuilder::RequirementSource final
744
736
// / requirement of the given protocol described by the parent.
745
737
const RequirementSource *viaAbstractProtocolRequirement (
746
738
GenericSignatureBuilder &builder,
747
- ProtocolDecl *protocol) const ;
739
+ ProtocolDecl *protocol,
740
+ WrittenRequirementLoc writtenLoc =
741
+ WrittenRequirementLoc ()) const ;
748
742
749
743
public:
750
744
// / A requirement source that describes that a requirement that is resolved
@@ -799,15 +793,17 @@ class GenericSignatureBuilder::RequirementSource final
799
793
800
794
// / Retrieve the type representation for this requirement, if there is one.
801
795
const TypeRepr *getTypeRepr () const {
802
- if (storageKind != StorageKind::TypeRepr) return nullptr ;
803
- return storage.typeRepr ;
796
+ if (!hasTrailingWrittenRequirementLoc) return nullptr ;
797
+ return getTrailingObjects<WrittenRequirementLoc>()[0 ]
798
+ .dyn_cast <const TypeRepr *>();
804
799
}
805
800
806
801
// / Retrieve the requirement representation for this requirement, if there is
807
802
// / one.
808
803
const RequirementRepr *getRequirementRepr () const {
809
- if (storageKind != StorageKind::RequirementRepr) return nullptr ;
810
- return storage.requirementRepr ;
804
+ if (!hasTrailingWrittenRequirementLoc) return nullptr ;
805
+ return getTrailingObjects<WrittenRequirementLoc>()[0 ]
806
+ .dyn_cast <const RequirementRepr *>();
811
807
}
812
808
813
809
// / Retrieve the protocol for this requirement, if there is one.
@@ -828,17 +824,19 @@ class GenericSignatureBuilder::RequirementSource final
828
824
829
825
// / Profiling support for \c FoldingSet.
830
826
void Profile (llvm::FoldingSetNodeID &ID) {
831
- Profile (ID, kind, parent, getOpaqueStorage (), getExtraOpaqueStorage ());
827
+ Profile (ID, kind, parent, getOpaqueStorage1 (), getOpaqueStorage2 (),
828
+ getOpaqueStorage3 ());
832
829
}
833
830
834
831
// / Profiling support for \c FoldingSet.
835
832
static void Profile (llvm::FoldingSetNodeID &ID, Kind kind,
836
- const RequirementSource *parent, const void *storage ,
837
- const void *extraStorage ) {
833
+ const RequirementSource *parent, const void *storage1 ,
834
+ const void *storage2, const void *storage3 ) {
838
835
ID.AddInteger (kind);
839
836
ID.AddPointer (parent);
840
- ID.AddPointer (storage);
841
- ID.AddPointer (extraStorage);
837
+ ID.AddPointer (storage1);
838
+ ID.AddPointer (storage2);
839
+ ID.AddPointer (storage3);
842
840
}
843
841
844
842
LLVM_ATTRIBUTE_DEPRECATED (
@@ -881,7 +879,7 @@ class GenericSignatureBuilder::FloatingRequirementSource {
881
879
// Additional storage for an abstract protocol requirement.
882
880
struct {
883
881
ProtocolDecl *protocol = nullptr ;
884
- llvm::PointerUnion< const TypeRepr *, const RequirementRepr *> written;
882
+ WrittenRequirementLoc written;
885
883
} abstractProtocolReq;
886
884
887
885
FloatingRequirementSource (Kind kind, Storage storage)
@@ -920,9 +918,7 @@ class GenericSignatureBuilder::FloatingRequirementSource {
920
918
static FloatingRequirementSource viaAbstractProtocolRequirement (
921
919
const RequirementSource *base,
922
920
ProtocolDecl *inProtocol,
923
- llvm::PointerUnion<
924
- const TypeRepr *,
925
- const RequirementRepr *> written) {
921
+ WrittenRequirementLoc written) {
926
922
FloatingRequirementSource result{ AbstractProtocol, base };
927
923
result.abstractProtocolReq .protocol = inProtocol;
928
924
result.abstractProtocolReq .written = written;
0 commit comments