@@ -315,6 +315,7 @@ BitMask BuiltinTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) cons
315315 mask.keepOnlyMostSignificantBits (getSize () * 8 - intSize);
316316 return mask;
317317 } else if (
318+ Name == " ypXp" || // Any.Type
318319 Name == " yyXf" // 'yyXf' = @thin () -> Void function
319320 ) {
320321 // Builtin types that expose pointer spare bits
@@ -578,7 +579,9 @@ class NoPayloadEnumTypeInfo: public EnumTypeInfo {
578579 }
579580
580581 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;
582585 }
583586
584587 bool projectEnumValue (remote::MemoryReader &reader,
@@ -648,7 +651,17 @@ class SinglePayloadEnumTypeInfo: public EnumTypeInfo {
648651 }
649652
650653 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;
652665 }
653666
654667 // Think of a single-payload enum as being encoded in "pages".
@@ -2046,11 +2059,10 @@ class EnumTypeInfoBuilder {
20462059 //
20472060
20482061 // Do we have a fixed layout?
2049- // TODO: Test whether a missing FixedDescriptor is actually relevant.
20502062 auto FixedDescriptor = TC.getBuilder ().getBuiltinTypeDescriptor (TR);
20512063 if (!FixedDescriptor || GenericPayloadCases > 0 ) {
20522064 // This is a "dynamic multi-payload enum". For example,
2053- // this occurs with:
2065+ // this occurs with generics such as :
20542066 // ```
20552067 // class ClassWithEnum<T> {
20562068 // enum E {
@@ -2060,6 +2072,12 @@ class EnumTypeInfoBuilder {
20602072 // var e: E?
20612073 // }
20622074 // ```
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+ // }
20632081 auto tagCounts = getEnumTagCounts (Size, EffectiveNoPayloadCases,
20642082 EffectivePayloadCases);
20652083 Size += tagCounts.numTagBytes ;
@@ -2091,7 +2109,6 @@ class EnumTypeInfoBuilder {
20912109 unsigned Stride = ((Size + Alignment - 1 ) & ~(Alignment - 1 ));
20922110 if (Stride == 0 )
20932111 Stride = 1 ;
2094- auto PayloadSize = EnumTypeInfo::getPayloadSizeForCases (Cases);
20952112
20962113 // Compute the spare bit mask and determine if we have any address-only fields
20972114 auto localSpareBitMask = BitMask::oneMask (Size);
@@ -2103,44 +2120,11 @@ class EnumTypeInfoBuilder {
21032120 }
21042121 }
21052122
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-
21422123 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.
21442128 return TC.makeTypeInfo <TaggedMultiPayloadEnumTypeInfo>(
21452129 Size, Alignment, Stride, NumExtraInhabitants,
21462130 BitwiseTakable, Cases, EffectivePayloadCases);
0 commit comments