From 620bf695e8d595c67acbf1457a8a14a7013a8522 Mon Sep 17 00:00:00 2001 From: Vexu Date: Mon, 16 Dec 2019 07:43:18 +0200 Subject: [PATCH] organize tests --- test/translate_c.zig | 780 +++++++++++++++++++++---------------------- 1 file changed, 382 insertions(+), 398 deletions(-) diff --git a/test/translate_c.zig b/test/translate_c.zig index 7edbb0ea70..51069b65d6 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -162,6 +162,270 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); + cases.add_both("enums", + \\enum Foo { + \\ FooA, + \\ FooB, + \\ Foo1, + \\}; + , &[_][]const u8{ + \\pub const enum_Foo = extern enum { + \\ A, + \\ B, + \\ @"1", + \\}; + , + \\pub const FooA = enum_Foo.A; + , + \\pub const FooB = enum_Foo.B; + , + \\pub const Foo1 = enum_Foo.@"1"; + , + \\pub const Foo = enum_Foo; + }); + + cases.add_both("enums", + \\enum Foo { + \\ FooA = 2, + \\ FooB = 5, + \\ Foo1, + \\}; + , &[_][]const u8{ + \\pub const enum_Foo = extern enum { + \\ A = 2, + \\ B = 5, + \\ @"1" = 6, + \\}; + , + \\pub const FooA = enum_Foo.A; + , + \\pub const FooB = enum_Foo.B; + , + \\pub const Foo1 = enum_Foo.@"1"; + , + \\pub const Foo = enum_Foo; + }); + + cases.add_both("typedef of function in struct field", + \\typedef void lws_callback_function(void); + \\struct Foo { + \\ void (*func)(void); + \\ lws_callback_function *callback_http; + \\}; + , &[_][]const u8{ + \\pub const lws_callback_function = extern fn () void; + \\pub const struct_Foo = extern struct { + \\ func: ?extern fn () void, + \\ callback_http: ?lws_callback_function, + \\}; + }); + + cases.add_both("pointer to struct demoted to opaque due to bit fields", + \\struct Foo { + \\ unsigned int: 1; + \\}; + \\struct Bar { + \\ struct Foo *foo; + \\}; + , &[_][]const u8{ + \\pub const struct_Foo = @OpaqueType() + , + \\pub const struct_Bar = extern struct { + \\ foo: ?*struct_Foo, + \\}; + }); + + cases.add_both("macro with left shift", + \\#define REDISMODULE_READ (1<<0) + , &[_][]const u8{ + \\pub const REDISMODULE_READ = 1 << 0; + }); + + cases.add_both("double define struct", + \\typedef struct Bar Bar; + \\typedef struct Foo Foo; + \\ + \\struct Foo { + \\ Foo *a; + \\}; + \\ + \\struct Bar { + \\ Foo *a; + \\}; + , &[_][]const u8{ + \\pub const struct_Foo = extern struct { + \\ a: [*c]Foo, + \\}; + , + \\pub const Foo = struct_Foo; + , + \\pub const struct_Bar = extern struct { + \\ a: [*c]Foo, + \\}; + , + \\pub const Bar = struct_Bar; + }); + + cases.add_both("simple struct", + \\struct Foo { + \\ int x; + \\ char *y; + \\}; + , &[_][]const u8{ + \\const struct_Foo = extern struct { + \\ x: c_int, + \\ y: [*c]u8, + \\}; + , + \\pub const Foo = struct_Foo; + }); + + cases.add_both("self referential struct with function pointer", + \\struct Foo { + \\ void (*derp)(struct Foo *foo); + \\}; + , &[_][]const u8{ + \\pub const struct_Foo = extern struct { + \\ derp: ?extern fn ([*c]struct_Foo) void, + \\}; + , + \\pub const Foo = struct_Foo; + }); + + cases.add_both("struct prototype used in func", + \\struct Foo; + \\struct Foo *some_func(struct Foo *foo, int x); + , &[_][]const u8{ + \\pub const struct_Foo = @OpaqueType(); + , + \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo; + , + \\pub const Foo = struct_Foo; + }); + + cases.add_both("#define an unsigned integer literal", + \\#define CHANNEL_COUNT 24 + , &[_][]const u8{ + \\pub const CHANNEL_COUNT = 24; + }); + + cases.add_both("#define referencing another #define", + \\#define THING2 THING1 + \\#define THING1 1234 + , &[_][]const u8{ + \\pub const THING1 = 1234; + , + \\pub const THING2 = THING1; + }); + + cases.add_both("circular struct definitions", + \\struct Bar; + \\ + \\struct Foo { + \\ struct Bar *next; + \\}; + \\ + \\struct Bar { + \\ struct Foo *next; + \\}; + , &[_][]const u8{ + \\pub const struct_Bar = extern struct { + \\ next: [*c]struct_Foo, + \\}; + , + \\pub const struct_Foo = extern struct { + \\ next: [*c]struct_Bar, + \\}; + }); + + cases.add_both("#define string", + \\#define foo "a string" + , &[_][]const u8{ + \\pub const foo = "a string"; + }); + + cases.add_both("zig keywords in C code", + \\struct comptime { + \\ int defer; + \\}; + , &[_][]const u8{ + \\pub const struct_comptime = extern struct { + \\ @"defer": c_int, + \\}; + , + \\pub const @"comptime" = struct_comptime; + }); + + cases.add_both("macro with parens around negative number", + \\#define LUA_GLOBALSINDEX (-10002) + , &[_][]const u8{ + \\pub const LUA_GLOBALSINDEX = -10002; + }); + + cases.add_both( + "u integer suffix after 0 (zero) in macro definition", + "#define ZERO 0U", + &[_][]const u8{ + "pub const ZERO = @as(c_uint, 0);", + }, + ); + + cases.add_both( + "l integer suffix after 0 (zero) in macro definition", + "#define ZERO 0L", + &[_][]const u8{ + "pub const ZERO = @as(c_long, 0);", + }, + ); + + cases.add_both( + "ul integer suffix after 0 (zero) in macro definition", + "#define ZERO 0UL", + &[_][]const u8{ + "pub const ZERO = @as(c_ulong, 0);", + }, + ); + + cases.add_both( + "lu integer suffix after 0 (zero) in macro definition", + "#define ZERO 0LU", + &[_][]const u8{ + "pub const ZERO = @as(c_ulong, 0);", + }, + ); + + cases.add_both( + "ll integer suffix after 0 (zero) in macro definition", + "#define ZERO 0LL", + &[_][]const u8{ + "pub const ZERO = @as(c_longlong, 0);", + }, + ); + + cases.add_both( + "ull integer suffix after 0 (zero) in macro definition", + "#define ZERO 0ULL", + &[_][]const u8{ + "pub const ZERO = @as(c_ulonglong, 0);", + }, + ); + + cases.add_both( + "llu integer suffix after 0 (zero) in macro definition", + "#define ZERO 0LLU", + &[_][]const u8{ + "pub const ZERO = @as(c_ulonglong, 0);", + }, + ); + + cases.add_both( + "bitwise not on u-suffixed 0 (zero) in macro definition", + "#define NOT_ZERO (~0U)", + &[_][]const u8{ + "pub const NOT_ZERO = ~@as(c_uint, 0);", + }, + ); + /////////////// Cases that pass for only stage2 //////////////// cases.add_2("Parameterless function prototypes", @@ -202,22 +466,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add_2("field struct", - \\union OpenGLProcs { - \\ struct { - \\ int Clear; - \\ } gl; - \\}; - , &[_][]const u8{ - \\pub const union_OpenGLProcs = extern union { - \\ gl: extern struct { - \\ Clear: c_int, - \\ }, - \\}; - , - \\pub const OpenGLProcs = union_OpenGLProcs; - }); - cases.add_2("enums", \\typedef enum { \\ a, @@ -422,41 +670,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// - cases.add_both("typedef of function in struct field", - \\typedef void lws_callback_function(void); - \\struct Foo { - \\ void (*func)(void); - \\ lws_callback_function *callback_http; - \\}; - , &[_][]const u8{ - \\pub const lws_callback_function = extern fn () void; - \\pub const struct_Foo = extern struct { - \\ func: ?extern fn () void, - \\ callback_http: ?lws_callback_function, - \\}; - }); - - cases.add_both("pointer to struct demoted to opaque due to bit fields", - \\struct Foo { - \\ unsigned int: 1; - \\}; - \\struct Bar { - \\ struct Foo *foo; - \\}; - , &[_][]const u8{ - \\pub const struct_Foo = @OpaqueType() - , - \\pub const struct_Bar = extern struct { - \\ foo: ?*struct_Foo, - \\}; - }); - - cases.add_both("macro with left shift", - \\#define REDISMODULE_READ (1<<0) - , &[_][]const u8{ - \\pub const REDISMODULE_READ = 1 << 0; - }); - if (builtin.os != builtin.Os.windows) { // Windows treats this as an enum with type c_int cases.add("big negative enum init values when C ABI supports long long enums", @@ -594,31 +807,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add_both("double define struct", - \\typedef struct Bar Bar; - \\typedef struct Foo Foo; - \\ - \\struct Foo { - \\ Foo *a; - \\}; - \\ - \\struct Bar { - \\ Foo *a; - \\}; - , &[_][]const u8{ - \\pub const struct_Foo = extern struct { - \\ a: [*c]Foo, - \\}; - , - \\pub const Foo = struct_Foo; - , - \\pub const struct_Bar = extern struct { - \\ a: [*c]Foo, - \\}; - , - \\pub const Bar = struct_Bar; - }); - cases.addAllowWarnings("simple data types", \\#include \\int foo(char a, unsigned char b, signed char c); @@ -643,70 +831,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add_both("enums", - \\enum Foo { - \\ FooA, - \\ FooB, - \\ Foo1, - \\}; - , &[_][]const u8{ - \\pub const enum_Foo = extern enum { - \\ A, - \\ B, - \\ @"1", - \\}; - , - \\pub const FooA = enum_Foo.A; - , - \\pub const FooB = enum_Foo.B; - , - \\pub const Foo1 = enum_Foo.@"1"; - , - \\pub const Foo = enum_Foo; - }); - - cases.add_both("enums", - \\enum Foo { - \\ FooA = 2, - \\ FooB = 5, - \\ Foo1, - \\}; - , &[_][]const u8{ - \\pub const enum_Foo = extern enum { - \\ A = 2, - \\ B = 5, - \\ @"1" = 6, - \\}; - , - \\pub const FooA = enum_Foo.A; - , - \\pub const FooB = enum_Foo.B; - , - \\pub const Foo1 = enum_Foo.@"1"; - , - \\pub const Foo = enum_Foo; - }); - cases.add("restrict -> noalias", \\void foo(void *restrict bar, void *restrict); , &[_][]const u8{ \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void; }); - cases.add_both("simple struct", - \\struct Foo { - \\ int x; - \\ char *y; - \\}; - , &[_][]const u8{ - \\const struct_Foo = extern struct { - \\ x: c_int, - \\ y: [*c]u8, - \\}; - , - \\pub const Foo = struct_Foo; - }); - cases.add("qualified struct and enum", \\struct Foo { \\ int x; @@ -745,162 +875,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn func(array: [*c]c_int) void; }); - cases.add_both("self referential struct with function pointer", - \\struct Foo { - \\ void (*derp)(struct Foo *foo); - \\}; - , &[_][]const u8{ - \\pub const struct_Foo = extern struct { - \\ derp: ?extern fn ([*c]struct_Foo) void, - \\}; - , - \\pub const Foo = struct_Foo; - }); - - cases.add_both("struct prototype used in func", - \\struct Foo; - \\struct Foo *some_func(struct Foo *foo, int x); - , &[_][]const u8{ - \\pub const struct_Foo = @OpaqueType(); - , - \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo; - , - \\pub const Foo = struct_Foo; - }); - - cases.add("#define a char literal", - \\#define A_CHAR 'a' - , &[_][]const u8{ - \\pub const A_CHAR = 97; - }); - - cases.add_both("#define an unsigned integer literal", - \\#define CHANNEL_COUNT 24 - , &[_][]const u8{ - \\pub const CHANNEL_COUNT = 24; - }); - - cases.add_both("#define referencing another #define", - \\#define THING2 THING1 - \\#define THING1 1234 - , &[_][]const u8{ - \\pub const THING1 = 1234; - , - \\pub const THING2 = THING1; - }); - - cases.add_both("circular struct definitions", - \\struct Bar; - \\ - \\struct Foo { - \\ struct Bar *next; - \\}; - \\ - \\struct Bar { - \\ struct Foo *next; - \\}; - , &[_][]const u8{ - \\pub const struct_Bar = extern struct { - \\ next: [*c]struct_Foo, - \\}; - , - \\pub const struct_Foo = extern struct { - \\ next: [*c]struct_Bar, - \\}; - }); - - cases.add("generate inline func for #define global extern fn", - \\extern void (*fn_ptr)(void); - \\#define foo fn_ptr - \\ - \\extern char (*fn_ptr2)(int, float); - \\#define bar fn_ptr2 - , &[_][]const u8{ - \\pub extern var fn_ptr: ?extern fn () void; - , - \\pub inline fn foo() void { - \\ return fn_ptr.?(); - \\} - , - \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8; - , - \\pub inline fn bar(arg0: c_int, arg1: f32) u8 { - \\ return fn_ptr2.?(arg0, arg1); - \\} - }); - - cases.add_both("#define string", - \\#define foo "a string" - , &[_][]const u8{ - \\pub const foo = "a string"; - }); - cases.add("__cdecl doesn't mess up function pointers", \\void foo(void (__cdecl *fn_ptr)(void)); , &[_][]const u8{ \\pub extern fn foo(fn_ptr: ?extern fn () void) void; }); - cases.add("comment after integer literal", - \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = 32; - }); - - cases.add("u integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_uint, 32); - }); - - cases.add("l integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_long, 32); - }); - - cases.add("ul integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); - }); - - cases.add("lu integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); - }); - - cases.add("ll integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32); - }); - - cases.add("ull integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); - }); - - cases.add("llu integer suffix after hex literal", - \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ - , &[_][]const u8{ - \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); - }); - - cases.add_both("zig keywords in C code", - \\struct comptime { - \\ int defer; - \\}; - , &[_][]const u8{ - \\pub const struct_comptime = extern struct { - \\ @"defer": c_int, - \\}; - , - \\pub const @"comptime" = struct_comptime; - }); - cases.add("macro defines string literal with hex", \\#define FOO "aoeu\xab derp" \\#define FOO2 "aoeu\x0007a derp" @@ -925,12 +905,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub const FOO_CHAR = 63; }); - cases.add_both("macro with parens around negative number", - \\#define LUA_GLOBALSINDEX (-10002) - , &[_][]const u8{ - \\pub const LUA_GLOBALSINDEX = -10002; - }); - cases.addC("post increment", \\unsigned foo1(unsigned a) { \\ a++; @@ -1658,44 +1632,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add("macros with field targets", - \\typedef unsigned int GLbitfield; - \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask); - \\typedef void(*OpenGLProc)(void); - \\union OpenGLProcs { - \\ OpenGLProc ptr[1]; - \\ struct { - \\ PFNGLCLEARPROC Clear; - \\ } gl; - \\}; - \\extern union OpenGLProcs glProcs; - \\#define glClearUnion glProcs.gl.Clear - \\#define glClearPFN PFNGLCLEARPROC - , &[_][]const u8{ - \\pub const GLbitfield = c_uint; - , - \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; - , - \\pub const OpenGLProc = ?extern fn () void; - , - \\pub const union_OpenGLProcs = extern union { - \\ ptr: [1]OpenGLProc, - \\ gl: extern struct { - \\ Clear: PFNGLCLEARPROC, - \\ }, - \\}; - , - \\pub extern var glProcs: union_OpenGLProcs; - , - \\pub const glClearPFN = PFNGLCLEARPROC; - , - \\pub inline fn glClearUnion(arg0: GLbitfield) void { - \\ return glProcs.gl.Clear.?(arg0); - \\} - , - \\pub const OpenGLProcs = union_OpenGLProcs; - }); - cases.add("variable name shadowing", \\int foo(void) { \\ int x = 1; @@ -1762,12 +1698,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add("macro pointer cast", - \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) - , &[_][]const u8{ - \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE); - }); - cases.add("if on non-bool", \\enum SomeEnum { A, B, C }; \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) { @@ -1869,70 +1799,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add_both( - "u integer suffix after 0 (zero) in macro definition", - "#define ZERO 0U", - &[_][]const u8{ - "pub const ZERO = @as(c_uint, 0);", - }, - ); - - cases.add_both( - "l integer suffix after 0 (zero) in macro definition", - "#define ZERO 0L", - &[_][]const u8{ - "pub const ZERO = @as(c_long, 0);", - }, - ); - - cases.add_both( - "ul integer suffix after 0 (zero) in macro definition", - "#define ZERO 0UL", - &[_][]const u8{ - "pub const ZERO = @as(c_ulong, 0);", - }, - ); - - cases.add_both( - "lu integer suffix after 0 (zero) in macro definition", - "#define ZERO 0LU", - &[_][]const u8{ - "pub const ZERO = @as(c_ulong, 0);", - }, - ); - - cases.add_both( - "ll integer suffix after 0 (zero) in macro definition", - "#define ZERO 0LL", - &[_][]const u8{ - "pub const ZERO = @as(c_longlong, 0);", - }, - ); - - cases.add_both( - "ull integer suffix after 0 (zero) in macro definition", - "#define ZERO 0ULL", - &[_][]const u8{ - "pub const ZERO = @as(c_ulonglong, 0);", - }, - ); - - cases.add_both( - "llu integer suffix after 0 (zero) in macro definition", - "#define ZERO 0LLU", - &[_][]const u8{ - "pub const ZERO = @as(c_ulonglong, 0);", - }, - ); - - cases.add_both( - "bitwise not on u-suffixed 0 (zero) in macro definition", - "#define NOT_ZERO (~0U)", - &[_][]const u8{ - "pub const NOT_ZERO = ~@as(c_uint, 0);", - }, - ); - cases.addC("implicit casts", \\#include \\ @@ -2073,4 +1939,122 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() void {} \\pub export fn bar() void {} }); + + cases.add("#define a char literal", + \\#define A_CHAR 'a' + , &[_][]const u8{ + \\pub const A_CHAR = 97; + }); + + cases.add("generate inline func for #define global extern fn", + \\extern void (*fn_ptr)(void); + \\#define foo fn_ptr + \\ + \\extern char (*fn_ptr2)(int, float); + \\#define bar fn_ptr2 + , &[_][]const u8{ + \\pub extern var fn_ptr: ?extern fn () void; + , + \\pub inline fn foo() void { + \\ return fn_ptr.?(); + \\} + , + \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8; + , + \\pub inline fn bar(arg0: c_int, arg1: f32) u8 { + \\ return fn_ptr2.?(arg0, arg1); + \\} + }); + cases.add("comment after integer literal", + \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = 32; + }); + + cases.add("u integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_uint, 32); + }); + + cases.add("l integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_long, 32); + }); + + cases.add("ul integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); + }); + + cases.add("lu integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); + }); + + cases.add("ll integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32); + }); + + cases.add("ull integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); + }); + + cases.add("llu integer suffix after hex literal", + \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ + , &[_][]const u8{ + \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); + }); + + cases.add("macros with field targets", + \\typedef unsigned int GLbitfield; + \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask); + \\typedef void(*OpenGLProc)(void); + \\union OpenGLProcs { + \\ OpenGLProc ptr[1]; + \\ struct { + \\ PFNGLCLEARPROC Clear; + \\ } gl; + \\}; + \\extern union OpenGLProcs glProcs; + \\#define glClearUnion glProcs.gl.Clear + \\#define glClearPFN PFNGLCLEARPROC + , &[_][]const u8{ + \\pub const GLbitfield = c_uint; + , + \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; + , + \\pub const OpenGLProc = ?extern fn () void; + , + \\pub const union_OpenGLProcs = extern union { + \\ ptr: [1]OpenGLProc, + \\ gl: extern struct { + \\ Clear: PFNGLCLEARPROC, + \\ }, + \\}; + , + \\pub extern var glProcs: union_OpenGLProcs; + , + \\pub const glClearPFN = PFNGLCLEARPROC; + , + \\pub inline fn glClearUnion(arg0: GLbitfield) void { + \\ return glProcs.gl.Clear.?(arg0); + \\} + , + \\pub const OpenGLProcs = union_OpenGLProcs; + }); + + cases.add("macro pointer cast", + \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) + , &[_][]const u8{ + \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE); + }); + }