diff --git a/src/translate_c.zig b/src/translate_c.zig index ff9e1e5d0d..388fa8841e 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -2942,9 +2942,9 @@ fn transCharLiteral( suppress_as: SuppressCast, ) TransError!*ast.Node { const kind = stmt.getKind(); + const val = stmt.getValue(); const int_lit_node = switch (kind) { .Ascii, .UTF8 => blk: { - const val = stmt.getValue(); if (kind == .Ascii) { // C has a somewhat obscure feature called multi-character character // constant @@ -2960,13 +2960,15 @@ fn transCharLiteral( }; break :blk &node.base; }, - .UTF16, .UTF32, .Wide => return revertAndWarn( - rp, - error.UnsupportedTranslation, - @ptrCast(*const clang.Stmt, stmt).getBeginLoc(), - "TODO: support character literal kind {}", - .{kind}, - ), + .Wide, .UTF16, .UTF32 => blk: { + const token = try appendTokenFmt(rp.c, .CharLiteral, "'\\u{{{x}}}'", .{val}); + const node = try rp.c.arena.create(ast.Node.OneToken); + node.* = .{ + .base = .{ .tag = .CharLiteral }, + .token = token, + }; + break :blk &node.base; + }, }; if (suppress_as == .no_as) { return maybeSuppressResult(rp, scope, result_used, int_lit_node); diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index f719d0fe40..1395274251 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -719,4 +719,22 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\ return 0; \\} , ""); + + cases.add("Wide, UTF-16, and UTF-32 character literals", + \\#include + \\#include + \\int main() { + \\ wchar_t wc = L'™'; + \\ int utf16_char = u'™'; + \\ int utf32_char = U'💯'; + \\ if (wc != 8482) abort(); + \\ if (utf16_char != 8482) abort(); + \\ if (utf32_char != 128175) abort(); + \\ unsigned char c = wc; + \\ if (c != 0x22) abort(); + \\ c = utf32_char; + \\ if (c != 0xaf) abort(); + \\ return 0; + \\} + , ""); }