[cxx-interop] Fix metadata mismatch regarding fields of structs

In https://github.com/swiftlang/swift/pull/78467 and https://github.com/swiftlang/swift/pull/78961, we stopped emitting metadata for private C++ fields. However, this created a mismatch between the fields emitted and the number of fields + their offsets in the StructDescriptor.

rdar://147263490
(cherry picked from commit 72b13b3b48)
This commit is contained in:
susmonteiro
2025-05-20 10:15:14 +01:00
parent 8079f1b12b
commit d81d6547ba
12 changed files with 335 additions and 29 deletions

View File

@@ -946,35 +946,13 @@ private:
B.addInt16(uint16_t(kind));
B.addInt16(FieldRecordSize);
// Filter to select which fields we'll export FieldDescriptors for.
auto exportable_field =
[](Field field) {
// Don't export private C++ fields that were imported as private Swift fields.
// The type of a private field might not have all the type witness
// operations that Swift requires, for instance,
// `std::unique_ptr<IncompleteType>` would not have a destructor.
if (field.getKind() == Field::Kind::Var &&
field.getVarDecl()->getClangDecl() &&
field.getVarDecl()->getFormalAccess() == AccessLevel::Private)
return false;
// All other fields are exportable
return true;
};
// Count exportable fields
int exportableFieldCount = 0;
forEachField(IGM, NTD, [&](Field field) {
if (exportable_field(field)) {
++exportableFieldCount;
}
});
// Emit exportable fields, prefixed with a count
B.addInt32(exportableFieldCount);
B.addInt32(countExportableFields(IGM, NTD));
// Filter to select which fields we'll export FieldDescriptor for.
forEachField(IGM, NTD, [&](Field field) {
if (exportable_field(field)) {
if (isExportableField(field))
addField(field);
}
});
}