Skip to content

Commit 219b4a6

Browse files
authored
Merge pull request #74439 from tbkka/tbkka-remotemirror-mpe-removal-fix
Fix an ABI break
2 parents 9121b26 + 05c74e0 commit 219b4a6

File tree

11 files changed

+325
-25
lines changed

11 files changed

+325
-25
lines changed

include/swift/RemoteInspection/DescriptorFinder.h

+11-17
Original file line numberDiff line numberDiff line change
@@ -93,31 +93,26 @@ struct FieldDescriptorBase {
9393
getFieldRecords() = 0;
9494
};
9595

96-
// There are no longer any clients of this interface, but we
97-
// need to keep this stubbed out until all the
98-
// implementors have been removed. In particular, LLDB
99-
// still implements this interface.
100-
// TODO: Delete this after Swift 6.0 ships
10196
struct MultiPayloadEnumDescriptorBase {
102-
virtual ~MultiPayloadEnumDescriptorBase(){ abort(); };
97+
virtual ~MultiPayloadEnumDescriptorBase(){};
10398

104-
virtual llvm::StringRef getMangledTypeName() { abort(); };
99+
virtual llvm::StringRef getMangledTypeName() = 0;
105100

106-
virtual uint32_t getContentsSizeInWords() const { abort(); };
101+
virtual uint32_t getContentsSizeInWords() const = 0;
107102

108-
virtual size_t getSizeInBytes() const { abort(); };
103+
virtual size_t getSizeInBytes() const = 0;
109104

110-
virtual uint32_t getFlags() const { abort(); };
105+
virtual uint32_t getFlags() const = 0;
111106

112-
virtual bool usesPayloadSpareBits() const { abort(); };
107+
virtual bool usesPayloadSpareBits() const = 0;
113108

114-
virtual uint32_t getPayloadSpareBitMaskByteOffset() const { abort(); };
109+
virtual uint32_t getPayloadSpareBitMaskByteOffset() const = 0;
115110

116-
virtual uint32_t getPayloadSpareBitMaskByteCount() const { abort(); };
111+
virtual uint32_t getPayloadSpareBitMaskByteCount() const = 0;
117112

118-
virtual const uint8_t *getPayloadSpareBits() const { abort(); };
119-
};
113+
virtual const uint8_t *getPayloadSpareBits() const = 0;
120114

115+
};
121116
/// Interface for finding type descriptors. Implementors may provide descriptors
122117
/// that live inside or outside reflection metadata.
123118
struct DescriptorFinder {
@@ -130,9 +125,8 @@ struct DescriptorFinder {
130125
virtual std::unique_ptr<FieldDescriptorBase>
131126
getFieldDescriptor(const TypeRef *TR) = 0;
132127

133-
// TODO: Delete this as soon as LLDB no longer attempts to override it
134128
virtual std::unique_ptr<MultiPayloadEnumDescriptorBase>
135-
getMultiPayloadEnumDescriptor(const TypeRef *TR) { abort(); };
129+
getMultiPayloadEnumDescriptor(const TypeRef *TR) = 0;
136130
};
137131

138132
} // namespace reflection

include/swift/RemoteInspection/Records.h

+105
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,111 @@ class BuiltinTypeDescriptor {
378378
}
379379
};
380380

