Skip to content

Commit cb3d820

Browse files
authored
Merge pull request #82706 from xymus/cdecl-implementation-tests
Sema: Add `@cdecl @implementation` tests
2 parents 9e953d2 + 4d814d0 commit cb3d820

File tree

6 files changed

+237
-3
lines changed

6 files changed

+237
-3
lines changed

test/IRGen/Inputs/objc_implementation.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#if __OBJC__
12
#import <Foundation/Foundation.h>
23

34
@interface ImplClass: NSObject <NSCopying>
@@ -31,11 +32,13 @@
3132
- (void)category2Method:(int)param;
3233

3334
@end
35+
#endif
3436

3537
extern void implFunc(int param);
3638
extern void implFuncCName(int param) __asm__("_implFuncAsmName");
39+
extern void implFuncRenamed_C(int param) __attribute__((swift_name("implFuncRenamed_Swift(param:)")));
3740

38-
41+
#if __OBJC__
3942
@interface NoImplClass
4043

4144
- (void)noImplMethod:(int)param;
@@ -57,3 +60,4 @@ extern void implFuncCName(int param) __asm__("_implFuncAsmName");
5760
@property (assign) int afterInt;
5861

5962
@end
63+
#endif

test/IRGen/cdecl_implementation.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) \
2+
// RUN: -enable-experimental-feature CImplementation \
3+
// RUN: -enable-experimental-feature CDecl \
4+
// RUN: -disable-objc-interop \
5+
// RUN: -F %clang-importer-sdk-path/frameworks %s \
6+
// RUN: -import-objc-header %S/Inputs/objc_implementation.h -emit-ir \
7+
// RUN: -target %target-future-triple > %t.ir
8+
// RUN: %FileCheck --input-file %t.ir %s
9+
10+
// REQUIRES: swift_feature_CImplementation
11+
// REQUIRES: swift_feature_CDecl
12+
13+
@implementation @cdecl
14+
public func implFunc(_ param: Int32) {}
15+
16+
@implementation @cdecl
17+
public func implFuncCName(_ param: Int32) {}
18+
19+
@implementation @cdecl(implFuncRenamed_C)
20+
public func implFuncRenamed_Swift(param: Int32) {}
21+
22+
public func fn() {
23+
implFunc(2)
24+
implFuncCName(3)
25+
implFuncRenamed_Swift(param: 4)
26+
}
27+
28+
/// implFunc(_:)
29+
// CHECK-LABEL: define{{.*}} void @implFunc
30+
31+
// FIXME: We'd like this to be internal or hidden, not public.
32+
// CHECK: define{{.*}} swiftcc void @"$s20cdecl_implementation8implFuncyys5Int32VF"
33+
34+
/// inplFuncCName(_:)
35+
// CHECK-LABEL: define{{.*}} void @"\01_implFuncAsmName"
36+
37+
// FIXME: We'd like this to be internal or hidden, not public.
38+
// CHECK: define{{.*}} swiftcc void @"$s20cdecl_implementation13implFuncCNameyys5Int32VF"
39+
40+
/// fn()
41+
// CHECK-LABEL: define{{.*}} swiftcc void @"$s20cdecl_implementation2fnyyF"
42+
// CHECK: call void @implFunc
43+
// CHECK: call void @"\01_implFuncAsmName"
44+
// CHECK: call void @implFuncRenamed_C
45+
// CHECK: ret void
46+
// CHECK: }
47+

test/IRGen/objc_implementation.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,15 @@ public func implFunc(_ param: Int32) {}
185185
@_objcImplementation @_cdecl("implFuncCName")
186186
public func implFuncCName(_ param: Int32) {}
187187

188+
@implementation @_cdecl("implFuncRenamed_C")
189+
public func implFuncRenamed_Swift(param: Int32) {}
190+
188191
public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
189192
impl.mainMethod(0)
190193
swiftSub.mainMethod(1)
191194
implFunc(2)
192195
implFuncCName(3)
196+
implFuncRenamed_Swift(param: 4)
193197
}
194198

195199
// Swift calling convention -[ImplClass init]
@@ -329,12 +333,12 @@ public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
329333
// Swift calling convention SwiftSubclass.deinit (deallocating)
330334
// CHECK-LABEL: define swiftcc void @"$s19objc_implementation13SwiftSubclassCfD"
331335

332-
// inplFunc(_:)
336+
// implFunc(_:)
333337
// CHECK-LABEL: define void @implFunc
334338
// FIXME: We'd like this to be internal or hidden, not public.
335339
// CHECK: define swiftcc void @"$s19objc_implementation8implFuncyys5Int32VF"
336340

