Skip to content

Commit 6cf1aa3

Browse files
authored
Merge pull request #14399 from xedin/field-desc-for-imported-structs-2.0
[Reflection] Add support for imported structs with recorded fields (attempt #2)
2 parents fd88c72 + 8f05d64 commit 6cf1aa3

File tree

6 files changed

+48
-6
lines changed

6 files changed

+48
-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/GenMeta.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5618,7 +5618,9 @@ IRGenModule::getAddrOfForeignTypeMetadataCandidate(CanType type) {
56185618
} else if (auto structType = dyn_cast<StructType>(type)) {
56195619
auto structDecl = structType->getDecl();
56205620
assert(isa<ClangModuleUnit>(structDecl->getModuleScopeContext()));
5621-
5621+
5622+
ImportedStructs.insert(structDecl);
5623+
56225624
ForeignStructMetadataBuilder builder(*this, structDecl, init);
56235625
builder.layout();
56245626
addressPoint = builder.getOffsetOfAddressPoint();

lib/IRGen/GenReflection.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,13 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
368368
B.addInt16(fieldRecordSize);
369369

370370
// Imported classes don't need field descriptors
371-
if (NTD->hasClangNode()) {
372-
assert(isa<ClassDecl>(NTD));
371+
if (NTD->hasClangNode() && isa<ClassDecl>(NTD)) {
373372
B.addInt32(0);
374373
return;
375374
}
376375

376+
assert(!NTD->hasClangNode() || isa<StructDecl>(NTD));
377+
377378
auto properties = NTD->getStoredProperties();
378379
B.addInt32(std::distance(properties.begin(), properties.end()));
379380
for (auto property : properties)
@@ -435,6 +436,7 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
435436
void layout() override {
436437
if (NTD->hasClangNode() &&
437438
!isa<ClassDecl>(NTD) &&
439+
!isa<StructDecl>(NTD) &&
438440
!isa<ProtocolDecl>(NTD))
439441
return;
440442

@@ -941,6 +943,9 @@ void IRGenModule::emitBuiltinReflectionMetadata() {
941943
for (auto PD : ImportedProtocols)
942944
emitFieldMetadataRecord(PD);
943945

946+
for (auto SD : ImportedStructs)
947+
emitFieldMetadataRecord(SD);
948+
944949
for (auto builtinType : BuiltinTypes)
945950
emitBuiltinTypeMetadataRecord(builtinType);
946951

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)