381+
class MultiPayloadEnumDescriptor {
382+
public:
383+
const RelativeDirectPointer<const char> TypeName;
384+
385+
private:
386+
// This descriptor contains a series of 32-bit words
387+
uint32_t contents[];
388+
389+
// Properties are stored in `contents` at particular indexes:
390+
391+
// uint32_t SizeFlags;
392+
// Upper 16 bits are the size of the contents (in 32-bit words):
393+
// (This allows us to expand this structure in the future;
394+
// new fields should have accessors that test whether the
395+
// size is large enough and return "non-existent" if the
396+
// descriptor isn't large enough to have that field.)
397+
// Lower 16 bits are flag bits
398+
399+
int getSizeFlagsIndex() const { return 0; }
400+
401+
// uint32_t PayloadSpareBitMaskByteOffsetCount;
402+
// Number of bytes in "payload spare bits", and
403+
// offset of them within the payload area
404+
// Only present if `usePayloadSpareBits()`
405+
406+
int getPayloadSpareBitMaskByteCountIndex() const {
407+
return getSizeFlagsIndex() + 1;
408+
}
409+
410+
// uint8_t *PayloadSpareBits;
411+
// Variably-sized bitmask field (padded to a multiple of 4 bytes)
412+
// Only present if `usePayloadSpareBits()`
413+
414+
int getPayloadSpareBitsIndex() const {
415+
int PayloadSpareBitMaskByteCountFieldSize = usesPayloadSpareBits() ? 1 : 0;
416+
return getPayloadSpareBitMaskByteCountIndex() + PayloadSpareBitMaskByteCountFieldSize;
417+
}
418+
419+
// uint32_t foo;
420+
// TODO: Some future field
421+
// int getFooIndex() const {
422+
// int PayloadSpareBitMaskFieldSize = (getPayloadSpareBitMaskByteCount() + 3) / 4;
423+
// return getPayloadSpareBitsIndex() + PayloadSpareBitMaskFieldSize;
424+
// }
425+
426+
// uint32_t getFoo() const {
427+
// if (getFooIndex() < getContentsSizeInWords()) {
428+
// return contents[getFooIndex()];
429+
// } else {
430+
// return 0; // Field isn't present
431+
// }
432+
// }
433+
434+
public:
435+
//
436+
// Data derived from the above...
437+
//
438+
439+
uint32_t getContentsSizeInWords() const {
440+
return contents[getSizeFlagsIndex()] >> 16;
441+
}
442+
443+
size_t getSizeInBytes() const {
444+
// assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
445+
size_t sizeInBytes = sizeof(TypeName) + getContentsSizeInWords() * 4;
446+
return sizeInBytes;
447+
}
448+
449+
uint32_t getFlags() const {
450+
assert(getContentsSizeInWords() > 0 && "Malformed MPEnum reflection record");
451+
return contents[getSizeFlagsIndex()] & 0xffff;
452+
}
453+
454+
bool usesPayloadSpareBits() const {
455+
return getFlags() & 1;
456+
}
457+
458+
uint32_t getPayloadSpareBitMaskByteOffset() const {
459+
if (usesPayloadSpareBits()) {
460+
return contents[getPayloadSpareBitMaskByteCountIndex()] >> 16;
461+
} else {
462+
return 0;
463+
}
464+
}
465+
466+
uint32_t getPayloadSpareBitMaskByteCount() const {
467+
if (usesPayloadSpareBits()) {
468+
auto byteCount = contents[getPayloadSpareBitMaskByteCountIndex()] & 0xffff;
469+
assert(getContentsSizeInWords() >= 2 + (byteCount + 3) / 4
470+
&& "Malformed MPEnum reflection record: mask bigger than record");
471+
return byteCount;
472+
} else {
473+
return 0;
474+
}
475+
}
476+
477+
const uint8_t *getPayloadSpareBits() const {
478+
if (usesPayloadSpareBits()) {
479+
return reinterpret_cast<const uint8_t *>(&contents[getPayloadSpareBitsIndex()]);
480+
} else {
481+
return nullptr;
482+
}
483+
}
484+
};
485+
381486
class CaptureTypeRecord {
382487
public:
383488
const RelativeDirectPointer<const char> MangledTypeName;

include/swift/RemoteInspection/ReflectionContext.h

+21-6
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,17 @@ class ReflectionContext
335335
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
336336
auto ConformMdSec = findMachOSectionByName(
337337
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
338+
auto MPEnumMdSec = findMachOSectionByName(
339+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));
338340

339341
if (FieldMdSec.first == nullptr &&
340342
AssocTySec.first == nullptr &&
341343
BuiltinTySec.first == nullptr &&
342344
CaptureSec.first == nullptr &&
343345
TypeRefMdSec.first == nullptr &&
344346
ReflStrMdSec.first == nullptr &&
345-
ConformMdSec.first == nullptr)
347+
ConformMdSec.first == nullptr &&
348+
MPEnumMdSec.first == nullptr)
346349
return {};
347350

