[cxx-interop] Support char8_t C++20 type

https://en.cppreference.com/w/cpp/keyword/char8_t

This is based on a patch from Varun Gandhi: https://github.com/swiftlang/swift/pull/26153

rdar://39988329 / resolves https://github.com/swiftlang/swift/issues/68726
This commit is contained in:
Egor Zhdan
2024-09-26 20:13:29 +01:00
parent 488581f6c6
commit fcb590690e
12 changed files with 25 additions and 7 deletions

View File

@@ -47,6 +47,7 @@ MAP_BUILTIN_INTEGER_TYPE(UInt, CUnsignedInt)
MAP_BUILTIN_INTEGER_TYPE(ULong, CUnsignedLong)
MAP_BUILTIN_INTEGER_TYPE(ULongLong, CUnsignedLongLong)
MAP_BUILTIN_INTEGER_TYPE(UInt128, CUnsignedInt128)
MAP_BUILTIN_INTEGER_TYPE(Char8, CChar8)
MAP_BUILTIN_INTEGER_TYPE(Char16, CChar16)
MAP_BUILTIN_INTEGER_TYPE(Char32, CChar32)
MAP_BUILTIN_INTEGER_TYPE(SChar, CSignedChar)

View File

@@ -73,6 +73,7 @@
#endif
CLANG_MACRO_DEFINED("SWIFT_TYPEDEFS")
CLANG_MACRO_DEFINED("char8_t")
CLANG_MACRO_DEFINED("char16_t")
CLANG_MACRO_DEFINED("char32_t")

View File

