@@ -653,13 +653,16 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
653
653
// }
654
654
// ```
655
655
class TaggedMultiPayloadEnumTypeInfo : public EnumTypeInfo {
656
+ unsigned NumEffectivePayloadCases;
656
657
public:
657
658
TaggedMultiPayloadEnumTypeInfo (unsigned Size, unsigned Alignment,
658
659
unsigned Stride, unsigned NumExtraInhabitants,
659
660
bool BitwiseTakable,
660
- const std::vector<FieldInfo> &Cases)
661
+ const std::vector<FieldInfo> &Cases,
662
+ unsigned NumEffectivePayloadCases)
661
663
: EnumTypeInfo(Size, Alignment, Stride, NumExtraInhabitants,
662
- BitwiseTakable, EnumKind::MultiPayloadEnum, Cases) {
664
+ BitwiseTakable, EnumKind::MultiPayloadEnum, Cases),
665
+ NumEffectivePayloadCases (NumEffectivePayloadCases) {
663
666
// Definition of "multi-payload enum"
664
667
assert (getCases ().size () > 1 ); // At least 2 cases
665
668
assert (Cases[0 ].TR != 0 ); // At least 2 payloads
@@ -698,7 +701,7 @@ class TaggedMultiPayloadEnumTypeInfo: public EnumTypeInfo {
698
701
remote::RemoteAddress address,
699
702
int *CaseIndex) const override {
700
703
unsigned long PayloadSize = getPayloadSize ();
701
- unsigned PayloadCount = getNumPayloadCases () ;
704
+ unsigned PayloadCount = NumEffectivePayloadCases ;
702
705
unsigned NumCases = getNumCases ();
703
706
unsigned TagSize = getSize () - PayloadSize;
704
707
unsigned tag = 0 ;
@@ -1030,15 +1033,24 @@ class BitMask {
1030
1033
// bits in the payload.
1031
1034
class MultiPayloadEnumTypeInfo : public EnumTypeInfo {
1032
1035
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;
1033
1043
public:
1034
1044
MultiPayloadEnumTypeInfo (unsigned Size, unsigned Alignment,
1035
1045
unsigned Stride, unsigned NumExtraInhabitants,
1036
1046
bool BitwiseTakable,
1037
1047
const std::vector<FieldInfo> &Cases,
1038
- BitMask spareBitsMask)
1048
+ BitMask spareBitsMask,
1049
+ unsigned NumEffectivePayloadCases)
1039
1050
: EnumTypeInfo(Size, Alignment, Stride, NumExtraInhabitants,
1040
1051
BitwiseTakable, EnumKind::MultiPayloadEnum, Cases),
1041
- spareBitsMask (spareBitsMask) {
1052
+ spareBitsMask (spareBitsMask),
1053
+ NumEffectivePayloadCases(NumEffectivePayloadCases) {
1042
1054
assert (Cases[0 ].TR != 0 );
1043
1055
assert (Cases[1 ].TR != 0 );
1044
1056
assert (getNumNonEmptyPayloadCases () > 1 );
@@ -1125,7 +1137,6 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
1125
1137
remote::RemoteAddress address,
1126
1138
int *CaseIndex) const override {
1127
1139
unsigned long payloadSize = getPayloadSize ();
1128
- unsigned NumPayloadCases = getNumPayloadCases ();
1129
1140
1130
1141
// Extra Tag (if any) holds upper bits of case value
1131
1142
auto extraTagSize = getSize () - payloadSize;
@@ -1156,7 +1167,7 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
1156
1167
}
1157
1168
1158
1169
// If the above identifies a payload case, we're done
1159
- if (static_cast <unsigned >(tagValue) < NumPayloadCases ) {
1170
+ if (static_cast <unsigned >(tagValue) < NumEffectivePayloadCases ) {
1160
1171
*CaseIndex = tagValue;
1161
1172
return true ;
1162
1173
}
@@ -1173,9 +1184,9 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
1173
1184
1174
1185
int ComputedCase = 0 ;
1175
1186
if (occupiedBitCount >= 32 ) {
1176
- ComputedCase = payloadValue + NumPayloadCases ;
1187
+ ComputedCase = payloadValue + NumEffectivePayloadCases ;
1177
1188
} else {
1178
- ComputedCase = (((tagValue - NumPayloadCases ) << occupiedBitCount) | payloadValue) + NumPayloadCases ;
1189
+ ComputedCase = (((tagValue - NumEffectivePayloadCases ) << occupiedBitCount) | payloadValue) + NumEffectivePayloadCases ;
1179
1190
}
1180
1191
1181
1192
if (static_cast <unsigned >(ComputedCase) < getNumCases ()) {
@@ -1193,8 +1204,8 @@ class MultiPayloadEnumTypeInfo: public EnumTypeInfo {
1193
1204
// * The remainder of the payload bits (for non-payload cases)
1194
1205
// This computes the bits used for the payload tag.
1195
1206
BitMask getMultiPayloadTagBitsMask () const {
1196
- auto payloadTagValues = getNumPayloadCases () - 1 ;
1197
- if (getNumCases () > getNumPayloadCases () ) {
1207
+ auto payloadTagValues = NumEffectivePayloadCases - 1 ;
1208
+ if (getNumCases () > NumEffectivePayloadCases ) {
1198
1209
payloadTagValues += 1 ;
1199
1210
}
1200
1211
int payloadTagBits = 0 ;
@@ -2257,7 +2268,7 @@ class EnumTypeInfoBuilder {
2257
2268
Stride = 1 ;
2258
2269
return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
2259
2270
Size, Alignment, Stride, NumExtraInhabitants,
2260
- BitwiseTakable, Cases);
2271
+ BitwiseTakable, Cases, EffectivePayloadCases );
2261
2272
}
2262
2273
2263
2274
// This is a multi-payload enum that:
@@ -2291,7 +2302,7 @@ class EnumTypeInfoBuilder {
2291
2302
// If there are no spare bits, use the "simple" tag-only implementation.
2292
2303
return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
2293
2304
Size, Alignment, Stride, NumExtraInhabitants,
2294
- BitwiseTakable, Cases);
2305
+ BitwiseTakable, Cases, EffectivePayloadCases );
2295
2306
}
2296
2307
2297
2308
#if 0 // TODO: This should be !defined(NDEBUG)
@@ -2314,7 +2325,8 @@ class EnumTypeInfoBuilder {
2314
2325
// Use compiler-provided spare bit information
2315
2326
return TC.makeTypeInfo <MultiPayloadEnumTypeInfo>(
2316
2327
Size, Alignment, Stride, NumExtraInhabitants,
2317
- BitwiseTakable, Cases, spareBitsMask);
2328
+ BitwiseTakable, Cases, spareBitsMask,
2329
+ EffectivePayloadCases);
2318
2330
}
2319
2331
2320
2332
// Either there was no compiler data or it didn't make sense
@@ -2339,13 +2351,14 @@ class EnumTypeInfoBuilder {
2339
2351
// above only returns an empty mask when the mask is really empty,
2340
2352
return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
2341
2353
Size, Alignment, Stride, NumExtraInhabitants,
2342
- BitwiseTakable, Cases);
2354
+ BitwiseTakable, Cases, EffectivePayloadCases );
2343
2355
} else {
2344
2356
// General case can mix spare bits and extra discriminator
2345
2357
// It obviously relies on having an accurate spare bit mask.
2346
2358
return TC.makeTypeInfo <MultiPayloadEnumTypeInfo>(
2347
2359
Size, Alignment, Stride, NumExtraInhabitants,
2348
- BitwiseTakable, Cases, spareBitsMask);
2360
+ BitwiseTakable, Cases, spareBitsMask,
2361
+ EffectivePayloadCases);
2349
2362
}
2350
2363
}
2351
2364
};
0 commit comments