348351
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
@@ -352,6 +355,7 @@ class ReflectionContext
352355
{TypeRefMdSec.first, TypeRefMdSec.second},
353356
{ReflStrMdSec.first, ReflStrMdSec.second},
354357
{ConformMdSec.first, ConformMdSec.second},
358+
{MPEnumMdSec.first, MPEnumMdSec.second},
355359
PotentialModuleNames};
356360

357361
auto InfoID = this->addReflectionInfo(info);
@@ -466,14 +470,17 @@ class ReflectionContext
466470
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr));
467471
auto ConformMdSec = findCOFFSectionByName(
468472
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform));
473+
auto MPEnumMdSec = findCOFFSectionByName(
474+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum));
469475

470476
if (FieldMdSec.first == nullptr &&
471477
AssocTySec.first == nullptr &&
472478
BuiltinTySec.first == nullptr &&
473479
CaptureSec.first == nullptr &&
474480
TypeRefMdSec.first == nullptr &&
475481
ReflStrMdSec.first == nullptr &&
476-
ConformMdSec.first == nullptr)
482+
ConformMdSec.first == nullptr &&
483+
MPEnumMdSec.first == nullptr)
477484
return {};
478485

479486
ReflectionInfo Info = {{FieldMdSec.first, FieldMdSec.second},
@@ -483,6 +490,7 @@ class ReflectionContext
483490
{TypeRefMdSec.first, TypeRefMdSec.second},
484491
{ReflStrMdSec.first, ReflStrMdSec.second},
485492
{ConformMdSec.first, ConformMdSec.second},
493+
{MPEnumMdSec.first, MPEnumMdSec.second},
486494
PotentialModuleNames};
487495
return this->addReflectionInfo(Info);
488496
}
@@ -679,6 +687,9 @@ class ReflectionContext
679687
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr), true);
680688
auto ConformMdSec = findELFSectionByName(
681689
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform), true);
690+
auto MPEnumMdSec = findELFSectionByName(
691+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum), true);
692+
682693
if (Error)
683694
return {};
684695

@@ -688,14 +699,15 @@ class ReflectionContext
688699
// ELF executable.
689700
if (FieldMdSec.first || AssocTySec.first || BuiltinTySec.first ||
690701
CaptureSec.first || TypeRefMdSec.first || ReflStrMdSec.first ||
691-
ConformMdSec.first) {
702+
ConformMdSec.first || MPEnumMdSec.first) {
692703
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
693704
{AssocTySec.first, AssocTySec.second},
694705
{BuiltinTySec.first, BuiltinTySec.second},
695706
{CaptureSec.first, CaptureSec.second},
696707
{TypeRefMdSec.first, TypeRefMdSec.second},
697708
{ReflStrMdSec.first, ReflStrMdSec.second},
698709
{ConformMdSec.first, ConformMdSec.second},
710+
{MPEnumMdSec.first, MPEnumMdSec.second},
699711
PotentialModuleNames};
700712
result = this->addReflectionInfo(info);
701713
}
@@ -718,20 +730,23 @@ class ReflectionContext
718730
ObjectFileFormat.getSectionName(ReflectionSectionKind::reflstr), false);
719731
ConformMdSec = findELFSectionByName(
720732
ObjectFileFormat.getSectionName(ReflectionSectionKind::conform), false);
733+
MPEnumMdSec = findELFSectionByName(
734+
ObjectFileFormat.getSectionName(ReflectionSectionKind::mpenum), false);
721735

