24
24
#include " swift/AST/Witness.h"
25
25
#include " swift/Basic/Compiler.h"
26
26
#include " swift/Basic/Debug.h"
27
+ #include " swift/Basic/InlineBitfield.h"
27
28
#include " llvm/ADT/ArrayRef.h"
28
29
#include " llvm/ADT/DenseMap.h"
29
30
#include " llvm/ADT/FoldingSet.h"
@@ -55,10 +56,10 @@ typedef llvm::DenseMap<AssociatedTypeDecl *, TypeWitnessAndDecl>
55
56
56
57
// / Describes the kind of protocol conformance structure used to encode
57
58
// / conformance.
58
- enum class ProtocolConformanceKind {
59
+ enum class ProtocolConformanceKind : unsigned {
59
60
// / "Normal" conformance of a (possibly generic) nominal type, which
60
61
// / contains complete mappings.
61
- Normal = 0 ,
62
+ Normal,
62
63
// / Self-conformance of a protocol to itself.
63
64
Self,
64
65
// / Conformance for a specialization of a generic type, which projects the
@@ -82,13 +83,25 @@ enum : unsigned {
82
83
// / incomplete, or currently being checked.
83
84
enum class ProtocolConformanceState {
84
85
// / The conformance has been fully checked.
85
- Complete,
86
+ Complete = 0 ,
86
87
// / The conformance is known but is not yet complete.
87
88
Incomplete,
88
89
// / The conformance's type witnesses are currently being resolved.
89
90
CheckingTypeWitnesses,
90
91
// / The conformance is being checked.
91
92
Checking,
93
+
94
+ Last_State = Checking
95
+ };
96
+
97
+ enum : unsigned {
98
+ NumProtocolConformanceStateBits =
99
+ countBitsUsed (static_cast <unsigned >(ProtocolConformanceState::Last_State))
100
+ };
101
+
102
+ enum : unsigned {
103
+ NumConformanceEntryKindBits =
104
+ countBitsUsed (static_cast <unsigned >(ConformanceEntryKind::Last_Kind))
92
105
};
93
106
94
107
// / Describes how a particular type conforms to a given protocol,
@@ -115,6 +128,38 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
115
128
// / The kind of protocol conformance.
116
129
Kind : bitmax (NumProtocolConformanceKindBits, 8 )
117
130
);
131
+
132
+ SWIFT_INLINE_BITFIELD_EMPTY (RootProtocolConformance, ProtocolConformance);
133
+
134
+ SWIFT_INLINE_BITFIELD_FULL (NormalProtocolConformance, RootProtocolConformance,
135
+ 1 +1 +1 +1 +bitmax (NumProtocolConformanceStateBits,8 )+
136
+ bitmax (NumConformanceEntryKindBits,8 ),
137
+ // / Indicates whether the conformance is invalid.
138
+ IsInvalid : 1 ,
139
+ // / The conformance was labeled with @unchecked.
140
+ IsUnchecked : 1 ,
141
+ // / The conformance was labeled with @preconcurrency.
142
+ IsPreconcurrency : 1 ,
143
+ // / We have allocated the AssociatedConformances array (but not necessarily
144
+ // / populated any of its elements).
145
+ HasComputedAssociatedConformances : 1 ,
146
+
147
+ : NumPadBits,
148
+
149
+ // / The current state of the conformance.
150
+ State : bitmax (NumProtocolConformanceStateBits, 8 ),
151
+ // / The reason that this conformance exists.
152
+ // /
153
+ // / Either Explicit (e.g. 'struct Foo: Protocol {}' or 'extension Foo:
154
+ // / Protocol {}'), Synthesized (e.g. RawRepresentable for 'enum Foo: Int {}')
155
+ // / or Implied (e.g. 'Foo : Protocol' in 'protocol Other: Protocol {} struct
156
+ // / Foo: Other {}'). In only the latter case, the conformance is non-null and
157
+ // / points to the conformance that implies this one.
158
+ // /
159
+ // / This should never be Inherited: that is handled by
160
+ // / InheritedProtocolConformance.
161
+ SourceKind : bitmax (NumConformanceEntryKindBits, 8 )
162
+ );
118
163
} Bits;
119
164
// clang-format on
120
165
@@ -456,49 +501,17 @@ class NormalProtocolConformance : public RootProtocolConformance,
456
501
friend class ValueWitnessRequest ;
457
502
friend class TypeWitnessRequest ;
458
503
459
- // / The protocol being conformed to and its current state.
460
- llvm::PointerIntPair<ProtocolDecl *, 2 , ProtocolConformanceState>
461
- ProtocolAndState;
504
+ // / The protocol being conformed to.
505
+ ProtocolDecl *Protocol;
462
506
463
507
// / The location of this protocol conformance in the source.
464
508
SourceLoc Loc;
465
509
466
- // Flag bits used in ContextAndBits.
467
- enum {
468
- // / The conformance was labeled with @unchecked.
469
- UncheckedFlag = 0x01 ,
470
-
471
- // / The conformance was labeled with @preconcurrency.
472
- PreconcurrencyFlag = 0x02 ,
473
-
474
- // / We have allocated the AssociatedConformances array (but not necessarily
475
- // / populated any of its elements).
476
- HasComputedAssociatedConformancesFlag = 0x04 ,
477
- };
478
-
479
510
// / The declaration context containing the ExtensionDecl or
480
511
// / NominalTypeDecl that declared the conformance.
481
- // /
482
- // / Also stores the "unchecked", "preconcurrency" and "has computed associated
483
- // / conformances" bits.
484
- llvm::PointerIntPair<DeclContext *, 3 , unsigned > ContextAndBits;
485
-
486
- // / Indicates whether the conformance is invalid.
487
- bool Invalid : 1 ;
512
+ DeclContext *Context;
488
513
489
- // / The reason that this conformance exists.
490
- // /
491
- // / Either Explicit (e.g. 'struct Foo: Protocol {}' or 'extension Foo:
492
- // / Protocol {}'), Synthesized (e.g. RawRepresentable for 'enum Foo: Int {}')
493
- // / or Implied (e.g. 'Foo : Protocol' in 'protocol Other: Protocol {} struct
494
- // / Foo: Other {}'). In only the latter case, the conformance is non-null and
495
- // / points to the conformance that implies this one.
496
- // /
497
- // / This should never be Inherited: that is handled by
498
- // / InheritedProtocolConformance.
499
- llvm::PointerIntPair<NormalProtocolConformance *, 3 , ConformanceEntryKind>
500
- SourceKindAndImplyingConformance = {nullptr ,
501
- ConformanceEntryKind::Explicit};
514
+ NormalProtocolConformance *ImplyingConformance = nullptr ;
502
515
503
516
// / The mapping of individual requirements in the protocol over to
504
517
// / the declarations that satisfy those requirements.
@@ -529,25 +542,27 @@ class NormalProtocolConformance : public RootProtocolConformance,
529
542
bool isPreconcurrency)
530
543
: RootProtocolConformance(ProtocolConformanceKind::Normal,
531
544
conformingType),
532
- ProtocolAndState (protocol, state), Loc(loc),
533
- ContextAndBits(dc, ((isUnchecked ? UncheckedFlag : 0 ) |
534
- (isPreconcurrency ? PreconcurrencyFlag : 0 ))),
535
- Invalid(false ) {
545
+ Protocol (protocol), Loc(loc), Context(dc) {
536
546
assert (!conformingType->hasArchetype () &&
537
547
" ProtocolConformances should store interface types" );
548
+ setState (state);
549
+ Bits.NormalProtocolConformance .IsInvalid = false ;
550
+ Bits.NormalProtocolConformance .IsUnchecked = isUnchecked;
551
+ Bits.NormalProtocolConformance .IsPreconcurrency = isPreconcurrency;
552
+ Bits.NormalProtocolConformance .HasComputedAssociatedConformances = false ;
553
+ Bits.NormalProtocolConformance .SourceKind =
554
+ unsigned (ConformanceEntryKind::Explicit);
538
555
}
539
556
540
557
// / Get the protocol being conformed to.
541
- ProtocolDecl *getProtocol () const { return ProtocolAndState. getPointer () ; }
558
+ ProtocolDecl *getProtocol () const { return Protocol ; }
542
559
543
560
// / Retrieve the location of this
544
561
SourceLoc getLoc () const { return Loc; }
545
562
546
563
// / Get the declaration context that contains the conforming extension or
547
564
// / nominal type declaration.
548
- DeclContext *getDeclContext () const {
549
- return ContextAndBits.getPointer ();
550
- }
565
+ DeclContext *getDeclContext () const { return Context; }
551
566
552
567
// / Get any additional requirements that are required for this conformance to
553
568
// / be satisfied, e.g. for Array<T>: Equatable, T: Equatable also needs
@@ -559,59 +574,59 @@ class NormalProtocolConformance : public RootProtocolConformance,
559
574
560
575
// / Retrieve the state of this conformance.
561
576
ProtocolConformanceState getState () const {
562
- return ProtocolAndState.getInt ();
577
+ return static_cast <ProtocolConformanceState>(
578
+ Bits.NormalProtocolConformance .State );
563
579
}
564
580
565
581
// / Set the state of this conformance.
566
582
void setState (ProtocolConformanceState state) {
567
- ProtocolAndState. setInt (state);
583
+ Bits. NormalProtocolConformance . State = unsigned (state);
568
584
}
569
585
570
586
// / Determine whether this conformance is invalid.
571
- bool isInvalid () const {
572
- return Invalid;
573
- }
587
+ bool isInvalid () const { return Bits.NormalProtocolConformance .IsInvalid ; }
574
588
575
589
// / Mark this conformance as invalid.
576
- void setInvalid () {
577
- Invalid = true ;
578
- }
590
+ void setInvalid () { Bits.NormalProtocolConformance .IsInvalid = true ; }
579
591
580
592
// / Whether this is an "unchecked" conformance.
581
593
bool isUnchecked () const {
582
- return ContextAndBits. getInt () & UncheckedFlag ;
594
+ return Bits. NormalProtocolConformance . IsUnchecked ;
583
595
}
584
596
585
597
// / Mark the conformance as unchecked (equivalent to the @unchecked
586
598
// / conformance attribute).
587
599
void setUnchecked () {
588
600
// OK to mutate because the flags are not part of the folding set node ID.
589
- ContextAndBits. setInt (ContextAndBits. getInt () | UncheckedFlag) ;
601
+ Bits. NormalProtocolConformance . IsUnchecked = true ;
590
602
}
591
603
592
604
// / Whether this is an preconcurrency conformance.
593
- bool isPreconcurrency () const ;
605
+ bool isPreconcurrency () const {
606
+ return Bits.NormalProtocolConformance .IsPreconcurrency ;
607
+ }
594
608
595
609
// / Determine whether we've lazily computed the associated conformance array
596
610
// / already.
597
611
bool hasComputedAssociatedConformances () const {
598
- return ContextAndBits. getInt () & HasComputedAssociatedConformancesFlag ;
612
+ return Bits. NormalProtocolConformance . HasComputedAssociatedConformances ;
599
613
}
600
614
601
615
// / Mark this conformance as having computed the assocaited conformance array.
602
616
void setHasComputedAssociatedConformances () {
603
- ContextAndBits. setInt (ContextAndBits. getInt () | HasComputedAssociatedConformancesFlag) ;
617
+ Bits. NormalProtocolConformance . HasComputedAssociatedConformances = true ;
604
618
}
605
619
606
620
// / Get the kind of source from which this conformance comes.
607
621
ConformanceEntryKind getSourceKind () const {
608
- return SourceKindAndImplyingConformance.getInt ();
622
+ return static_cast <ConformanceEntryKind>(
623
+ Bits.NormalProtocolConformance .SourceKind );
609
624
}
610
625
611
626
// / Get the protocol conformance which implied this implied conformance.
612
627
NormalProtocolConformance *getImplyingConformance () const {
613
628
assert (getSourceKind () == ConformanceEntryKind::Implied);
614
- return SourceKindAndImplyingConformance. getPointer () ;
629
+ return ImplyingConformance ;
615
630
}
616
631
617
632
void setSourceKindAndImplyingConformance (
@@ -624,7 +639,8 @@ class NormalProtocolConformance : public RootProtocolConformance,
624
639
" an implied conformance needs something that implies it" );
625
640
assert (sourceKind != ConformanceEntryKind::PreMacroExpansion &&
626
641
" cannot create conformance pre-macro-expansion" );
627
- SourceKindAndImplyingConformance = {implyingConformance, sourceKind};
642
+ Bits.NormalProtocolConformance .SourceKind = unsigned (sourceKind);
643
+ ImplyingConformance = implyingConformance;
628
644
}
629
645
630
646
// / Determine whether this conformance is lazily loaded.
0 commit comments