Skip to content

Commit 13c1805

Browse files
committed
Clang importer: teach importFullName about dropping certain variadics.
This moves the hack used for UIActionSheet and UIAlertView's variadic designated initializers over into importFullName().
1 parent 91d1c3b commit 13c1805

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,46 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix(
15941594
return commonPrefix;
15951595
}
15961596

1597+
/// Determine whether the given Clang selector matches the given
1598+
/// selector pieces.
1599+
static bool isNonNullarySelector(clang::Selector selector,
1600+
ArrayRef<StringRef> pieces) {
1601+
unsigned n = selector.getNumArgs();
1602+
if (n == 0) return false;
1603+
if (n != pieces.size()) return false;
1604+
1605+
for (unsigned i = 0; i != n; ++i) {
1606+
if (selector.getNameForSlot(i) != pieces[i]) return false;
1607+
}
1608+
1609+
return true;
1610+
}
1611+
1612+
/// Whether we should make a variadic method with the given selector
1613+
/// non-variadic.
1614+
static bool shouldMakeSelectorNonVariadic(clang::Selector selector) {
1615+
// This is UIActionSheet's designated initializer.
1616+
if (isNonNullarySelector(selector,
1617+
{ "initWithTitle",
1618+
"delegate",
1619+
"cancelButtonTitle",
1620+
"destructiveButtonTitle",
1621+
"otherButtonTitles" }))
1622+
return true;
1623+
1624+
// This is UIAlertView's designated initializer.
1625+
if (isNonNullarySelector(selector,
1626+
{ "initWithTitle",
1627+
"message",
1628+
"delegate",
1629+
"cancelButtonTitle",
1630+
"otherButtonTitles" }))
1631+
return true;
1632+
1633+
// Nothing else for now.
1634+
return false;
1635+
}
1636+
15971637
auto ClangImporter::Implementation::importFullName(
15981638
const clang::NamedDecl *D,
15991639
clang::DeclContext **effectiveContext) -> ImportedName {
@@ -1694,8 +1734,16 @@ auto ClangImporter::Implementation::importFullName(
16941734
baseName = "init";
16951735
else
16961736
baseName = selector.getNameForSlot(0);
1697-
for (unsigned index = 0, numArgs = selector.getNumArgs(); index != numArgs;
1698-
++index) {
1737+
1738+
// If we have a variadic method for which we need to drop the last
1739+
// selector piece, do so now.
1740+
unsigned numArgs = selector.getNumArgs();
1741+
if (objcMethod->isVariadic() && shouldMakeSelectorNonVariadic(selector)) {
1742+
--numArgs;
1743+
result.DroppedVariadic = true;
1744+
}
1745+
1746+
for (unsigned index = 0; index != numArgs; ++index) {
16991747
if (index == 0) {
17001748
argumentNames.push_back(StringRef());
17011749
} else {

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
753753
/// swift_name attribute.
754754
bool HasCustomName = false;
755755

756+
/// Whether this was one of a special class of Objective-C
757+
/// initializers for which we drop the variadic argument rather
758+
/// than refuse to import the initializer.
759+
bool DroppedVariadic = false;
760+
756761
/// For an initializer, the kind of initializer to import.
757762
CtorInitializerKind InitKind;
758763

test/IDE/Inputs/swift_name_objc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,7 @@ SWIFT_NAME(SomeProtocol)
4949
@protocol NSAccessibility
5050
@property (nonatomic) float accessibilityFloat;
5151
@end
52+
53+
@interface UIActionSheet : NSObject
54+
-(instancetype)initWithTitle:(const char *)title delegate:(id)delegate cancelButtonTitle:(const char *)cancelButtonTitle destructiveButtonTitle:(const char *)destructiveButtonTitle otherButtonTitles:(const char *)otherButtonTitles, ...;
55+
@end

test/IDE/dump_swift_lookup_tables_objc.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
// CHECK-NEXT: SNCollisionProtocol --> SNCollisionProtocol
1010
// CHECK-NEXT: SomeClass --> SomeClass
1111
// CHECK-NEXT: SomeProtocol --> SomeProtocol
12+
// CHECK-NEXT: UIActionSheet --> UIActionSheet
1213
// CHECK-NEXT: accessibilityFloat --> accessibilityFloat()
1314
// CHECK-NEXT: categoryMethodWithX --> categoryMethodWithX(_:y:), categoryMethodWithX(_:y:z:)
1415
// CHECK-NEXT: doubleProperty --> doubleProperty{{$}}
1516
// CHECK-NEXT: extensionMethodWithX --> extensionMethodWithX(_:y:)
1617
// CHECK-NEXT: floatProperty --> floatProperty{{$}}
17-
// CHECK-NEXT: init --> init(float:), init(withDefault:), init(double:), init(withTry:), init(uint8:){{$}}
18+
// CHECK-NEXT: init --> init(float:), init(withDefault:), init(double:), init(withTry:), init(uint8:), init(title:delegate:cancelButtonTitle:destructiveButtonTitle:)
1819
// CHECK-NEXT: instanceMethodWithX --> instanceMethodWithX(_:y:z:)
1920
// CHECK-NEXT: protoInstanceMethodWithX --> protoInstanceMethodWithX(_:y:)
2021
// CHECK-NEXT: setAccessibilityFloat --> setAccessibilityFloat(_:)
@@ -30,6 +31,8 @@
3031
// CHECK-NEXT: TU: SNSomeClass
3132
// CHECK-NEXT: SomeProtocol:
3233
// CHECK-NEXT: TU: SNSomeProtocol
34+
// CHECK-NEXT: UIActionSheet:
35+
// CHECK-NEXT: TU: UIActionSheet
3336
// CHECK-NEXT: accessibilityFloat():
3437
// CHECK-NEXT: NSAccessibility: -[NSAccessibility accessibilityFloat]
3538
// CHECK-NEXT: categoryMethodWithX(_:y:):
@@ -46,6 +49,8 @@
4649
// CHECK-NEXT: SNSomeClass: +[SNSomeClass someClassWithDouble:]
4750
// CHECK-NEXT: init(float:):
4851
// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithFloat:]
52+
// CHECK-NEXT: init(title:delegate:cancelButtonTitle:destructiveButtonTitle:):
53+
// CHECK-NEXT: UIActionSheet: -[UIActionSheet initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherButtonTitles:]
4954
// CHECK-NEXT: init(uint8:):
5055
// CHECK-NEXT: SNSomeClass: +[SNSomeClass buildWithUnsignedChar:]
5156
// CHECK-NEXT: init(withDefault:):

0 commit comments

Comments
 (0)