@@ -315,6 +315,7 @@ BitMask BuiltinTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) cons
315
315
mask.keepOnlyMostSignificantBits (getSize () * 8 - intSize);
316
316
return mask;
317
317
} else if (
318
+ Name == " ypXp" || // Any.Type
318
319
Name == " yyXf" // 'yyXf' = @thin () -> Void function
319
320
) {
320
321
// Builtin types that expose pointer spare bits
@@ -578,7 +579,9 @@ class NoPayloadEnumTypeInfo: public EnumTypeInfo {
578
579
}
579
580
580
581
BitMask getSpareBits (TypeConverter &TC, bool &hasAddrOnly) const override {
581
- return BitMask::zeroMask (getSize ());
582
+ auto mask = BitMask (getSize (), maskForCount (getNumCases ()));
583
+ mask.complement ();
584
+ return mask;
582
585
}
583
586
584
587
bool projectEnumValue (remote::MemoryReader &reader,
@@ -648,7 +651,17 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
648
651
}
649
652
650
653
BitMask getSpareBits (TypeConverter &TC, bool &hasAddrOnly) const override {
651
- return BitMask::zeroMask (getSize ());
654
+ FieldInfo PayloadCase = getCases ()[0 ];
655
+ size_t payloadSize = PayloadCase.TI .getSize ();
656
+ if (getSize () <= payloadSize) {
657
+ return BitMask::zeroMask (getSize ());
658
+ }
659
+ size_t tagSize = getSize () - payloadSize;
660
+ auto mask = BitMask::oneMask (getSize ());
661
+ mask.keepOnlyMostSignificantBits (tagSize * 8 ); // Clear payload bits
662
+ auto tagMaskUsedBits = BitMask (getSize (), maskForCount (getNumCases ()));
663
+ mask.andNotMask (tagMaskUsedBits, payloadSize); // Clear used tag bits
664
+ return mask;
652
665
}
653
666
654
667
// Think of a single-payload enum as being encoded in "pages".
@@ -2046,11 +2059,10 @@ class EnumTypeInfoBuilder {
2046
2059
//
2047
2060
2048
2061
// Do we have a fixed layout?
2049
- // TODO: Test whether a missing FixedDescriptor is actually relevant.
2050
2062
auto FixedDescriptor = TC.getBuilder ().getBuiltinTypeDescriptor (TR);
2051
2063
if (!FixedDescriptor || GenericPayloadCases > 0 ) {
2052
2064
// This is a "dynamic multi-payload enum". For example,
2053
- // this occurs with:
2065
+ // this occurs with generics such as :
2054
2066
// ```
2055
2067
// class ClassWithEnum<T> {
2056
2068
// enum E {
@@ -2060,6 +2072,12 @@ class EnumTypeInfoBuilder {
2060
2072
// var e: E?
2061
2073
// }
2062
2074
// ```
2075
+ // and when we have a resilient inner enum, such as:
2076
+ // ```
2077
+ // enum E2 {
2078
+ // case y(E1_resilient)
2079
+ // case z(Int)
2080
+ // }
2063
2081
auto tagCounts = getEnumTagCounts (Size, EffectiveNoPayloadCases,
2064
2082
EffectivePayloadCases);
2065
2083
Size += tagCounts.numTagBytes ;
@@ -2091,7 +2109,6 @@ class EnumTypeInfoBuilder {
2091
2109
unsigned Stride = ((Size + Alignment - 1 ) & ~(Alignment - 1 ));
2092
2110
if (Stride == 0 )
2093
2111
Stride = 1 ;
2094
- auto PayloadSize = EnumTypeInfo::getPayloadSizeForCases (Cases);
2095
2112
2096
2113
// Compute the spare bit mask and determine if we have any address-only fields
2097
2114
auto localSpareBitMask = BitMask::oneMask (Size);
@@ -2103,44 +2120,11 @@ class EnumTypeInfoBuilder {
2103
2120
}
2104
2121
}
2105
2122
2106
- // See if we have MPE bit mask information from the compiler...
2107
- // TODO: drop this?
2108
-
2109
- // Uncomment the following line to dump the MPE section every time we come through here...
2110
- // TC.getBuilder().dumpMultiPayloadEnumSection(std::cerr); // DEBUG helper
2111
-
2112
- auto MPEDescriptor = TC.getBuilder ().getMultiPayloadEnumDescriptor (TR);
2113
- if (MPEDescriptor && MPEDescriptor->usesPayloadSpareBits ()) {
2114
- // We found compiler-provided spare bit data...
2115
- auto PayloadSpareBitMaskByteCount = MPEDescriptor->getPayloadSpareBitMaskByteCount ();
2116
- auto PayloadSpareBitMaskByteOffset = MPEDescriptor->getPayloadSpareBitMaskByteOffset ();
2117
- auto SpareBitMask = MPEDescriptor->getPayloadSpareBits ();
2118
- BitMask compilerSpareBitMask (PayloadSize, SpareBitMask,
2119
- PayloadSpareBitMaskByteCount, PayloadSpareBitMaskByteOffset);
2120
-
2121
- if (compilerSpareBitMask.isZero () || hasAddrOnly) {
2122
- // If there are no spare bits, use the "simple" tag-only implementation.
2123
- return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
2124
- Size, Alignment, Stride, NumExtraInhabitants,
2125
- BitwiseTakable, Cases, EffectivePayloadCases);
2126
- }
2127
-
2128
- #if 0 // TODO: This should be !defined(NDEBUG)
2129
- // Verify that compiler provided and local spare bit info agree...
2130
- // TODO: If we could make this actually work, then we wouldn't need the
2131
- // bulky compiler-provided info, would we?
2132
- assert(localSpareBitMask == compilerSpareBitMask);
2133
- #endif
2134
-
2135
- // Use compiler-provided spare bit information
2136
- return TC.makeTypeInfo <MultiPayloadEnumTypeInfo>(
2137
- Size, Alignment, Stride, NumExtraInhabitants,
2138
- BitwiseTakable, Cases, compilerSpareBitMask,
2139
- EffectivePayloadCases);
2140
- }
2141
-
2142
2123
if (localSpareBitMask.isZero () || hasAddrOnly) {
2143
- // Simple case that does not use spare bits
2124
+ // Simple tag-only layout does not use spare bits.
2125
+ // Either:
2126
+ // * There are no spare bits, or
2127
+ // * We can't copy it to strip spare bits.
2144
2128
return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
2145
2129
Size, Alignment, Stride, NumExtraInhabitants,
2146
2130
BitwiseTakable, Cases, EffectivePayloadCases);
0 commit comments