Skip to content

Commit 0d624ec

Browse files
authored
Merge pull request #63719 from NuriAmari/NSOptionsFix
[CXX-Interop] Fix NS_OPTION related label transformations and assertion failures
2 parents 7018c55 + a4d9082 commit 0d624ec

File tree

7 files changed

+77
-9
lines changed

7 files changed

+77
-9
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5756,7 +5756,8 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
57565756
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
57575757
typedefType->getCanonicalTypeInternal());
57585758
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
5759-
importedType = {cast<NominalTypeDecl>(swiftEnum)->getDeclaredType(), false};
5759+
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
5760+
false};
57605761
}
57615762
}
57625763
}

lib/ClangImporter/ImportType.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,7 +2138,7 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
21382138
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
21392139
typedefType->getCanonicalTypeInternal());
21402140
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2141-
return {cast<NominalTypeDecl>(swiftEnum)->getDeclaredType(), false};
2141+
return {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
21422142
}
21432143
}
21442144
}
@@ -2204,7 +2204,8 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
22042204
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
22052205
typedefType->getCanonicalTypeInternal());
22062206
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2207-
importedType = {cast<NominalTypeDecl>(swiftEnum)->getDeclaredType(), false};
2207+
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
2208+
false};
22082209
}
22092210
}
22102211
}
@@ -2305,7 +2306,7 @@ ClangImporter::Implementation::importParameterType(
23052306
->getCanonicalTypeInternal() ==
23062307
typedefType->getCanonicalTypeInternal());
23072308
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2308-
swiftParamTy = cast<NominalTypeDecl>(swiftEnum)->getDeclaredType();
2309+
swiftParamTy = cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType();
23092310
}
23102311
}
23112312
}
@@ -2592,7 +2593,11 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
25922593
// behave like a C enum in the presence of C++.
25932594
auto enumName = typedefType->getDecl()->getName();
25942595
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true, enumName);
2595-
for (auto word : llvm::reverse(camel_case::getWords(enumName))) {
2596+
auto camelCaseWords = camel_case::getWords(enumName);
2597+
for (auto it = camelCaseWords.rbegin(); it != camelCaseWords.rend();
2598+
++it) {
2599+
auto word = *it;
2600+
auto next = std::next(it);
25962601
if (camel_case::sameWordIgnoreFirstCase(word, "options")) {
25972602
argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
25982603
return argumentAttrs;
@@ -2603,13 +2608,17 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
26032608
return argumentAttrs;
26042609
if (camel_case::sameWordIgnoreFirstCase(word, "action"))
26052610
return argumentAttrs;
2606-
if (camel_case::sameWordIgnoreFirstCase(word, "controlevents"))
2611+
if (camel_case::sameWordIgnoreFirstCase(word, "events") &&
2612+
next != camelCaseWords.rend() &&
2613+
camel_case::sameWordIgnoreFirstCase(*next, "control"))
26072614
return argumentAttrs;
26082615
if (camel_case::sameWordIgnoreFirstCase(word, "state"))
26092616
return argumentAttrs;
26102617
if (camel_case::sameWordIgnoreFirstCase(word, "unit"))
26112618
return argumentAttrs;
2612-
if (camel_case::sameWordIgnoreFirstCase(word, "scrollposition"))
2619+
if (camel_case::sameWordIgnoreFirstCase(word, "position") &&
2620+
next != camelCaseWords.rend() &&
2621+
camel_case::sameWordIgnoreFirstCase(*next, "scroll"))
26132622
return argumentAttrs;
26142623
if (camel_case::sameWordIgnoreFirstCase(word, "edge"))
26152624
return argumentAttrs;
@@ -2896,7 +2905,8 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
28962905
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
28972906
typedefType->getCanonicalTypeInternal());
28982907
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2899-
importedType = {cast<NominalTypeDecl>(swiftEnum)->getDeclaredType(), false};
2908+
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
2909+
false};
29002910
}
29012911
}
29022912
}

test/Interop/Cxx/enum/Inputs/CenumsNSOptions.apinotes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ Enumerators:
1111
Tags:
1212
- Name: UIPrinterJobTypes
1313
SwiftName: UIPrinter.JobTypes
14+
- Name: Baz
15+
SwiftName: CurrentBazVersion
1416
SwiftVersions:
1517
- Version: 4
1618
Tags:
1719
- Name: UIPrinterJobTypes
1820
SwiftName: UIPrinterJobTypes
21+
- Name: Baz
22+
SwiftName: BazVersion4