337-
// inplFuncCName(_:)
341+
// implFuncCName(_:)
338342
// CHECK-LABEL: define void @"\01_implFuncAsmName"
339343
// FIXME: We'd like this to be internal or hidden, not public.
340344
// CHECK: define swiftcc void @"$s19objc_implementation13implFuncCNameyys5Int32VF"
@@ -346,6 +350,7 @@ public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
346350
// CHECK: [[SEL_2:%[^ ]+]] = load ptr, ptr @"\01L_selector(mainMethod:)", align 8
347351
// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr [[SEL_2]], i32 1)
348352
// CHECK: call void @implFunc
353+
// CHECK: call void @"\01_implFuncAsmName"
349354
// CHECK: ret void
350355
// CHECK: }
351356

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t --leading-lines
3+
4+
/// Build Swift dylib and compatibility header.
5+
// RUN: %target-build-swift-dylib(%t/%target-library-name(Lib)) %t/Lib.swift \
6+
// RUN: -emit-module-path %t/Lib.swiftmodule \
7+
// RUN: -emit-clang-header-path %t/cdecl.h \
8+
// RUN: -import-objc-header %t/BridgingHeader.h \
9+
// RUN: -enable-experimental-feature CDecl \
10+
// RUN: -enable-experimental-feature CImplementation
11+
// RUN: %target-codesign %t/%target-library-name(Lib)
12+
13+
/// Build a C client against cdecl.h.
14+
// RUN: %clang-no-modules %t/Client.c -o %t/a.out \
15+
// RUN: -I %clang-include-dir -Werror -isysroot %sdk \
16+
// RUN: -I %t -l Lib -L %t %target-rpath(%t)
17+
// RUN: %target-codesign %t/a.out
18+
// RUN: %target-run %t/a.out > %t/run.log
19+
// RUN: %FileCheck %t/Client.c --check-prefix=PRINTS --input-file %t/run.log
20+
21+
/// Build a Swift client against cdecl.h.
22+
// RUN: %target-build-swift %t/Client.swift -o %t/a.out \
23+
// RUN: -I %t -l Lib -L %t %target-rpath(%t)
24+
// RUN: %target-codesign %t/a.out
25+
// RUN: %target-run %t/a.out > %t/run.log
26+
// RUN: %FileCheck %t/Client.swift --check-prefix=PRINTS --input-file %t/run.log
27+
28+
// REQUIRES: swift_feature_CDecl
29+
// REQUIRES: swift_feature_CImplementation
30+
// REQUIRES: executable_test
31+
32+
//--- BridgingHeader.h
33+
#include <stddef.h>
34+
#include <stdbool.h>
35+
36+
extern int simple(int x, int y);
37+
38+
extern void primitiveTypes(ptrdiff_t i, int ci, long l, char c, float f, double d, bool b);
39+
40+
extern void sameName();
41+
42+
__attribute__((swift_name("renamed_swiftSide(_:)")))
43+
extern void renamed_clangSide(ptrdiff_t arg);
44+
45+
//--- Lib.swift
46+
47+
@cdecl @implementation
48+
public func simple(_ x: Int32, _ y: Int32) -> Int32 {
49+
print(x, y)
50+
return x
51+
}
52+
53+
@implementation @cdecl
54+
public func primitiveTypes(_ i: Int, _ ci: CInt, _ l: CLong, _ c: CChar, _ f: Float, _ d: Double, _ b: Bool) {
55+
print(i, ci, l, c, f, d, b)
56+
}
57+
58+
@cdecl(sameName) @implementation
59+
public func sameName() {
60+
print("sameName")
61+
}
62+
63+
@cdecl(renamed_clangSide) @implementation
64+
public func renamed_swiftSide(_ arg: Int) {
65+
print(arg)
66+
}
67+
68+
//--- Client.c
69+
70+
#include "cdecl.h"
71+
#include "BridgingHeader.h"
72+
73+
int main() {
74+
ptrdiff_t x = simple(42, 43);
75+
// PRINTS: 42 43
76+
primitiveTypes(1, 2, 3, 'a', 1.0f, 2.0, true);
77+
// PRINTS: 1 2 3 97 1.0 2.0 true
78+
sameName();
79+
// PRINTS: sameName
80+
renamed_clangSide(11);
81+
// PRINTS: 11
82+
}
83+
84+
//--- Client.swift
85+
import Lib
86+
87+
let _ = simple(42, 43)
88+
// PRINTS: 42 43
89+
primitiveTypes(1, 2, 3, 97, 1.0, 2.0, true)
90+
// PRINTS: 1 2 3 97 1.0 2.0 true
91+
sameName();
92+
// PRINTS: sameName
93+
renamed_swiftSide(11)
94+
// PRINTS: 11