722736
if (Error)
723737
return {};
724738

725739
if (FieldMdSec.first || AssocTySec.first || BuiltinTySec.first ||
726740
CaptureSec.first || TypeRefMdSec.first || ReflStrMdSec.first ||
727-
ConformMdSec.first) {
741+
ConformMdSec.first || MPEnumMdSec.first) {
728742
ReflectionInfo info = {{FieldMdSec.first, FieldMdSec.second},
729743
{AssocTySec.first, AssocTySec.second},
730744
{BuiltinTySec.first, BuiltinTySec.second},
731745
{CaptureSec.first, CaptureSec.second},
732746
{TypeRefMdSec.first, TypeRefMdSec.second},
733747
{ReflStrMdSec.first, ReflStrMdSec.second},
734748
{ConformMdSec.first, ConformMdSec.second},
749+
{MPEnumMdSec.first, MPEnumMdSec.second},
735750
PotentialModuleNames};
736751
auto rid = this->addReflectionInfo(info);
737752
if (!result)
@@ -846,8 +861,7 @@ class ReflectionContext
846861
ReflectionSectionKind::fieldmd, ReflectionSectionKind::assocty,
847862
ReflectionSectionKind::builtin, ReflectionSectionKind::capture,
848863
ReflectionSectionKind::typeref, ReflectionSectionKind::reflstr,
849-
ReflectionSectionKind::conform
850-
};
864+
ReflectionSectionKind::conform, ReflectionSectionKind::mpenum};
851865

852866
llvm::SmallVector<std::pair<RemoteRef<void>, uint64_t>, 6> Pairs;
853867
for (auto Section : Sections) {
@@ -873,6 +887,7 @@ class ReflectionContext
873887
{Pairs[4].first, Pairs[4].second},
874888
{Pairs[5].first, Pairs[5].second},
875889
{Pairs[6].first, Pairs[6].second},
890+
{Pairs[7].first, Pairs[7].second},
876891
PotentialModuleNames};
877892
return addReflectionInfo(Info);
878893
}

include/swift/RemoteInspection/RuntimeHeaders/llvm/BinaryFormat/Swift.def

+1
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ HANDLE_SWIFT_SECTION(protocs, "__swift5_protos", "swift5_protocols",
3030
".sw5prt$B")
3131
HANDLE_SWIFT_SECTION(acfuncs, "__swift5_acfuncs", "swift5_accessible_functions",
3232
".sw5acfn$B")
33+
HANDLE_SWIFT_SECTION(mpenum, "__swift5_mpenum", "swift5_mpenum", ".sw5mpen$B")

include/swift/RemoteInspection/TypeRefBuilder.h

+36-2
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ class CaptureDescriptorIterator
231231
};
232232
using CaptureSection = ReflectionSection<CaptureDescriptorIterator>;
233233

234+
class MultiPayloadEnumDescriptorIterator
235+
: public ReflectionSectionIteratorBase<MultiPayloadEnumDescriptorIterator,
236+
MultiPayloadEnumDescriptor> {
237+
public:
238+
MultiPayloadEnumDescriptorIterator(RemoteRef<void> Cur, uint64_t Size)
239+
: ReflectionSectionIteratorBase(Cur, Size, "MultiPayloadEnum") {}
240+
241+
static uint64_t
242+
getCurrentRecordSize(RemoteRef<MultiPayloadEnumDescriptor> MPER) {
243+
return MPER->getSizeInBytes();
244+
}
245+
};
246+
using MultiPayloadEnumSection =
247+
ReflectionSection<MultiPayloadEnumDescriptorIterator>;
248+
234249
using GenericSection = ReflectionSection<const void *>;
235250

