@@ -544,6 +544,30 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
544
544
}
545
545
}
546
546
547
+ // Think of a single-payload enum as being encoded in "pages".
548
+ // The discriminator (tag) tells us which page we're on:
549
+ // * Page 0 is the payload page which can either store
550
+ // the single payload case (any valid value
551
+ // for the payload) or any of N non-payload cases
552
+ // (encoded as XIs for the payload)
553
+ // * Other pages use the payload area to encode non-payload
554
+ // cases. The number of cases that can be encoded
555
+ // on each such page depends only on the size of the
556
+ // payload area.
557
+ //
558
+ // The above logic generalizes the following important cases:
559
+ // * A payload with XIs will generally have enough to
560
+ // encode all payloadcases. It will have no discriminator
561
+ // case, so everything is effectively on "page zero."
562
+ // * If the payload has no XIs but is not zero-sized, then
563
+ // we'll need a page one. That page will usually be
564
+ // large enough to encode all non-payload cases.
565
+ // * If the payload is zero-sized, then we only have a
566
+ // discriminator. In effect, the single-payload enum
567
+ // degenerates in this case to a non-payload enum
568
+ // (except for the subtle distinction that the
569
+ // single-payload enum doesn't export XIs).
570
+
547
571
bool projectEnumValue (remote::MemoryReader &reader,
548
572
remote::RemoteAddress address,
549
573
int *CaseIndex) const override {
@@ -552,7 +576,7 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
552
576
auto DiscriminatorAddress = address + PayloadSize;
553
577
auto DiscriminatorSize = getSize () - PayloadSize;
554
578
unsigned discriminator = 0 ;
555
- if (getSize () > PayloadSize ) {
579
+ if (DiscriminatorSize > 0 ) {
556
580
if (!reader.readInteger (DiscriminatorAddress,
557
581
DiscriminatorSize,
558
582
&discriminator)) {
@@ -574,9 +598,9 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
574
598
return false ;
575
599
}
576
600
auto casesPerNonPayloadPage =
577
- DiscriminatorSize >= 4
601
+ PayloadSize >= 4
578
602
? ValueWitnessFlags::MaxNumExtraInhabitants
579
- : (1UL << (DiscriminatorSize * 8UL ));
603
+ : (1UL << (PayloadSize * 8UL ));
580
604
ComputedCase =
581
605
1
582
606
+ nonPayloadCasesUsingXIs
@@ -618,7 +642,7 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
618
642
// case c(Int)
619
643
// }
620
644
//
621
- // // Enums with one payload with no XIs
645
+ // // Enums with one non-empty payload but that has no XIs
622
646
// // (This is almost but not quite the same as the single-payload
623
647
// // case. Different in that this MPE exposes extra tag values
624
648
// // as XIs to an enclosing enum; SPEs don't do that.)
0 commit comments