Skip to content

Commit 9b88853

Browse files
committed
[Serialization] Serialize Objective-C method names for accessors.
Due to some short-circuiting in the serialization logic, we never added @objc getters/setters to a module’s Objective-C method table.
1 parent 0a5eb5a commit 9b88853

File tree

3 files changed

+56
-45
lines changed

3 files changed

+56
-45
lines changed

lib/Serialization/Serialization.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,9 +4788,33 @@ static void collectInterestingNestedDeclarations(
47884788
const NominalTypeDecl *nominalParent = nullptr;
47894789

47904790
for (const Decl *member : members) {
4791+
// If there is a corresponding Objective-C method, record it.
4792+
auto recordObjCMethod = [&] {
4793+
if (isLocal)
4794+
return;
4795+
4796+
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
4797+
if (func->isObjC()) {
4798+
if (auto owningClass =
4799+
func->getDeclContext()->getAsClassOrClassExtensionContext()) {
4800+
Mangle::ASTMangler mangler;
4801+
std::string ownerName = mangler.mangleNominalType(owningClass);
4802+
assert(!ownerName.empty() && "Mangled type came back empty!");
4803+
4804+
objcMethods[func->getObjCSelector()].push_back(
4805+
std::make_tuple(ownerName,
4806+
func->isObjCInstanceMethod(),
4807+
S.addDeclRef(func)));
4808+
}
4809+
}
4810+
}
4811+
};
4812+
47914813
if (auto memberValue = dyn_cast<ValueDecl>(member)) {
4792-
if (!memberValue->hasName())
4814+
if (!memberValue->hasName()) {
4815+
recordObjCMethod();
47934816
continue;
4817+
}
47944818

47954819
if (memberValue->isOperator()) {
47964820
// Add operator methods.
@@ -4826,23 +4850,7 @@ static void collectInterestingNestedDeclarations(
48264850
}
48274851

48284852
// Record Objective-C methods.
4829-
if (!isLocal) {
4830-
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
4831-
if (func->isObjC()) {
4832-
if (auto owningClass =
4833-
func->getDeclContext()->getAsClassOrClassExtensionContext()) {
4834-
Mangle::ASTMangler mangler;
4835-
std::string ownerName = mangler.mangleNominalType(owningClass);
4836-
assert(!ownerName.empty() && "Mangled type came back empty!");
4837-
4838-
objcMethods[func->getObjCSelector()].push_back(
4839-
std::make_tuple(ownerName,
4840-
func->isObjCInstanceMethod(),
4841-
S.addDeclRef(func)));
4842-
}
4843-
}
4844-
}
4845-
}
4853+
recordObjCMethod();
48464854
}
48474855
}
48484856

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Foundation
2+
3+
public class Bar : Foo {
4+
@objc(method2WithValue:) public override func method2(_ value: Int) { }
5+
6+
@objc(overloadedWithInt:) public func overloaded(_ x: Int) { }
7+
@objc(overloadedWithString:) public func overloaded(_ x: String) { }
8+
9+
@objc(staticOverloadedWithInt:) public static func staticOverloaded(_ x: Int) { }
10+
@objc(staticOverloadedWithString:) public static func staticOverloaded(_ x: String) { }
11+
12+
@objc(staticOrNonStatic:) public func staticOrNonStatic(_ x: Int) { }
13+
@objc(staticOrNonStatic:) public static func staticOrNonStatic(_ x: Int) { }
14+
15+
@objc(theInstanceOne:) public func staticOrNonStatic2(_ x: Int) { }
16+
@objc(theStaticOne:) public static func staticOrNonStatic2(_ x: Int) { }
17+
}
18+
19+
public class Foo {
20+
@objc(methodWithValue:label:) public func method(_ value: Int, label: String) { }
21+
22+
@objc(method2WithValue:) public func method2(_ value: Int) { }
23+
24+
@objc public func method3() { }
25+
26+
@objc public var property: String = ""
27+
}

test/expr/primary/selector/fixits.swift

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t.overlays %clang-importer-sdk-path/swift-modules/Foundation.swift
1010
// FIXME: END -enable-source-import hackaround
1111

12+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-module -o %t.overlays %S/Inputs/fixits_helper.swift -module-name Helper
13+
1214
// Make sure we get the right diagnostics.
1315
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t.overlays) -typecheck %s -verify
1416

@@ -29,33 +31,7 @@
2931
// CHECK: warning: string literal is not a valid Objective-C selector
3032

3133
import Foundation
32-
33-
class Bar : Foo {
34-
@objc(method2WithValue:) override func method2(_ value: Int) { }
35-
36-
@objc(overloadedWithInt:) func overloaded(_ x: Int) { }
37-
@objc(overloadedWithString:) func overloaded(_ x: String) { }
38-
39-
@objc(staticOverloadedWithInt:) static func staticOverloaded(_ x: Int) { }
40-
@objc(staticOverloadedWithString:) static func staticOverloaded(_ x: String) { }
41-
42-
@objc(staticOrNonStatic:) func staticOrNonStatic(_ x: Int) { }
43-
@objc(staticOrNonStatic:) static func staticOrNonStatic(_ x: Int) { }
44-
45-
@objc(theInstanceOne:) func staticOrNonStatic2(_ x: Int) { }
46-
@objc(theStaticOne:) static func staticOrNonStatic2(_ x: Int) { }
47-
}
48-
49-
class Foo {
50-
@objc(methodWithValue:label:) func method(_ value: Int, label: String) { }
51-
52-
@objc(method2WithValue:) func method2(_ value: Int) { }
53-
54-
@objc func method3() { }
55-
56-
@objc var property: String = ""
57-
}
58-
34+
import Helper
5935

6036
func testDeprecatedStringLiteralSelector() {
6137
let sel1: Selector = "methodWithValue:label:" // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{24-48=#selector(Foo.method(_:label:))}}

0 commit comments

Comments
 (0)