Skip to content

Commit b2f1260

Browse files
authored
Merge pull request #14185 from xedin/field-desc-for-imported-structs
[WIP][IRGen] Emit type field descriptors for imported structs
2 parents 10fedbe + 9e08ea4 commit b2f1260

File tree

5 files changed

+59
-6
lines changed

5 files changed

+59
-6
lines changed

include/swift/Reflection/Records.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ class FieldDescriptor {
186186
Kind == FieldDescriptorKind::ObjCProtocol);
187187
}
188188

189+
bool isStruct() const {
190+
return Kind == FieldDescriptorKind::Struct;
191+
}
192+
189193
const_iterator begin() const {
190194
auto Begin = getFieldRecordBuffer();
191195
auto End = Begin + NumFields;

lib/IRGen/GenReflection.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,12 @@ class ReflectionMetadataBuilder {
195195
IGM.ImportedClasses.insert(CD);
196196
else if (auto PD = dyn_cast<ProtocolDecl>(Nominal))
197197
IGM.ImportedProtocols.insert(PD);
198-
else
198+
else {
199+
if (auto *SD = dyn_cast<StructDecl>(Nominal))
200+
IGM.ImportedStructs.insert(SD);
201+
199202
IGM.OpaqueTypes.insert(Nominal);
203+
}
200204
}
201205
});
202206
}
@@ -341,6 +345,15 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
341345
} else {
342346
addTypeRef(value->getModuleContext(), type);
343347
addBuiltinTypeRefs(type);
348+
349+
// Trigger foreign struct metadata generation for each field,
350+
// this is going to be used later on by reflection library.
351+
type.visit([&](CanType nestedType) {
352+
if (auto *NTD = nestedType->getAnyNominal()) {
353+
if (NTD->hasClangNode() && isa<StructDecl>(NTD))
354+
(void) IGM.getAddrOfForeignTypeMetadataCandidate(nestedType);
355+
}
356+
});
344357
}
345358

346359
if (IGM.IRGen.Opts.EnableReflectionNames) {
@@ -368,12 +381,13 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
368381
B.addInt16(fieldRecordSize);
369382

370383
// Imported classes don't need field descriptors
371-
if (NTD->hasClangNode()) {
372-
assert(isa<ClassDecl>(NTD));
384+
if (NTD->hasClangNode() && isa<ClassDecl>(NTD)) {
373385
B.addInt32(0);
374386
return;
375387
}
376388

389+
assert(!NTD->hasClangNode() || isa<StructDecl>(NTD));
390+
377391
auto properties = NTD->getStoredProperties();
378392
B.addInt32(std::distance(properties.begin(), properties.end()));
379393
for (auto property : properties)
@@ -435,6 +449,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
435449
void layout() override {
436450
if (NTD->hasClangNode() &&
437451
!isa<ClassDecl>(NTD) &&
452+
!isa<StructDecl>(NTD) &&
438453
!isa<ProtocolDecl>(NTD))
439454
return;
440455

@@ -941,6 +956,9 @@ void IRGenModule::emitBuiltinReflectionMetadata() {
941956
for (auto PD : ImportedProtocols)
942957
emitFieldMetadataRecord(PD);
943958

959+
for (auto SD : ImportedStructs)
960+
emitFieldMetadataRecord(SD);
961+
944962
for (auto builtinType : BuiltinTypes)
945963
emitBuiltinTypeMetadataRecord(builtinType);
946964

lib/IRGen/IRGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,9 @@ class IRGenModule {
920920
/// Imported protocols referenced by types in this module when emitting
921921
/// reflection metadata.
922922
llvm::SetVector<const ProtocolDecl *> ImportedProtocols;
923+
/// Imported structs referenced by types in this module when emitting
924+
/// reflection metadata.
925+
llvm::SetVector<const StructDecl *> ImportedStructs;
923926

924927
llvm::Constant *getAddrOfStringForTypeRef(StringRef Str);
925928
llvm::Constant *getAddrOfFieldName(StringRef Name);

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,16 +1057,18 @@ class LowerType
10571057

10581058
const TypeInfo *visitAnyNominalTypeRef(const TypeRef *TR) {
10591059
const auto &FD = TC.getBuilder().getFieldTypeInfo(TR);
1060-
if (FD.first == nullptr) {
1060+
if (FD.first == nullptr || FD.first->isStruct()) {
10611061
// Maybe this type is opaque -- look for a builtin
10621062
// descriptor to see if we at least know its size
10631063
// and alignment.
10641064
if (auto ImportedTypeDescriptor = TC.getBuilder().getBuiltinTypeInfo(TR))
10651065
return TC.makeTypeInfo<BuiltinTypeInfo>(ImportedTypeDescriptor);
10661066

10671067
// Otherwise, we're out of luck.
1068-
DEBUG(std::cerr << "No TypeInfo for nominal type: "; TR->dump());
1069-
return nullptr;
1068+
if (FD.first == nullptr) {
1069+
DEBUG(std::cerr << "No TypeInfo for nominal type: "; TR->dump());
1070+
return nullptr;
1071+
}
10701072
}
10711073

10721074
switch (FD.first->Kind) {

test/Reflection/typeref_decoding_imported.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@
2020
// CHECK-32: mce: __C.MyCEnum
2121
// CHECK-32: (struct __C.MyCEnum)
2222

23+
// CHECK-32: __C.MyCStruct
24+
// CHECK-32: -------------
25+
// CHECK-32: i: Swift.Int32
26+
// CHECK-32: (struct Swift.Int32)
27+
28+
// CHECK-32: ip: Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int32>>
29+
// CHECK-32: (bound_generic_enum Swift.Optional
30+
// CHECK-32: (bound_generic_struct Swift.UnsafeMutablePointer
31+
// CHECK-32: (struct Swift.Int32)))
32+
33+
// CHECK-32: c: Swift.Int8
34+
// CHECK-32: (struct Swift.Int8)
35+
2336
// CHECK-32: TypesToReflect.AlsoHasCTypes
2437
// CHECK-32: ----------------------------
2538

@@ -82,6 +95,19 @@
8295
// CHECK-64: mcu: __C.MyCUnion
8396
// CHECK-64: (struct __C.MyCUnion)
8497

98+
// CHECK-64: __C.MyCStruct
99+
// CHECK-64: -------------
100+
// CHECK-64: i: Swift.Int32
101+
// CHECK-64: (struct Swift.Int32)
102+
103+
// CHECK-64: ip: Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int32>>
104+
// CHECK-64: (bound_generic_enum Swift.Optional
105+
// CHECK-64: (bound_generic_struct Swift.UnsafeMutablePointer
106+
// CHECK-64: (struct Swift.Int32)))
107+
108+
// CHECK-64: c: Swift.Int8
109+
// CHECK-64: (struct Swift.Int8)
110+
85111
// CHECK-64: TypesToReflect.AlsoHasCTypes
86112
// CHECK-64: ----------------------------
87113

0 commit comments

Comments
 (0)