mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IRGen: Fix reflection metadata for zero-sized enum cases
If an enum has a payload case with zero size, we treat it as an empty case for ABI purposes. Unfortunately, this meant that reflection metadata was incomplete for such cases, with a Mirror reporting that the enum value had zero children. Tweak the field type metadata emission slightly to preserve the payload type for such enum cases. Fixes <https://bugs.swift.org/browse/SR-12044> / <rdar://problem/58861157>.
This commit is contained in:
@@ -673,7 +673,7 @@ private:
|
||||
const NominalTypeDecl *NTD;
|
||||
|
||||
void addFieldDecl(const ValueDecl *value, Type type,
|
||||
GenericSignature genericSig, bool indirect=false) {
|
||||
bool indirect=false) {
|
||||
reflection::FieldRecordFlags flags;
|
||||
flags.setIsIndirectCase(indirect);
|
||||
if (auto var = dyn_cast<VarDecl>(value))
|
||||
@@ -684,6 +684,8 @@ private:
|
||||
if (!type) {
|
||||
B.addInt32(0);
|
||||
} else {
|
||||
auto genericSig = NTD->getGenericSignature();
|
||||
|
||||
// The standard library's Mirror demangles metadata from field
|
||||
// descriptors, so use MangledTypeRefRole::Metadata to ensure
|
||||
// runtime metadata is available.
|
||||
@@ -717,8 +719,7 @@ private:
|
||||
auto properties = NTD->getStoredProperties();
|
||||
B.addInt32(properties.size());
|
||||
for (auto property : properties)
|
||||
addFieldDecl(property, property->getInterfaceType(),
|
||||
NTD->getGenericSignature());
|
||||
addFieldDecl(property, property->getInterfaceType());
|
||||
}
|
||||
|
||||
void layoutEnum() {
|
||||
@@ -743,12 +744,11 @@ private:
|
||||
bool indirect = (enumCase.decl->isIndirect() ||
|
||||
enumDecl->isIndirect());
|
||||
addFieldDecl(enumCase.decl, enumCase.decl->getArgumentInterfaceType(),
|
||||
enumDecl->getGenericSignature(),
|
||||
indirect);
|
||||
}
|
||||
|
||||
for (auto enumCase : strategy.getElementsWithNoPayload()) {
|
||||
addFieldDecl(enumCase.decl, CanType(), nullptr);
|
||||
addFieldDecl(enumCase.decl, enumCase.decl->getArgumentInterfaceType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user