Skip to content

Commit d61b885

Browse files
authored
stdlib: map wchar_t to UInt16 on Windows
This is an ABI breaking change for Windows. `WCHAR` on Windows is mapped to `short` (`-fshort-wchar` makes it `unsigned short`). When C++ interop is enabled, `WCHAR` will be mapped to `wchar_t` which is then mapped to `short` (or `unsigned short` if `-fshort-wchar` is specified). Correct the mapping type to get the desired behaviour.
1 parent 879ffde commit d61b885

File tree

8 files changed

+46
-4
lines changed

8 files changed

+46
-4
lines changed

stdlib/public/core/CTypes.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,11 @@ public typealias CLongDouble = Float80
116116
// FIXME: Is it actually UTF-32 on Darwin?
117117
//
118118
/// The C++ 'wchar_t' type.
119+
#if os(Windows)
120+
public typealias CWideChar = UInt16
121+
#else
119122
public typealias CWideChar = Unicode.Scalar
123+
#endif
120124

121125
// FIXME: Swift should probably have a UTF-16 type other than UInt16.
122126
//
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module unicode {
2+
header "unicode.h"
3+
export *
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
#if !defined(__cplusplus)
3+
typedef short wchar_t;
4+
#endif
5+
typedef wchar_t WCHAR;
6+
#define UNICODE_NULL ((WCHAR)0)

test/ClangImporter/unicode.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %swift-ide-test -target x86_64-unknown-windows-msvc -print-module -module-to-print unicode -print-interface -source-filename %s -I %S/Inputs/unicode | %FileCheck %s -check-prefix CHECK-C
2+
// RUN: %swift-ide-test -target x86_64-unknown-windows-msvc -enable-experimental-cxx-interop -print-module -module-to-print unicode -print-interface -source-filename %s -I %S/Inputs/unicode | %FileCheck %s -check-prefix CHECK-CXX
3+
4+
// REQUIRES: OS=windows-msvc
5+
6+
import unicode
7+
8+
// CHECK-C: typealias WCHAR = wchar_t
9+
// CHECK-CXX: typealias WCHAR = CWideChar
10+
// CHECK: var UNICODE_NULL: WCHAR { get }

test/Interop/SwiftToC/functions/swift-primitive-functions-c-bridging.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-decls=all-public -emit-clang-header-path %t/functions.h
3-
// RUN: %FileCheck %s < %t/functions.h
3+
// RUN: %FileCheck %s -check-prefix CHECK -check-prefix CHECK-%target-abi < %t/functions.h
44

55
// RUN: %check-interop-c-header-in-clang(%t/functions.h)
66

@@ -19,7 +19,8 @@
1919
// CHECK-NEXT: SWIFT_EXTERN unsigned long long $s9Functions024passThroughCUnsignedLongE0ys6UInt64VADF(unsigned long long x) SWIFT_NOEXCEPT SWIFT_CALL;
2020
// CHECK-NEXT: SWIFT_EXTERN unsigned short $s9Functions25passThroughCUnsignedShortys6UInt16VADF(unsigned short x) SWIFT_NOEXCEPT SWIFT_CALL;
2121
// CHECK-NEXT: SWIFT_EXTERN unsigned char $s9Functions30passThroughCUnsignedSignedCharys5UInt8VADF(unsigned char x) SWIFT_NOEXCEPT SWIFT_CALL;
22-
// CHECK-NEXT: SWIFT_EXTERN wchar_t $s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF(wchar_t x) SWIFT_NOEXCEPT SWIFT_CALL;
22+
// CHECK-SYSV-NEXT: SWIFT_EXTERN wchar_t $s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF(wchar_t x) SWIFT_NOEXCEPT SWIFT_CALL;
23+
// CHECK-WIN-NEXT: SWIFT_EXTERN wchar_t $s9Functions20passThroughCWideCharys6UInt16VADF(wchar_t x) SWIFT_NOEXCEPT SWIFT_CALL;
2324
// CHECK-NEXT: SWIFT_EXTERN double $s9Functions17passThroughDoubleyS2dF(double x) SWIFT_NOEXCEPT SWIFT_CALL;
2425
// CHECK-NEXT: SWIFT_EXTERN float $s9Functions16passThroughFloatyS2fF(float x) SWIFT_NOEXCEPT SWIFT_CALL;
2526
// CHECK-NEXT: SWIFT_EXTERN float $s9Functions18passThroughFloat32yS2fF(float x) SWIFT_NOEXCEPT SWIFT_CALL;

test/Interop/SwiftToC/functions/swift-primitive-functions-execution.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ int main() {
2222
// passThroughCChar
2323
VERIFY_PASSTHROUGH_VALUE($s9Functions16passThroughCCharys4Int8VADF, 'a');
2424
// passThroughCWideChar
25+
#if defined(_WIN32)
26+
VERIFY_PASSTHROUGH_VALUE($s9Functions20passThroughCWideCharys6UInt16VADF, 'a');
27+
#else
2528
VERIFY_PASSTHROUGH_VALUE($s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF, 'a');
29+
#endif
2630
// passThroughCChar16
2731
VERIFY_PASSTHROUGH_VALUE($s9Functions18passThroughCChar16ys6UInt16VADF, 0xFE1);
2832
// passThroughCChar32

test/Interop/SwiftToCxx/functions/swift-primitive-functions-cxx-bridging.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-decls=all-public -emit-clang-header-path %t/functions.h
3-
// RUN: %FileCheck %s < %t/functions.h
3+
// RUN: %FileCheck %s -check-prefix CHECK -check-prefix CHECK-%target-abi < %t/functions.h
44

55
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
66

@@ -67,7 +67,8 @@
6767
// CHECK-NEXT: }
6868

6969
// CHECK: SWIFT_INLINE_THUNK wchar_t passThroughCWideChar(wchar_t x) noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {
70-
// CHECK-NEXT: return _impl::$s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF(x);
70+
// CHECK-SYSV: return _impl::$s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF(x);
71+
// CHECK-WIN: return _impl::$s9Functions20passThroughCWideCharys6UInt16VADF(x);
7172
// CHECK-NEXT: }
7273

7374
// CHECK: SWIFT_INLINE_THUNK double passThroughDouble(double x) noexcept SWIFT_SYMBOL({{.*}}) SWIFT_WARN_UNUSED_RESULT {

test/stdlib/PrintInteger.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ PrintTests.test("CustomStringConvertible") {
3434
hasDescription(CInt(42))
3535
hasDescription(CLong(42))
3636
hasDescription(CLongLong(42))
37+
#if os(Windows)
38+
hasDescription(CWideChar(exactly: 42)!)
39+
#else
3740
hasDescription(CWideChar(42)!)
41+
#endif
3842
hasDescription(CChar16(42))
3943
hasDescription(CChar32(42)!)
4044
}
@@ -51,7 +55,11 @@ PrintTests.test("Printable") {
5155
expectPrinted("42", CInt(42))
5256
expectPrinted("42", CLong(42))
5357
expectPrinted("42", CLongLong(42))
58+
#if os(Windows)
59+
expectPrinted("42", CWideChar(exactly: 42)!)
60+
#else
5461
expectPrinted("*", CWideChar(42)!)
62+
#endif
5563
expectPrinted("42", CChar16(42))
5664
expectPrinted("*", CChar32(42)!)
5765

@@ -142,7 +150,11 @@ PrintTests.test("Printable") {
142150
expectPrinted("42", CLong(42))
143151
expectPrinted("42", CLongLong(42))
144152

153+
#if os(Windows)
154+
expectPrinted("42", CWideChar(exactly: 42)!)
155+
#else
145156
expectPrinted("*", CWideChar(42)!)
157+
#endif
146158
expectPrinted("42", CChar16(42))
147159
expectPrinted("*", CChar32(42)!)
148160
}

0 commit comments

Comments
 (0)