Skip to content

Commit 1c0c558

Browse files
committed
add test case for [Mutable]Span wrappers in ObjC protocols
1 parent 14c79d2 commit 1c0c558

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// REQUIRES: swift_feature_SafeInteropWrappers
2+
// REQUIRES: swift_feature_LifetimeDependence
3+
4+
// REQUIRES: foundation
5+
6+
// RUN: %empty-directory(%t)
7+
// RUN: split-file %s %t
8+
9+
// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %t -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature LifetimeDependence %t/test.swift -verify -Xcc -Wno-nullability-completeness
10+
// RUN: env SWIFT_BACKTRACE="" %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %t -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature LifetimeDependence %t/test.swift -dump-macro-expansions 2> %t/expansions.out
11+
// RUN: %diff %t/expansions.out %t/expansions.expected
12+
13+
//--- test.h
14+
#pragma once
15+
16+
#include <Foundation/Foundation.h>
17+
18+
// __counted_by definition inherited from Foundation.h
19+
#define __noescape __attribute__((noescape))
20+
#define __lifetimebound __attribute__((lifetimebound))
21+
22+
void foo(int len, int * __counted_by(len) p __noescape);
23+
@protocol TestProtocol
24+
- (void) bar:(int * __noescape)p _Nullable:(int)asdf;
25+
- (void) simple:(int)len :(int * __counted_by(len) __noescape)p;
26+
- (void) shared:(int)len :(int * __counted_by(len) __noescape)p1 :(int * __counted_by(len) __noescape)p2;
27+
- (void) complexExpr:(int)len :(int) offset :(int * __counted_by(len - offset) __noescape)p;
28+
- (void) nullUnspecified:(int)len :(int * __counted_by(len) _Null_unspecified __noescape)p;
29+
- (void) nonnull:(int)len :(int * __counted_by(len) _Nonnull __noescape)p;
30+
- (void) nullable:(int)len :(int * __counted_by(len) _Nullable __noescape)p;
31+
- (int * __counted_by(len)) returnPointer:(int)len : (int * __counted_by(len) _Nullable) __lifetimebound p;
32+
- (void) mixedEscapability:(int)len :(int * __counted_by(len) __noescape)p1 :(int * __counted_by(len))p2;
33+
@end
34+
35+
@protocol StaticProtocol
36+
+ (void) staticMethod:(int)len :(int * __counted_by(len) __noescape)p;
37+
@end
38+
39+
@interface StaticInterface : NSObject <StaticProtocol> {}
40+
@end
41+
42+
//--- expansions.expected
43+
@__swiftmacro_So12TestProtocol015_SwiftifyImportB0fMe_.swift
44+
------------------------------
45+
extension TestProtocol {
46+
/// This is an auto-generated wrapper for safer interop
47+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public
48+
func simple(_ p: inout MutableSpan<Int32>) {
49+
let len = Int32(exactly: p.count)!
50+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
51+
return unsafe simple(len, _pPtr.baseAddress!)
52+
}
53+
}
54+
/// This is an auto-generated wrapper for safer interop
55+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p1: copy p1) @_lifetime(p2: copy p2) @_disfavoredOverload public
56+
func shared(_ p1: inout MutableSpan<Int32>, _ p2: inout MutableSpan<Int32>) {
57+
let len = Int32(exactly: p1.count)!
58+
if p2.count != len {
59+
fatalError("bounds check failure in shared: expected \(len) but got \(p2.count)")
60+
}
61+
return unsafe p2.withUnsafeMutableBufferPointer { _p2Ptr in
62+
return unsafe p1.withUnsafeMutableBufferPointer { _p1Ptr in
63+
return unsafe shared(len, _p1Ptr.baseAddress!, _p2Ptr.baseAddress!)
64+
}
65+
}
66+
}
67+
/// This is an auto-generated wrapper for safer interop
68+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public
69+
func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan<Int32>) {
70+
let _pCount = p.count
71+
if _pCount != len - offset {
72+
fatalError("bounds check failure in complexExpr: expected \(len - offset) but got \(_pCount)")
73+
}
74+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
75+
return unsafe complexExpr(len, offset, _pPtr.baseAddress!)
76+
}
77+
}
78+
/// This is an auto-generated wrapper for safer interop
79+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public
80+
func nullUnspecified(_ p: inout MutableSpan<Int32>) {
81+
let len = Int32(exactly: p.count)!
82+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
83+
return unsafe nullUnspecified(len, _pPtr.baseAddress!)
84+
}
85+
}
86+
/// This is an auto-generated wrapper for safer interop
87+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public
88+
func nonnull(_ p: inout MutableSpan<Int32>) {
89+
let len = Int32(exactly: p.count)!
90+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
91+
return unsafe nonnull(len, _pPtr.baseAddress!)
92+
}
93+
}
94+
/// This is an auto-generated wrapper for safer interop
95+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public
96+
func nullable(_ p: inout MutableSpan<Int32>?) {
97+
let len = Int32(exactly: p?.count ?? 0)!
98+
return { () in
99+
return if p == nil {
100+
unsafe nullable(len, nil)
101+
} else {
102+
unsafe p!.withUnsafeMutableBufferPointer { _pPtr in
103+
return unsafe nullable(len, _pPtr.baseAddress)
104+
}
105+
}
106+
}()
107+
}
108+
/// This is an auto-generated wrapper for safer interop
109+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(copy p) @_lifetime(p: copy p) @_disfavoredOverload public
110+
func returnPointer(_ p: inout MutableSpan<Int32>?) -> MutableSpan<Int32> {
111+
let len = Int32(exactly: p?.count ?? 0)!
112+
return unsafe _swiftifyOverrideLifetime(MutableSpan<Int32>(_unsafeStart: { () in
113+
return if p == nil {
114+
unsafe returnPointer(len, nil)
115+
} else {
116+
unsafe p!.withUnsafeMutableBufferPointer { _pPtr in
117+
return unsafe returnPointer(len, _pPtr.baseAddress)
118+
}
119+
}
120+
}(), count: Int(len)), copying: ())
121+
}
122+
/// This is an auto-generated wrapper for safer interop
123+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p1: copy p1) @_disfavoredOverload public
124+
func mixedEscapability(_ p1: inout MutableSpan<Int32>, _ p2: UnsafeMutableBufferPointer<Int32>) {
125+
let len = Int32(exactly: p1.count)!
126+
if p2.count != len {
127+
fatalError("bounds check failure in mixedEscapability: expected \(len) but got \(p2.count)")
128+
}
129+
return unsafe p1.withUnsafeMutableBufferPointer { _p1Ptr in
130+
return unsafe mixedEscapability(len, _p1Ptr.baseAddress!, p2.baseAddress!)
131+
}
132+
}
133+
}
134+
------------------------------
135+
@__swiftmacro_So14StaticProtocol015_SwiftifyImportB0fMe_.swift
136+
------------------------------
137+
extension StaticProtocol {
138+
/// This is an auto-generated wrapper for safer interop
139+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload
140+
static public func staticMethod(_ p: inout MutableSpan<Int32>) {
141+
let len = Int32(exactly: p.count)!
142+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
143+
return unsafe staticMethod(len, _pPtr.baseAddress!)
144+
}
145+
}
146+
}
147+
------------------------------
148+
@__swiftmacro_So3foo15_SwiftifyImportfMp_.swift
149+
------------------------------
150+
/// This is an auto-generated wrapper for safer interop
151+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_lifetime(p: copy p) @_disfavoredOverload public func foo(_ p: inout MutableSpan<Int32>) {
152+
let len = Int32(exactly: p.count)!
153+
return unsafe p.withUnsafeMutableBufferPointer { _pPtr in
154+
return unsafe foo(len, _pPtr.baseAddress!)
155+
}
156+
}
157+
------------------------------
158+
//--- test.swift
159+
import TestClang
160+
161+
@inlinable
162+
public func call(p: inout MutableSpan<CInt>, p2: inout MutableSpan<CInt>, p3: inout MutableSpan<CInt>?, a: TestProtocol) {
163+
a.simple(&p)
164+
a.shared(&p, &p2)
165+
a.complexExpr(2, 3, &p)
166+
a.nullUnspecified(&p)
167+
a.nonnull(&p)
168+
a.nullable(&p3)
169+
let _: MutableSpan<CInt> = a.returnPointer(&p3)
170+
StaticInterface.staticMethod(&p2)
171+
foo(&p)
172+
}
173+
174+
//--- module.modulemap
175+
module TestClang {
176+
header "test.h"
177+
export *
178+
}

0 commit comments

Comments
 (0)