@@ -301,6 +301,8 @@ builtinTypeForToken(const clang::Token &tok, const clang::ASTContext &context) {
return clang::QualType(context.WCharTy);
case clang::tok::kw_bool:
return clang::QualType(context.BoolTy);
case clang::tok::kw_char8_t:
return clang::QualType(context.Char8Ty);
case clang::tok::kw_char16_t:
return clang::QualType(context.Char16Ty);
case clang::tok::kw_char32_t:

View File

@@ -312,7 +312,6 @@ namespace {
case clang::BuiltinType::BFloat16:
case clang::BuiltinType::Float128:
case clang::BuiltinType::NullPtr:
case clang::BuiltinType::Char8:
case clang::BuiltinType::Ibm128:
return Type();

View File

@@ -38,6 +38,7 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
MAP(CChar, "char", false);
MAP(CWideChar, "wchar_t", false);
MAP(CChar8, "char8_t", false);
MAP(CChar16, "char16_t", false);
MAP(CChar32, "char32_t", false);

View File

@@ -138,6 +138,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
"# if __has_include(<uchar.h>)\n"
"# include <uchar.h>\n"
"# elif !defined(__cplusplus)\n"
"typedef unsigned char char8_t;\n"
"typedef uint_least16_t char16_t;\n"
"typedef uint_least32_t char32_t;\n"
"# endif\n"

View File

@@ -134,6 +134,9 @@ public typealias CWideChar = UInt16
public typealias CWideChar = Unicode.Scalar
#endif
/// The C++20 'char8_t' type, which has UTF-8 encoding.
public typealias CChar8 = UInt8
// FIXME: Swift should probably have a UTF-16 type other than UInt16.
//
/// The C++11 'char16_t' type, which has UTF-16 encoding.

View File

@@ -74,10 +74,10 @@ import gizmo
// CHECK-watchos: private unnamed_addr constant [23 x i8] c"v44@0:8C16S20I24Q28Q36\00"
// CHECK-xros: private unnamed_addr constant [23 x i8] c"v44@0:8C16S20I24Q28Q36\00"
@objc func testCChars(_ basic: CChar, wchar wide: CWideChar, char16: CChar16, char32: CChar32) {}
// CHECK-macosx: private unnamed_addr constant [20 x i8] c"v32@0:8c16i20S24i28\00"
// CHECK-ios: private unnamed_addr constant [20 x i8] c"v32@0:8c16i20S24i28\00"
// CHECK-tvos: private unnamed_addr constant [20 x i8] c"v32@0:8c16i20S24i28\00"
@objc func testCChars(_ basic: CChar, wchar wide: CWideChar, char8: CChar8, char16: CChar16, char32: CChar32) {}
// CHECK-macosx: private unnamed_addr constant [23 x i8] c"v36@0:8c16i20C24S28i32\00"
// CHECK-ios: private unnamed_addr constant [23 x i8] c"v36@0:8c16i20C24S28i32\00"
// CHECK-tvos: private unnamed_addr constant [23 x i8] c"v36@0:8c16i20C24S28i32\00"
// CHECK-watchos: private unnamed_addr constant [20 x i8] c"v32@0:8c16i20S24i28\00"
// CHECK-xros: private unnamed_addr constant [20 x i8] c"v32@0:8c16i20S24i28\00"

View File

@@ -6,4 +6,8 @@
extern char a_char;
extern wchar_t a_wchar;
#if __cplusplus
extern char8_t small_char;
#endif
#endif // TEST_INTEROP_C_CHARS_INPUTS_IMPORT_CCHAR_TYPES_H

View File

@@ -1,4 +1,7 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=ImportCCharTypes -I %S/Inputs -source-filename=x | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=ImportCCharTypes -I %S/Inputs -source-filename=x -cxx-interoperability-mode=default -Xcc -std=c++20 | %FileCheck %s --check-prefix=CHECK-CXX
// CHECK: var a_char: CChar
// CHECK: var a_wchar: wchar_t
// CHECK-CXX: var small_char: UInt8

View File

@@ -204,7 +204,7 @@ class NotObjC {}
// CHECK-NEXT: - (void)testSelector:(SEL _Nonnull)sel boolean:(BOOL)b;
// CHECK-NEXT: - (void)testCSignedTypes:(signed char)a b:(short)b c:(int)c d:(long)d e:(long long)e;
// CHECK-NEXT: - (void)testCUnsignedTypes:(unsigned char)a b:(unsigned short)b c:(unsigned int)c d:(unsigned long)d e:(unsigned long long)e;
// CHECK-NEXT: - (void)testCChars:(char)basic wchar:(wchar_t)wide char16:(char16_t)char16 char32:(char32_t)char32;
// CHECK-NEXT: - (void)testCChars:(char)basic wchar:(wchar_t)wide char8:(char8_t)char8 char16:(char16_t)char16 char32:(char32_t)char32;
// CHECK-NEXT: - (void)testCFloats:(float)a b:(double)b;
// CHECK-NEXT: - (void)testCBool:(bool)a;
// CHECK-NEXT: - (void)testSizedSignedTypes:(int8_t)a b:(int16_t)b c:(int32_t)c d:(int64_t)d;
@@ -250,7 +250,7 @@ class NotObjC {}
@objc func testCSignedTypes(_ a: CSignedChar, b: CShort, c: CInt, d: CLong, e: CLongLong) {}
@objc func testCUnsignedTypes(_ a: CUnsignedChar, b: CUnsignedShort, c: CUnsignedInt, d: CUnsignedLong, e: CUnsignedLongLong) {}
@objc func testCChars(_ basic: CChar, wchar wide: CWideChar, char16: CChar16, char32: CChar32) {}
@objc func testCChars(_ basic: CChar, wchar wide: CWideChar, char8: CChar8, char16: CChar16, char32: CChar32) {}
@objc func testCFloats(_ a: CFloat, b: CDouble) {}
@objc func testCBool(_ a: CBool) {}

View File

@@ -39,6 +39,7 @@ PrintTests.test("CustomStringConvertible") {
#else
hasDescription(CWideChar(42)!)
#endif
hasDescription(CChar8(42))
hasDescription(CChar16(42))
hasDescription(CChar32(42)!)
}
@@ -60,6 +61,7 @@ PrintTests.test("Printable") {
#else
expectPrinted("*", CWideChar(42)!)
#endif
expectPrinted("42", CChar8(42))
expectPrinted("42", CChar16(42))
expectPrinted("*", CChar32(42)!)
@@ -155,6 +157,7 @@ PrintTests.test("Printable") {
#else
expectPrinted("*", CWideChar(42)!)
#endif
expectPrinted("42", CChar8(42))
expectPrinted("42", CChar16(42))
expectPrinted("*", CChar32(42)!)
}