Skip to content

Commit 7a46b0f

Browse files
committed
Reflection: Emit descriptors for referenced imported protocols
When we encounter a protocol typeref, we have to know if its @objc, class-bound, or opaque, so make sure we provide the necessary information when imported protocols are referenced.
1 parent 97fd1a7 commit 7a46b0f

File tree

5 files changed

+44
-11
lines changed

5 files changed

+44
-11
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,13 @@ class ReflectionMetadataBuilder : public ConstantBuilder<> {
188188
// for now, at least until we want to import C++ types or
189189
// something like that.
190190
//
191-
// Classes go down a different path.
191+
// Classes and protocols go down a different path.
192192
if (auto Nominal = t->getAnyNominal())
193193
if (Nominal->hasClangNode()) {
194194
if (auto CD = dyn_cast<ClassDecl>(Nominal))
195195
IGM.ImportedClasses.insert(CD);
196+
else if (auto PD = dyn_cast<ProtocolDecl>(Nominal))
197+
IGM.ImportedProtocols.insert(PD);
196198
else
197199
IGM.BuiltinTypes.insert(CanType(t));
198200
}
@@ -372,7 +374,9 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
372374
auto type = NTD->getDeclaredType()->getCanonicalType();
373375
addTypeRef(NTD->getModuleContext(), type);
374376

375-
if (NTD->hasClangNode() && !isa<ClassDecl>(NTD))
377+
if (NTD->hasClangNode() &&
378+
!isa<ClassDecl>(NTD) &&
379+
!isa<ProtocolDecl>(NTD))
376380
return;
377381

378382
switch (NTD->getKind()) {
@@ -884,6 +888,9 @@ void IRGenModule::emitBuiltinReflectionMetadata() {
884888
for (auto CD : ImportedClasses)
885889
emitFieldMetadataRecord(CD);
886890

891+
for (auto PD : ImportedProtocols)
892+
emitFieldMetadataRecord(PD);
893+
887894
BuiltinTypeMetadataBuilder builder(*this);
888895
auto var = builder.emit();
889896
if (var)

lib/IRGen/IRGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,9 @@ class IRGenModule {
721721
/// Imported classes referenced by types in this module when emitting
722722
/// reflection metadata.
723723
llvm::SetVector<ClassDecl *> ImportedClasses;
724+
/// Imported protocols referenced by types in this module when emitting
725+
/// reflection metadata.
726+
llvm::SetVector<ProtocolDecl *> ImportedProtocols;
724727

725728
llvm::Constant *getAddrOfStringForTypeRef(StringRef Str);
726729
llvm::Constant *getAddrOfFieldName(StringRef Name);

test/Reflection/Inputs/ObjectiveCTypes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ public class HasObjCClasses {
2929
let rect = NSRect(x: 0, y: 1, width: 2, height: 3)
3030
}
3131

32-
public func closureHasObjCClasses(b: NSBundle) -> () -> () {
33-
return { _ = b }
32+
public func closureHasObjCClasses(b: NSBundle, c: NSCoding) -> () -> () {
33+
return { _ = b; _ = c }
3434
}

test/Reflection/typeref_decoding_objc.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
// CHECK: ---------------
4646
// CHECK: __ObjC.NSURL
4747
// CHECK: ------------
48+
// CHECK: __ObjC.NSCoding
49+
// CHECK: ---------------
4850

4951
// CHECK: ASSOCIATED TYPES:
5052
// CHECK: =================
@@ -72,6 +74,23 @@
7274
// CHECK: (tuple))
7375
// CHECK: - Metadata sources:
7476

77+
// CHECK: - Capture types:
78+
// CHECK: (struct Swift.StaticString)
79+
// CHECK: (struct Swift.StaticString)
80+
// CHECK: (struct Swift.UInt)
81+
// CHECK: (struct Swift.UInt)
82+
// CHECK: - Metadata sources:
83+
84+
// CHECK: - Capture types:
85+
// CHECK: (function
86+
// CHECK: (tuple))
87+
// CHECK: - Metadata sources:
88+
89+
// CHECK: - Capture types:
90+
// CHECK: (class __ObjC.NSBundle)
91+
// CHECK: (protocol __ObjC.NSCoding)
92+
// CHECK: - Metadata sources:
93+
7594
// CHECK: - Capture types:
7695
// CHECK: (struct Swift.StaticString)
7796
// CHECK: (bound_generic_struct Swift.UnsafeBufferPointer

validation-test/Reflection/functions_objc.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,42 @@
66
import SwiftReflectionTest
77
import Foundation
88

9-
func capturesImportedClass(x: Int, n: NSURL, r: NSRect) {
10-
reflect(function: {print(x); print(n); print(r)})
9+
func capturesImportedTypes(x: Int, n: NSURL, r: NSRect, c: NSCoding) {
10+
reflect(function: {print(x); print(n); print(r); print(c)})
1111

1212
// CHECK-32: Type reference:
1313
// CHECK-32-NEXT: (builtin Builtin.NativeObject)
1414

1515
// CHECK-32: Type info:
16-
// CHECK-32-NEXT: (closure_context size=56 alignment=8 stride=56 num_extra_inhabitants=0
16+
// CHECK-32-NEXT: (closure_context size=60 alignment=8 stride=60 num_extra_inhabitants=0
1717
// CHECK-32-NEXT: (field offset=12
1818
// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
1919
// CHECK-32-NEXT: (field name=_value offset=0
2020
// CHECK-32-NEXT: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
2121
// CHECK-32-NEXT: (field offset=16
2222
// CHECK-32-NEXT: (reference kind=strong refcounting=unknown))
2323
// CHECK-32-NEXT: (field offset=24
24-
// CHECK-32-NEXT: (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0)))
24+
// CHECK-32-NEXT: (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0))
25+
// CHECK-32-NEXT: (field offset=56
26+
// CHECK-32-NEXT: (reference kind=strong refcounting=unknown)))
2527

2628
// CHECK-64: Type reference:
2729
// CHECK-64-NEXT: (builtin Builtin.NativeObject)
2830

2931
// CHECK-64: Type info:
30-
// CHECK-64-NEXT: (closure_context size=64 alignment=8 stride=64 num_extra_inhabitants=0
32+
// CHECK-64-NEXT: (closure_context size=72 alignment=8 stride=72 num_extra_inhabitants=0
3133
// CHECK-64-NEXT: (field offset=16
3234
// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
3335
// CHECK-64-NEXT: (field name=_value offset=0
3436
// CHECK-64-NEXT: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
3537
// CHECK-64-NEXT: (field offset=24
3638
// CHECK-64-NEXT: (reference kind=strong refcounting=unknown))
3739
// CHECK-64-NEXT: (field offset=32
38-
// CHECK-64-NEXT: (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0)))
40+
// CHECK-64-NEXT: (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0))
41+
// CHECK-64-NEXT: (field offset=64
42+
// CHECK-64-NEXT: (reference kind=strong refcounting=unknown)))
3943
}
4044

41-
capturesImportedClass(x: 10, n: NSURL(), r: NSRect(x: 1, y: 2, width: 3, height: 4))
45+
capturesImportedTypes(x: 10, n: NSURL(), r: NSRect(x: 1, y: 2, width: 3, height: 4), c: "" as NSString)
4246

4347
doneReflecting()

0 commit comments

Comments
 (0)