@@ -653,13 +653,16 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
653653// }
654654// ```
655655class TaggedMultiPayloadEnumTypeInfo : public EnumTypeInfo {
656+ unsigned NumEffectivePayloadCases;
656657public:
657658 TaggedMultiPayloadEnumTypeInfo (unsigned Size, unsigned Alignment,
658659 unsigned Stride, unsigned NumExtraInhabitants,
659660 bool BitwiseTakable,
660- const std::vector<FieldInfo> &Cases)
661+ const std::vector<FieldInfo> &Cases,
662+ unsigned NumEffectivePayloadCases)
661663 : EnumTypeInfo(Size, Alignment, Stride, NumExtraInhabitants,
662- BitwiseTakable, EnumKind::MultiPayloadEnum, Cases) {
664+ BitwiseTakable, EnumKind::MultiPayloadEnum, Cases),
665+ NumEffectivePayloadCases (NumEffectivePayloadCases) {
663666 // Definition of "multi-payload enum"
664667 assert (getCases ().size () > 1 ); // At least 2 cases
665668 assert (Cases[0 ].TR != 0 ); // At least 2 payloads
@@ -698,7 +701,7 @@ class TaggedMultiPayloadEnumTypeInfo: public EnumTypeInfo {
698701 remote::RemoteAddress address,
699702 int *CaseIndex) const override {
700703 unsigned long PayloadSize = getPayloadSize ();
701- unsigned PayloadCount = getNumPayloadCases () ;
704+ unsigned PayloadCount = NumEffectivePayloadCases ;
702705 unsigned NumCases = getNumCases ();
703706 unsigned TagSize = getSize () - PayloadSize;
704707 unsigned tag = 0 ;
@@ -1030,15 +1033,24 @@ class BitMask {
10301033// bits in the payload.
10311034class MultiPayloadEnumTypeInfo : public EnumTypeInfo {
10321035 BitMask spareBitsMask;
1036+ // "Effective" payload cases includes those with
1037+ // generic payload and non-generic cases that are
1038+ // statically known to have non-zero size.
1039+ // It does not include cases with payloads that are
1040+ // non-generic and zero-sized (these are treated as
1041+ // non-payload cases for many purposes).
1042+ unsigned NumEffectivePayloadCases;
10331043public:
10341044 MultiPayloadEnumTypeInfo (unsigned Size, unsigned Alignment,
10351045 unsigned Stride, unsigned NumExtraInhabitants,
10361046 bool BitwiseTakable,
10371047 const std::vector<FieldInfo> &Cases,
1038- BitMask spareBitsMask)
1048+ BitMask spareBitsMask,
1049+ unsigned NumEffectivePayloadCases)
10391050 : EnumTypeInfo(Size, Alignment, Stride, NumExtraInhabitants,
10401051 BitwiseTakable, EnumKind::MultiPayloadEnum, Cases),
1041- spareBitsMask (spareBitsMask) {
1052+ spareBitsMask (spareBitsMask),
1053+ NumEffectivePayloadCases(NumEffectivePayloadCases) {
10421054 assert (Cases[0 ].TR != 0 );
10431055 assert (Cases[1 ].TR != 0 );
10441056 assert (getNumNonEmptyPayloadCases () > 1 );
@@ -1125,7 +1137,6 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
11251137 remote::RemoteAddress address,
11261138 int *CaseIndex) const override {
11271139 unsigned long payloadSize = getPayloadSize ();
1128- unsigned NumPayloadCases = getNumPayloadCases ();
11291140
11301141 // Extra Tag (if any) holds upper bits of case value
11311142 auto extraTagSize = getSize () - payloadSize;
@@ -1156,7 +1167,7 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
11561167 }
11571168
11581169 // If the above identifies a payload case, we're done
1159- if (static_cast <unsigned >(tagValue) < NumPayloadCases ) {
1170+ if (static_cast <unsigned >(tagValue) < NumEffectivePayloadCases ) {
11601171 *CaseIndex = tagValue;
11611172 return true ;
11621173 }
@@ -1173,9 +1184,9 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
11731184
11741185 int ComputedCase = 0 ;
11751186 if (occupiedBitCount >= 32 ) {
1176- ComputedCase = payloadValue + NumPayloadCases ;
1187+ ComputedCase = payloadValue + NumEffectivePayloadCases ;
11771188 } else {
1178- ComputedCase = (((tagValue - NumPayloadCases ) << occupiedBitCount) | payloadValue) + NumPayloadCases ;
1189+ ComputedCase = (((tagValue - NumEffectivePayloadCases ) << occupiedBitCount) | payloadValue) + NumEffectivePayloadCases ;
11791190 }
11801191
11811192 if (static_cast <unsigned >(ComputedCase) < getNumCases ()) {
@@ -1193,8 +1204,8 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
11931204 // * The remainder of the payload bits (for non-payload cases)
11941205 // This computes the bits used for the payload tag.
11951206 BitMask getMultiPayloadTagBitsMask () const {
1196- auto payloadTagValues = getNumPayloadCases () - 1 ;
1197- if (getNumCases () > getNumPayloadCases () ) {
1207+ auto payloadTagValues = NumEffectivePayloadCases - 1 ;
1208+ if (getNumCases () > NumEffectivePayloadCases ) {
11981209 payloadTagValues += 1 ;
11991210 }
12001211 int payloadTagBits = 0 ;
@@ -2257,7 +2268,7 @@ class EnumTypeInfoBuilder {
22572268 Stride = 1 ;
22582269 return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
22592270 Size, Alignment, Stride, NumExtraInhabitants,
2260- BitwiseTakable, Cases);
2271+ BitwiseTakable, Cases, EffectivePayloadCases );
22612272 }
22622273
22632274 // This is a multi-payload enum that:
@@ -2291,7 +2302,7 @@ class EnumTypeInfoBuilder {
22912302 // If there are no spare bits, use the "simple" tag-only implementation.
22922303 return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
22932304 Size, Alignment, Stride, NumExtraInhabitants,
2294- BitwiseTakable, Cases);
2305+ BitwiseTakable, Cases, EffectivePayloadCases );
22952306 }
22962307
22972308#if 0 // TODO: This should be !defined(NDEBUG)
@@ -2314,7 +2325,8 @@ class EnumTypeInfoBuilder {
23142325 // Use compiler-provided spare bit information
23152326 return TC.makeTypeInfo <MultiPayloadEnumTypeInfo>(
23162327 Size, Alignment, Stride, NumExtraInhabitants,
2317- BitwiseTakable, Cases, spareBitsMask);
2328+ BitwiseTakable, Cases, spareBitsMask,
2329+ EffectivePayloadCases);
23182330 }
23192331
23202332 // Either there was no compiler data or it didn't make sense
@@ -2339,13 +2351,14 @@ class EnumTypeInfoBuilder {
23392351 // above only returns an empty mask when the mask is really empty,
23402352 return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
23412353 Size, Alignment, Stride, NumExtraInhabitants,
2342- BitwiseTakable, Cases);
2354+ BitwiseTakable, Cases, EffectivePayloadCases );
23432355 } else {
23442356 // General case can mix spare bits and extra discriminator
23452357 // It obviously relies on having an accurate spare bit mask.
23462358 return TC.makeTypeInfo <MultiPayloadEnumTypeInfo>(
23472359 Size, Alignment, Stride, NumExtraInhabitants,
2348- BitwiseTakable, Cases, spareBitsMask);
2360+ BitwiseTakable, Cases, spareBitsMask,
2361+ EffectivePayloadCases);
23492362 }
23502363 }
23512364};
0 commit comments