test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,13 @@ typedef NS_OPTIONS(NSUInteger, Bar) {
7878
API_NOTES_NAMED_OptionFour = API_NOTES_NAMED_OptionOne |
7979
API_NOTES_NAMED_OptionTwo
8080
};
81+
82+
typedef NS_OPTIONS(NSUInteger, Baz) { Baz1, Baz2 };
83+
84+
Baz CFunctionReturningNSOption();
85+
void CFunctionTakingNSOption(Baz);
86+
87+
@interface NSOptionTypeCheckTest
88+
+ (Baz)methodReturningNSOption;
89+
+ (void)methodTakingNSOption:(Baz)baz;
90+
@end

test/Interop/Cxx/enum/Inputs/c-enums-withOptions-omit.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,29 @@ enum : UIControlState { UIControlState1, UIControlState2 };
2828
typedef int __attribute__((availability(swift, unavailable))) UITableViewCellStateMask;
2929
enum : UITableViewCellStateMask { UITableViewCellStateMask1, UITableViewCellStateMask2 };
3030

31+
typedef int __attribute__((availability(swift, unavailable))) UIControlEvents;
32+
enum : UIControlEvents { UIControlEvents1, UIControlEvents2 };
33+
34+
typedef int __attribute__((availability(swift, unavailable)))
35+
UITableViewScrollPosition;
36+
enum : UITableViewScrollPosition {
37+
UITableViewScrollPosition1,
38+
UITableViewScrollPosition2
39+
};
40+
41+
@interface NSIndexPath
42+
@end
43+
3144
@interface TestsForEnhancedOmitNeedlessWords
3245
- (void)differenceFromArray:(int)other withOptions:(NSOrderedCollectionDifferenceCalculationOptions)options ;
3346
- (unsigned)minimumRangeOfUnit:(NSCalendarUnit)unit;
3447
- (unsigned)URLForDirectory:(unsigned)directory inDomain:(NSSearchPathDomainMask)domain ;
3548
- (unsigned)layoutManager:(unsigned)layoutManager shouldUseAction:(NSControlCharacterAction)action ;
3649
- (void)setBackButtonBackgroundImage:(unsigned)backgroundImage forState:(UIControlState)state ;
3750
- (void)willTransitionToState:(UITableViewCellStateMask)state ;
51+
- (void)addTarget:(nullable id)target
52+
action:(SEL)action
53+
forControlEvents:(UIControlEvents)controlEvents;
54+
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath
55+
atScrollPosition:(UITableViewScrollPosition)scrollPosition;
3856
@end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -I %S/Inputs -enable-experimental-cxx-interop -typecheck %s
2+
// REQUIRES: objc_interop
3+
4+
import CenumsNSOptions
5+
6+
let foo = CFunctionReturningNSOption()
7+
CFunctionTakingNSOption(foo)
8+
let foo2 = NSOptionTypeCheckTest.methodReturningNSOption()
9+
NSOptionTypeCheckTest.methodTakingNSOption(foo)

test/Interop/Cxx/enum/c-enums-withOptions-omit.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,20 @@ import CenumsWithOptionsOmit
5656
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "willTransition(to:)")
5757
// CHECK-NEXT: class func willTransitionToState(_ state: UITableViewCellStateMask)
5858
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "willTransition(to:)")
59-
// CHECK-NEXT: func willTransitionToState(_ state: UITableViewCellStateMask)
59+
// CHECK-NEXT: func willTransitionToState(_ state: UITableViewCellStateMask)
60+
61+
// Tests for forControlEvents -> 'for controlEvents'
62+
// CHECK-NEXT: class func addTarget(_ target: Any?, action: OpaquePointer!, for controlEvents: UIControlEvents)
63+
// CHECK-NEXT: func addTarget(_ target: Any?, action: OpaquePointer!, for controlEvents: UIControlEvents)
64+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "addTarget(_:action:for:)")
65+
// CHECK-NEXT: class func addTarget(_ target: Any?, action: OpaquePointer!, forControlEvents controlEvents: UIControlEvents)
66+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "addTarget(_:action:for:)")
67+
// CHECK-NEXT: func addTarget(_ target: Any?, action: OpaquePointer!, forControlEvents controlEvents: UIControlEvents)
68+
69+
// Tests for atScrollPosition -> 'at atScrollPosition'
70+
// CHECK-NEXT: class func scrollToRow(at indexPath: NSIndexPath!, at scrollPosition: UITableViewScrollPosition)
71+
// CHECK-NEXT: func scrollToRow(at indexPath: NSIndexPath!, at scrollPosition: UITableViewScrollPosition)
72+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "scrollToRow(at:at:)")
73+
// CHECK-NEXT: class func scrollToRowAtIndexPath(_ indexPath: NSIndexPath!, atScrollPosition scrollPosition: UITableViewScrollPosition)
74+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "scrollToRow(at:at:)")
75+
// CHECK-NEXT: func scrollToRowAtIndexPath(_ indexPath: NSIndexPath!, atScrollPosition scrollPosition: UITableViewScrollPosition)

0 commit comments

Comments
 (0)