236251
struct ReflectionInfo {
@@ -241,6 +256,7 @@ struct ReflectionInfo {
241256
GenericSection TypeReference;
242257
GenericSection ReflectionString;
243258
GenericSection Conformance;
259+
MultiPayloadEnumSection MultiPayloadEnum;
244260
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames;
245261
};
246262

@@ -474,6 +490,10 @@ class TypeRefBuilder {
474490
/// Get the unsubstituted capture types for a closure context.
475491
ClosureContextInfo getClosureContextInfo(RemoteRef<CaptureDescriptor> CD);
476492

493+
/// Get the multipayload enum projection information for a given TR
494+
std::unique_ptr<MultiPayloadEnumDescriptorBase>
495+
getMultiPayloadEnumDescriptor(const TypeRef *TR) override;
496+
477497
const TypeRef *lookupTypeWitness(const std::string &MangledTypeName,
478498
const std::string &Member,
479499
StringRef Protocol);
@@ -496,6 +516,8 @@ class TypeRefBuilder {
496516
/// Load unsubstituted field types for a nominal type.
497517
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
498518

519+
RemoteRef<MultiPayloadEnumDescriptor> getMultiPayloadEnumInfo(const TypeRef *TR);
520+
499521
void populateFieldTypeInfoCacheWithReflectionAtIndex(size_t Index);
500522

501523
std::optional<RemoteRef<FieldDescriptor>>
@@ -545,7 +567,8 @@ class TypeRefBuilder {
545567

546568
public:
547569
///
548-
/// Dumping typerefs, field declarations, builtin types, captures
570+
/// Dumping typerefs, field declarations, builtin types, captures,
571+
/// multi-payload enums
549572
///
550573
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
551574
bool printTypeName = false);
@@ -554,6 +577,7 @@ class TypeRefBuilder {
554577
void dumpFieldSection(std::ostream &stream);
555578
void dumpBuiltinTypeSection(std::ostream &stream);
556579
void dumpCaptureSection(std::ostream &stream);
580+
void dumpMultiPayloadEnumSection(std::ostream &stream);
557581

558582
template <template <typename Runtime> class ObjCInteropKind,
559583
unsigned PointerSize>
@@ -793,6 +817,10 @@ class TypeRefBuilder {
793817
stream << "=============\n";
794818
dumpConformanceSection<ObjCInteropKind, PointerSize>(stream);
795819
stream << "\n";
820+
stream << "MULTI-PAYLOAD ENUM DESCRIPTORS:\n";
821+
stream << "===============================\n";
822+
dumpMultiPayloadEnumSection(stream);
823+
stream << "\n";
796824
}
797825
};
798826
friend struct ReflectionTypeDescriptorFinder;
@@ -1549,10 +1577,17 @@ class TypeRefBuilder {
15491577
return RDF.getClosureContextInfo(CD);
15501578
}
15511579

1580+
/// Get the multipayload enum projection information for a given TR
1581+
std::unique_ptr<MultiPayloadEnumDescriptorBase>
1582+
getMultiPayloadEnumDescriptor(const TypeRef *TR);
1583+
15521584
private:
15531585
/// Get the primitive type lowering for a builtin type.
15541586
RemoteRef<BuiltinTypeDescriptor> getBuiltinTypeInfo(const TypeRef *TR);
15551587

1588+
RemoteRef<MultiPayloadEnumDescriptor>
1589+
getMultiPayloadEnumInfo(const TypeRef *TR);
1590+
15561591
std::optional<uint64_t> multiPayloadEnumPointerMask;
15571592

15581593
public:
@@ -1582,7 +1617,6 @@ class TypeRefBuilder {
15821617
}
15831618
return multiPayloadEnumPointerMask.value();
15841619
}
1585-
15861620
FieldTypeCollectionResult
15871621
collectFieldTypes(std::optional<std::string> forMangledTypeName) {
15881622
return RDF.collectFieldTypes(forMangledTypeName);

0 commit comments

Comments
 (0)