test/decl/ext/Inputs/objc_implementation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@
231231
void CImplFunc1(int param);
232232
void CImplFunc2(int param);
233233

234+
void CImplFuncRenamed_C(int param) __attribute__((swift_name("CImplFuncRenamed_Swift(arg:)")));
235+
234236
void CImplFuncMismatch1(int param);
235237
void CImplFuncMismatch2(int param);
236238

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-stable-abi-triple \
2+
// RUN: -import-bridging-header %S/Inputs/objc_implementation.h \
3+
// RUN: -disable-objc-interop \
4+
// RUN: -enable-experimental-feature CImplementation \
5+
// RUN: -enable-experimental-feature CDecl
6+
7+
// REQUIRES: swift_feature_CImplementation
8+
// REQUIRES: swift_feature_CDecl
9+
10+
@implementation @cdecl
11+
func CImplFunc1(_: Int32) {
12+
// OK
13+
}
14+
15+
@implementation @cdecl(CImplFuncRenamed_C)
16+
func CImplFuncRenamed_Swift(arg: CInt) {
17+
// OK
18+
}
19+
20+
@implementation(BadCategory) @cdecl
21+
func CImplFunc2(_: Int32) {
22+
// expected-error@-2 {{global function 'CImplFunc2' does not belong to an Objective-C category; remove the category name from this attribute}} {{16-29=}}
23+
}
24+
25+
@implementation @cdecl
26+
func CImplFuncMissing(_: Int32) {
27+
// expected-error@-2 {{could not find imported function 'CImplFuncMissing' matching global function 'CImplFuncMissing'; make sure your umbrella or bridging header imports the header that declares it}}
28+
}
29+
30+
@implementation @cdecl
31+
func CImplFuncMismatch1(_: Float) {
32+
// expected-error@-1 {{global function 'CImplFuncMismatch1' of type '(Float) -> ()' does not match type '(Int32) -> Void' declared by the header}}
33+
}
34+
35+
@implementation @cdecl
36+
func CImplFuncMismatch2(_: Int32) -> Float {
37+
// expected-error@-1 {{global function 'CImplFuncMismatch2' of type '(Int32) -> Float' does not match type '(Int32) -> Void' declared by the header}}
38+
}
39+
40+
@implementation @cdecl(CImplFuncNameMismatch1)
41+
func mismatchedName1(_: Int32) {
42+
// expected-error@-2 {{could not find imported function 'CImplFuncNameMismatch1' matching global function 'mismatchedName1'; make sure your umbrella or bridging header imports the header that declares it}}
43+
// FIXME: Improve diagnostic for a partial match.
44+
}
45+
46+
@implementation @cdecl(mismatchedName2)
47+
func CImplFuncNameMismatch2(_: Int32) {
48+
// expected-error@-2 {{could not find imported function 'mismatchedName2' matching global function 'CImplFuncNameMismatch2'; make sure your umbrella or bridging header imports the header that declares it}}
49+
// FIXME: Improve diagnostic for a partial match.
50+
}
51+
52+
//
53+
// TODO: @cdecl for global functions imported as computed vars
54+
//
55+
var cImplComputedGlobal1: Int32 {
56+
@implementation @cdecl(CImplGetComputedGlobal1)
57+
get {
58+
// FIXME: Lookup for vars isn't working yet
59+
// expected-error@-3 {{could not find imported function 'CImplGetComputedGlobal1' matching getter for var 'cImplComputedGlobal1'; make sure your umbrella or bridging header imports the header that declares it}}
60+
return 0
61+
}
62+
63+
@implementation @cdecl(CImplSetComputedGlobal1)
64+
set {
65+
// FIXME: Lookup for vars isn't working yet
66+
// expected-error@-3 {{could not find imported function 'CImplSetComputedGlobal1' matching setter for var 'cImplComputedGlobal1'; make sure your umbrella or bridging header imports the header that declares it}}
67+
print(newValue)
68+
}
69+
}
70+
71+
//
72+
// TODO: @cdecl for import-as-member functions
73+
//
74+
extension CImplStruct {
75+
@implementation @cdecl(CImplStructStaticFunc1)
76+
static func staticFunc1(_: Int32) {
77+
// FIXME: Add underlying support for this
78+
// expected-error@-3 {{@cdecl can only be applied to global functions}}
79+
// FIXME: Lookup in an enclosing type is not working yet
80+
// expected-error@-5 {{could not find imported function 'CImplStructStaticFunc1' matching static method 'staticFunc1'; make sure your umbrella or bridging header imports the header that declares it}}
81+
}
82+
}

0 commit comments

Comments
 (0)