Skip to content

Commit 97fd1a7

Browse files
committed
Reflection: Emit field metadata for @objc classes
While we can skip emitting metadata for imported classes (clients should ask the Objective-C runtime instead) it was not correct to do so for Swift-defined classes that used Objective-C reference counting.
1 parent e2cf23d commit 97fd1a7

File tree

2 files changed

+117
-160
lines changed

2 files changed

+117
-160
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -372,25 +372,33 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
372372
auto type = NTD->getDeclaredType()->getCanonicalType();
373373
addTypeRef(NTD->getModuleContext(), type);
374374

375-
if (auto CD = dyn_cast<ClassDecl>(NTD)) {
376-
auto RC = getReferenceCountingForClass(IGM, const_cast<ClassDecl *>(CD));
377-
if (RC == ReferenceCounting::ObjC || CD->hasClangNode()) {
378-
addObjCClassRecord();
379-
return;
380-
}
381-
}
382-
383-
if (NTD->hasClangNode())
375+
if (NTD->hasClangNode() && !isa<ClassDecl>(NTD))
384376
return;
385377

386378
switch (NTD->getKind()) {
387379
case DeclKind::Class:
388380
case DeclKind::Struct: {
389-
auto properties = NTD->getStoredProperties();
390-
addConstantInt16(uint16_t(isa<StructDecl>(NTD)
391-
? FieldDescriptorKind::Struct
392-
: FieldDescriptorKind::Class));
381+
auto kind = FieldDescriptorKind::Struct;
382+
383+
if (auto CD = dyn_cast<ClassDecl>(NTD)) {
384+
auto RC = getReferenceCountingForClass(IGM, const_cast<ClassDecl *>(CD));
385+
if (RC == ReferenceCounting::ObjC)
386+
kind = FieldDescriptorKind::ObjCClass;
387+
else
388+
kind = FieldDescriptorKind::Class;
389+
}
390+
391+
addConstantInt16(uint16_t(kind));
393392
addConstantInt16(fieldRecordSize);
393+
394+
// Imported classes don't need field descriptors
395+
if (NTD->hasClangNode()) {
396+
assert(isa<ClassDecl>(NTD));
397+
addConstantInt32(0);
398+
break;
399+
}
400+
401+
auto properties = NTD->getStoredProperties();
394402
addConstantInt32(std::distance(properties.begin(), properties.end()));
395403
for (auto property : properties)
396404
addFieldDecl(property,
Lines changed: 96 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,151 +1,100 @@
11
// RUN: rm -rf %t && mkdir -p %t
22
// RUN: %target-build-swift %S/Inputs/ObjectiveCTypes.swift -parse-as-library -emit-module -emit-library -module-name TypesToReflect -o %t/libTypesToReflect.%target-dylib-extension
3-
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect.%target-dylib-extension | FileCheck %s --check-prefix=CHECK-%target-ptrsize
3+
// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect.%target-dylib-extension | FileCheck %s --check-prefix=CHECK
44
// REQUIRES: objc_interop
55

6-
// CHECK-32: FIELDS:
7-
// CHECK-32: =======
8-
// CHECK-32: TypesToReflect.OC
9-
// CHECK-32: -----------------
10-
// CHECK-32: TypesToReflect.GenericOC
11-
// CHECK-32: ------------------------
12-
// CHECK-32: TypesToReflect.HasObjCClasses
13-
// CHECK-32: -----------------------------
14-
// CHECK-32: url: __ObjC.NSURL
15-
// CHECK-32: (class __ObjC.NSURL)
16-
17-
// CHECK-32: integer: Swift.Int
18-
// CHECK-32: (struct Swift.Int)
19-
20-
// CHECK-32: __ObjC.NSBundle
21-
// CHECK-32: ---------------
22-
// CHECK-32: __ObjC.NSURL
23-
// CHECK-32: ------------
24-
25-
// CHECK-32: ASSOCIATED TYPES:
26-
// CHECK-32: =================
27-
28-
// CHECK-32: BUILTIN TYPES:
29-
// CHECK-32: ==============
30-
31-
// CHECK-32: - __C.CGRect:
32-
// CHECK-32: Size: 32
33-
// CHECK-32: Alignment: 8
34-
// CHECK-32: Stride: 32
35-
// CHECK-32: NumExtraInhabitants: 0
36-
37-
// CHECK-32: CAPTURE DESCRIPTORS:
38-
// CHECK-32: ====================
39-
// CHECK-32: - Capture types:
40-
// CHECK-32: (struct Swift.StaticString)
41-
// CHECK-32: (struct Swift.StaticString)
42-
// CHECK-32: (struct Swift.UInt)
43-
// CHECK-32: (struct Swift.UInt)
44-
// CHECK-32: - Metadata sources:
45-
46-
// CHECK-32: - Capture types:
47-
// CHECK-32: (function
48-
// CHECK-32: (tuple))
49-
// CHECK-32: - Metadata sources:
50-
51-
// CHECK-32: - Capture types:
52-
// CHECK-32: (struct Swift.StaticString)
53-
// CHECK-32: (bound_generic_struct Swift.UnsafeBufferPointer
54-
// CHECK-32: (struct Swift.UInt8))
55-
// CHECK-32: (struct Swift.UInt)
56-
// CHECK-32: (struct Swift.UInt)
57-
// CHECK-32: - Metadata sources:
58-
59-
// CHECK-32: - Capture types:
60-
// CHECK-32: (function
61-
// CHECK-32: (tuple))
62-
// CHECK-32: - Metadata sources:
63-
64-
// CHECK-32: - Capture types:
65-
// CHECK-32: (bound_generic_struct Swift.UnsafeBufferPointer
66-
// CHECK-32: (struct Swift.UInt8))
67-
// CHECK-32: (bound_generic_struct Swift.UnsafeBufferPointer
68-
// CHECK-32: (struct Swift.UInt8))
69-
// CHECK-32: (struct Swift.UInt)
70-
// CHECK-32: (struct Swift.UInt)
71-
// CHECK-32: - Metadata sources:
72-
73-
// CHECK-32: - Capture types:
74-
// CHECK-32: (function
75-
// CHECK-32: (tuple))
76-
// CHECK-32: - Metadata sources:
77-
78-
79-
// CHECK-64: FIELDS:
80-
// CHECK-64: =======
81-
// CHECK-64: TypesToReflect.OC
82-
// CHECK-64: -----------------
83-
// CHECK-64: TypesToReflect.GenericOC
84-
// CHECK-64: ------------------------
85-
// CHECK-64: TypesToReflect.HasObjCClasses
86-
// CHECK-64: -----------------------------
87-
// CHECK-64: url: __ObjC.NSURL
88-
// CHECK-64: (class __ObjC.NSURL)
89-
90-
// CHECK-64: integer: Swift.Int
91-
// CHECK-64: (struct Swift.Int)
92-
93-
// CHECK-64: __ObjC.NSBundle
94-
// CHECK-64: ------------
95-
96-
// CHECK-64: __ObjC.NSURL
97-
// CHECK-64: ------------
98-
99-
// CHECK-64: ASSOCIATED TYPES:
100-
// CHECK-64: =================
101-
102-
// CHECK-64: BUILTIN TYPES:
103-
// CHECK-64: ==============
104-
105-
// CHECK-64: - __C.CGRect:
106-
// CHECK-64: Size: 32
107-
// CHECK-64: Alignment: 8
108-
// CHECK-64: Stride: 32
109-
// CHECK-64: NumExtraInhabitants: 0
110-
111-
// CHECK-64: CAPTURE DESCRIPTORS:
112-
// CHECK-64: ====================
113-
// CHECK-64: - Capture types:
114-
// CHECK-64: (struct Swift.StaticString)
115-
// CHECK-64: (struct Swift.StaticString)
116-
// CHECK-64: (struct Swift.UInt)
117-
// CHECK-64: (struct Swift.UInt)
118-
// CHECK-64: - Metadata sources:
119-
120-
// CHECK-64: - Capture types:
121-
// CHECK-64: (function
122-
// CHECK-64: (tuple))
123-
// CHECK-64: - Metadata sources:
124-
125-
// CHECK-64: - Capture types:
126-
// CHECK-64: (struct Swift.StaticString)
127-
// CHECK-64: (bound_generic_struct Swift.UnsafeBufferPointer
128-
// CHECK-64: (struct Swift.UInt8))
129-
// CHECK-64: (struct Swift.UInt)
130-
// CHECK-64: (struct Swift.UInt)
131-
// CHECK-64: - Metadata sources:
132-
133-
// CHECK-64: - Capture types:
134-
// CHECK-64: (function
135-
// CHECK-64: (tuple))
136-
// CHECK-64: - Metadata sources:
137-
138-
// CHECK-64: - Capture types:
139-
// CHECK-64: (bound_generic_struct Swift.UnsafeBufferPointer
140-
// CHECK-64: (struct Swift.UInt8))
141-
// CHECK-64: (bound_generic_struct Swift.UnsafeBufferPointer
142-
// CHECK-64: (struct Swift.UInt8))
143-
// CHECK-64: (struct Swift.UInt)
144-
// CHECK-64: (struct Swift.UInt)
145-
// CHECK-64: - Metadata sources:
146-
147-
// CHECK-64: - Capture types:
148-
// CHECK-64: (function
149-
// CHECK-64: (tuple))
150-
// CHECK-64: - Metadata sources:
151-
6+
// CHECK: FIELDS:
7+
// CHECK: =======
8+
// CHECK: TypesToReflect.OC
9+
// CHECK: -----------------
10+
// CHECK: nsObject: __ObjC.NSObject
11+
// CHECK: (class __ObjC.NSObject)
12+
13+
// CHECK: nsString: __ObjC.NSString
14+
// CHECK: (class __ObjC.NSString)
15+
16+
// CHECK: cfString: __ObjC.CFString
17+
// CHECK: (class __ObjC.CFString)
18+
19+
// CHECK: aBlock: @convention(block) () -> ()
20+
// CHECK: (function convention=block
21+
// CHECK: (tuple))
22+
23+
// CHECK: TypesToReflect.GenericOC
24+
// CHECK: ------------------------
25+
// CHECK: ocnss: TypesToReflect.GenericOC<__ObjC.NSString>
26+
// CHECK: (bound_generic_class TypesToReflect.GenericOC
27+
// CHECK: (class __ObjC.NSString))
28+
29+
// CHECK: occfs: TypesToReflect.GenericOC<__ObjC.CFString>
30+
// CHECK: (bound_generic_class TypesToReflect.GenericOC
31+
// CHECK: (class __ObjC.CFString))
32+
33+
// CHECK: TypesToReflect.HasObjCClasses
34+
// CHECK: -----------------------------
35+
// CHECK: url: __ObjC.NSURL
36+
// CHECK: (class __ObjC.NSURL)
37+
38+
// CHECK: integer: Swift.Int
39+
// CHECK: (struct Swift.Int)
40+
41+
// CHECK: rect: __C.CGRect
42+
// CHECK: (struct __C.CGRect)
43+
44+
// CHECK: __ObjC.NSBundle
45+
// CHECK: ---------------
46+
// CHECK: __ObjC.NSURL
47+
// CHECK: ------------
48+
49+
// CHECK: ASSOCIATED TYPES:
50+
// CHECK: =================
51+
52+
// CHECK: BUILTIN TYPES:
53+
// CHECK: ==============
54+
55+
// CHECK: - __C.CGRect:
56+
// CHECK: Size: 32
57+
// CHECK: Alignment: 8
58+
// CHECK: Stride: 32
59+
// CHECK: NumExtraInhabitants: 0
60+
61+
// CHECK: CAPTURE DESCRIPTORS:
62+
// CHECK: ====================
63+
// CHECK: - Capture types:
64+
// CHECK: (struct Swift.StaticString)
65+
// CHECK: (struct Swift.StaticString)
66+
// CHECK: (struct Swift.UInt)
67+
// CHECK: (struct Swift.UInt)
68+
// CHECK: - Metadata sources:
69+
70+
// CHECK: - Capture types:
71+
// CHECK: (function
72+
// CHECK: (tuple))
73+
// CHECK: - Metadata sources:
74+
75+
// CHECK: - Capture types:
76+
// CHECK: (struct Swift.StaticString)
77+
// CHECK: (bound_generic_struct Swift.UnsafeBufferPointer
78+
// CHECK: (struct Swift.UInt8))
79+
// CHECK: (struct Swift.UInt)
80+
// CHECK: (struct Swift.UInt)
81+
// CHECK: - Metadata sources:
82+
83+
// CHECK: - Capture types:
84+
// CHECK: (function
85+
// CHECK: (tuple))
86+
// CHECK: - Metadata sources:
87+
88+
// CHECK: - Capture types:
89+
// CHECK: (bound_generic_struct Swift.UnsafeBufferPointer
90+
// CHECK: (struct Swift.UInt8))
91+
// CHECK: (bound_generic_struct Swift.UnsafeBufferPointer
92+
// CHECK: (struct Swift.UInt8))
93+
// CHECK: (struct Swift.UInt)
94+
// CHECK: (struct Swift.UInt)
95+
// CHECK: - Metadata sources:
96+
97+
// CHECK: - Capture types:
98+
// CHECK: (function
99+
// CHECK: (tuple))
100+
// CHECK: - Metadata sources:

0 commit comments

Comments
 (0)