[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

@@ -589,6 +589,15 @@ unsigned irgen::getNumFields(const NominalTypeDecl *target) {
return numFields;
}
bool irgen::isExportableField(Field field) {
if (field.getKind() == Field::Kind::Var &&
field.getVarDecl()->getClangDecl() &&
field.getVarDecl()->getFormalAccess() == AccessLevel::Private)
return false;
// All other fields are exportable
return true;
}
void irgen::forEachField(IRGenModule &IGM, const NominalTypeDecl *typeDecl,
llvm::function_ref<void(Field field)> fn) {
auto classDecl = dyn_cast<ClassDecl>(typeDecl);
@@ -610,6 +619,17 @@ void irgen::forEachField(IRGenModule &IGM, const NominalTypeDecl *typeDecl,
}
}
unsigned irgen::countExportableFields(IRGenModule &IGM,
const NominalTypeDecl *type) {
// Don't count private C++ fields that were imported as private Swift fields
unsigned exportableFieldCount = 0;
forEachField(IGM, type, [&](Field field) {
if (isExportableField(field))
++exportableFieldCount;
});
return exportableFieldCount;
}
SILType Field::getType(IRGenModule &IGM, SILType baseType) const {
switch (getKind()) {
case Field::Var: