Skip to content

Commit e023274

Browse files
committed
Define the C++ Swift(U)Int types using the same logic as SwiftShims
The C type tha corresponds to Swift's pointer-sized `Int` and `UInt` types varies from one platform to the next. The canonical C types are `ptrdiff_t` and `size_t`, but we're in the depths of the compiler we can't include the C library headers that provide them because they introduce cyclic module dependencies. Sigh. SwiftShims has some logic to compute these types. However, SwiftShims is part of the Swift runtime, not the compiler, so those headers cannot be included here. So, we clone the logic and simplify it somewhat for our use case. This fixes truncation issues on Windows, where the uses of `unsigned long` and `long` for Swift(U)Int are incorrect.
1 parent dadb863 commit e023274

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

include/swift/Basic/CBasicBridging.h

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,64 @@
2121
// it causes importing the "Darwin"/"Glibc" overlay module. That violates
2222
// layering. i.e. Darwin overlay is created by Swift compiler.
2323

24+
// NOTE: Partially ported from SwiftShim's SwiftStdint.h. We cannot include
25+
// that header here because it belongs to the runtime, but we need the same
26+
// logic for interoperability with Swift code in the compiler itself.
27+
// stdint.h is provided by Clang, but it dispatches to libc's stdint.h. As a
28+
// result, using stdint.h here would pull in Darwin module (which includes
29+
// libc). This creates a dependency cycle, so we can't use stdint.h in
30+
// SwiftShims.
31+
// On Linux, the story is different. We get the error message
32+
// "/usr/include/x86_64-linux-gnu/sys/types.h:146:10: error: 'stddef.h' file not
33+
// found"
34+
// This is a known Clang/Ubuntu bug.
35+
36+
// Clang has been defining __INTxx_TYPE__ macros for a long time.
37+
// __UINTxx_TYPE__ are defined only since Clang 3.5.
38+
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__OpenBSD__) && !defined(__wasi__)
39+
#include <stdint.h>
40+
typedef int64_t __swiftc_int64_t;
41+
typedef uint64_t __swiftc_uint64_t;
42+
typedef int32_t __swiftc_int32_t;
43+
typedef uint32_t __swiftc_uint32_t;
44+
typedef intptr_t __swiftc_intptr_t;
45+
typedef uintptr_t __swiftc_uintptr_t;
46+
#else
47+
typedef __INT64_TYPE__ __swiftc_int64_t;
48+
#ifdef __UINT64_TYPE__
49+
typedef __UINT64_TYPE__ __swiftc_uint64_t;
50+
#else
51+
typedef unsigned __INT64_TYPE__ __swiftc_uint64_t;
52+
#endif
53+
54+
typedef __INT32_TYPE__ __swiftc_int32_t;
55+
#ifdef __UINT32_TYPE__
56+
typedef __UINT32_TYPE__ __swiftc_uint32_t;
57+
#else
58+
typedef unsigned __INT32_TYPE__ __swiftc_uint32_t;
59+
#endif
60+
61+
#define __swiftc_join3(a,b,c) a ## b ## c
62+
63+
#define __swiftc_intn_t(n) __swiftc_join3(__swiftc_int, n, _t)
64+
#define __swiftc_uintn_t(n) __swiftc_join3(__swiftc_uint, n, _t)
65+
66+
#if defined(_MSC_VER) && !defined(__clang__)
67+
#if defined(_WIN32)
68+
typedef __swiftc_int32_t SwiftInt;
69+
typedef __swiftc_uint32_t SwiftUInt;
70+
#elif defined(_WIN64)
71+
typedef __swiftc_int64_t SwiftInt;
72+
typedef __swiftc_uint64_t SwiftUInt;
73+
#else
74+
#error unknown windows pointer width
75+
#endif
76+
#else
77+
typedef __swiftc_intn_t(__INTPTR_WIDTH__) SwiftInt;
78+
typedef __swiftc_uintn_t(__INTPTR_WIDTH__) SwiftUInt;
79+
#endif
80+
#endif
81+
2482
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
2583

2684
#ifdef __cplusplus
@@ -38,9 +96,6 @@ FeatureName,
3896

3997
SWIFT_BEGIN_ASSUME_NONNULL
4098

41-
typedef long SwiftInt;
42-
typedef unsigned long SwiftUInt;
43-
4499
typedef struct BridgedData {
45100
const char *_Nullable baseAddress;
46101
SwiftUInt size;

0 commit comments

Comments
 (0)