| ... | @@ -162,6 +162,270 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -162,6 +162,270 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 162 | \\} | 162 | \\} |
| 163 | }); | 163 | }); |
| 164 | | 164 | |
| | 165 | cases.add_both("enums", |
| | 166 | \\enum Foo { |
| | 167 | \\ FooA, |
| | 168 | \\ FooB, |
| | 169 | \\ Foo1, |
| | 170 | \\}; |
| | 171 | , &[_][]const u8{ |
| | 172 | \\pub const enum_Foo = extern enum { |
| | 173 | \\ A, |
| | 174 | \\ B, |
| | 175 | \\ @"1", |
| | 176 | \\}; |
| | 177 | , |
| | 178 | \\pub const FooA = enum_Foo.A; |
| | 179 | , |
| | 180 | \\pub const FooB = enum_Foo.B; |
| | 181 | , |
| | 182 | \\pub const Foo1 = enum_Foo.@"1"; |
| | 183 | , |
| | 184 | \\pub const Foo = enum_Foo; |
| | 185 | }); |
| | 186 | |
| | 187 | cases.add_both("enums", |
| | 188 | \\enum Foo { |
| | 189 | \\ FooA = 2, |
| | 190 | \\ FooB = 5, |
| | 191 | \\ Foo1, |
| | 192 | \\}; |
| | 193 | , &[_][]const u8{ |
| | 194 | \\pub const enum_Foo = extern enum { |
| | 195 | \\ A = 2, |
| | 196 | \\ B = 5, |
| | 197 | \\ @"1" = 6, |
| | 198 | \\}; |
| | 199 | , |
| | 200 | \\pub const FooA = enum_Foo.A; |
| | 201 | , |
| | 202 | \\pub const FooB = enum_Foo.B; |
| | 203 | , |
| | 204 | \\pub const Foo1 = enum_Foo.@"1"; |
| | 205 | , |
| | 206 | \\pub const Foo = enum_Foo; |
| | 207 | }); |
| | 208 | |
| | 209 | cases.add_both("typedef of function in struct field", |
| | 210 | \\typedef void lws_callback_function(void); |
| | 211 | \\struct Foo { |
| | 212 | \\ void (*func)(void); |
| | 213 | \\ lws_callback_function *callback_http; |
| | 214 | \\}; |
| | 215 | , &[_][]const u8{ |
| | 216 | \\pub const lws_callback_function = extern fn () void; |
| | 217 | \\pub const struct_Foo = extern struct { |
| | 218 | \\ func: ?extern fn () void, |
| | 219 | \\ callback_http: ?lws_callback_function, |
| | 220 | \\}; |
| | 221 | }); |
| | 222 | |
| | 223 | cases.add_both("pointer to struct demoted to opaque due to bit fields", |
| | 224 | \\struct Foo { |
| | 225 | \\ unsigned int: 1; |
| | 226 | \\}; |
| | 227 | \\struct Bar { |
| | 228 | \\ struct Foo *foo; |
| | 229 | \\}; |
| | 230 | , &[_][]const u8{ |
| | 231 | \\pub const struct_Foo = @OpaqueType() |
| | 232 | , |
| | 233 | \\pub const struct_Bar = extern struct { |
| | 234 | \\ foo: ?*struct_Foo, |
| | 235 | \\}; |
| | 236 | }); |
| | 237 | |
| | 238 | cases.add_both("macro with left shift", |
| | 239 | \\#define REDISMODULE_READ (1<<0) |
| | 240 | , &[_][]const u8{ |
| | 241 | \\pub const REDISMODULE_READ = 1 << 0; |
| | 242 | }); |
| | 243 | |
| | 244 | cases.add_both("double define struct", |
| | 245 | \\typedef struct Bar Bar; |
| | 246 | \\typedef struct Foo Foo; |
| | 247 | \\ |
| | 248 | \\struct Foo { |
| | 249 | \\ Foo *a; |
| | 250 | \\}; |
| | 251 | \\ |
| | 252 | \\struct Bar { |
| | 253 | \\ Foo *a; |
| | 254 | \\}; |
| | 255 | , &[_][]const u8{ |
| | 256 | \\pub const struct_Foo = extern struct { |
| | 257 | \\ a: [*c]Foo, |
| | 258 | \\}; |
| | 259 | , |
| | 260 | \\pub const Foo = struct_Foo; |
| | 261 | , |
| | 262 | \\pub const struct_Bar = extern struct { |
| | 263 | \\ a: [*c]Foo, |
| | 264 | \\}; |
| | 265 | , |
| | 266 | \\pub const Bar = struct_Bar; |
| | 267 | }); |
| | 268 | |
| | 269 | cases.add_both("simple struct", |
| | 270 | \\struct Foo { |
| | 271 | \\ int x; |
| | 272 | \\ char *y; |
| | 273 | \\}; |
| | 274 | , &[_][]const u8{ |
| | 275 | \\const struct_Foo = extern struct { |
| | 276 | \\ x: c_int, |
| | 277 | \\ y: [*c]u8, |
| | 278 | \\}; |
| | 279 | , |
| | 280 | \\pub const Foo = struct_Foo; |
| | 281 | }); |
| | 282 | |
| | 283 | cases.add_both("self referential struct with function pointer", |
| | 284 | \\struct Foo { |
| | 285 | \\ void (*derp)(struct Foo *foo); |
| | 286 | \\}; |
| | 287 | , &[_][]const u8{ |
| | 288 | \\pub const struct_Foo = extern struct { |
| | 289 | \\ derp: ?extern fn ([*c]struct_Foo) void, |
| | 290 | \\}; |
| | 291 | , |
| | 292 | \\pub const Foo = struct_Foo; |
| | 293 | }); |
| | 294 | |
| | 295 | cases.add_both("struct prototype used in func", |
| | 296 | \\struct Foo; |
| | 297 | \\struct Foo *some_func(struct Foo *foo, int x); |
| | 298 | , &[_][]const u8{ |
| | 299 | \\pub const struct_Foo = @OpaqueType(); |
| | 300 | , |
| | 301 | \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo; |
| | 302 | , |
| | 303 | \\pub const Foo = struct_Foo; |
| | 304 | }); |
| | 305 | |
| | 306 | cases.add_both("#define an unsigned integer literal", |
| | 307 | \\#define CHANNEL_COUNT 24 |
| | 308 | , &[_][]const u8{ |
| | 309 | \\pub const CHANNEL_COUNT = 24; |
| | 310 | }); |
| | 311 | |
| | 312 | cases.add_both("#define referencing another #define", |
| | 313 | \\#define THING2 THING1 |
| | 314 | \\#define THING1 1234 |
| | 315 | , &[_][]const u8{ |
| | 316 | \\pub const THING1 = 1234; |
| | 317 | , |
| | 318 | \\pub const THING2 = THING1; |
| | 319 | }); |
| | 320 | |
| | 321 | cases.add_both("circular struct definitions", |
| | 322 | \\struct Bar; |
| | 323 | \\ |
| | 324 | \\struct Foo { |
| | 325 | \\ struct Bar *next; |
| | 326 | \\}; |
| | 327 | \\ |
| | 328 | \\struct Bar { |
| | 329 | \\ struct Foo *next; |
| | 330 | \\}; |
| | 331 | , &[_][]const u8{ |
| | 332 | \\pub const struct_Bar = extern struct { |
| | 333 | \\ next: [*c]struct_Foo, |
| | 334 | \\}; |
| | 335 | , |
| | 336 | \\pub const struct_Foo = extern struct { |
| | 337 | \\ next: [*c]struct_Bar, |
| | 338 | \\}; |
| | 339 | }); |
| | 340 | |
| | 341 | cases.add_both("#define string", |
| | 342 | \\#define foo "a string" |
| | 343 | , &[_][]const u8{ |
| | 344 | \\pub const foo = "a string"; |
| | 345 | }); |
| | 346 | |
| | 347 | cases.add_both("zig keywords in C code", |
| | 348 | \\struct comptime { |
| | 349 | \\ int defer; |
| | 350 | \\}; |
| | 351 | , &[_][]const u8{ |
| | 352 | \\pub const struct_comptime = extern struct { |
| | 353 | \\ @"defer": c_int, |
| | 354 | \\}; |
| | 355 | , |
| | 356 | \\pub const @"comptime" = struct_comptime; |
| | 357 | }); |
| | 358 | |
| | 359 | cases.add_both("macro with parens around negative number", |
| | 360 | \\#define LUA_GLOBALSINDEX (-10002) |
| | 361 | , &[_][]const u8{ |
| | 362 | \\pub const LUA_GLOBALSINDEX = -10002; |
| | 363 | }); |
| | 364 | |
| | 365 | cases.add_both( |
| | 366 | "u integer suffix after 0 (zero) in macro definition", |
| | 367 | "#define ZERO 0U", |
| | 368 | &[_][]const u8{ |
| | 369 | "pub const ZERO = @as(c_uint, 0);", |
| | 370 | }, |
| | 371 | ); |
| | 372 | |
| | 373 | cases.add_both( |
| | 374 | "l integer suffix after 0 (zero) in macro definition", |
| | 375 | "#define ZERO 0L", |
| | 376 | &[_][]const u8{ |
| | 377 | "pub const ZERO = @as(c_long, 0);", |
| | 378 | }, |
| | 379 | ); |
| | 380 | |
| | 381 | cases.add_both( |
| | 382 | "ul integer suffix after 0 (zero) in macro definition", |
| | 383 | "#define ZERO 0UL", |
| | 384 | &[_][]const u8{ |
| | 385 | "pub const ZERO = @as(c_ulong, 0);", |
| | 386 | }, |
| | 387 | ); |
| | 388 | |
| | 389 | cases.add_both( |
| | 390 | "lu integer suffix after 0 (zero) in macro definition", |
| | 391 | "#define ZERO 0LU", |
| | 392 | &[_][]const u8{ |
| | 393 | "pub const ZERO = @as(c_ulong, 0);", |
| | 394 | }, |
| | 395 | ); |
| | 396 | |
| | 397 | cases.add_both( |
| | 398 | "ll integer suffix after 0 (zero) in macro definition", |
| | 399 | "#define ZERO 0LL", |
| | 400 | &[_][]const u8{ |
| | 401 | "pub const ZERO = @as(c_longlong, 0);", |
| | 402 | }, |
| | 403 | ); |
| | 404 | |
| | 405 | cases.add_both( |
| | 406 | "ull integer suffix after 0 (zero) in macro definition", |
| | 407 | "#define ZERO 0ULL", |
| | 408 | &[_][]const u8{ |
| | 409 | "pub const ZERO = @as(c_ulonglong, 0);", |
| | 410 | }, |
| | 411 | ); |
| | 412 | |
| | 413 | cases.add_both( |
| | 414 | "llu integer suffix after 0 (zero) in macro definition", |
| | 415 | "#define ZERO 0LLU", |
| | 416 | &[_][]const u8{ |
| | 417 | "pub const ZERO = @as(c_ulonglong, 0);", |
| | 418 | }, |
| | 419 | ); |
| | 420 | |
| | 421 | cases.add_both( |
| | 422 | "bitwise not on u-suffixed 0 (zero) in macro definition", |
| | 423 | "#define NOT_ZERO (~0U)", |
| | 424 | &[_][]const u8{ |
| | 425 | "pub const NOT_ZERO = ~@as(c_uint, 0);", |
| | 426 | }, |
| | 427 | ); |
| | 428 | |
| 165 | /////////////// Cases that pass for only stage2 //////////////// | 429 | /////////////// Cases that pass for only stage2 //////////////// |
| 166 | | 430 | |
| 167 | cases.add_2("Parameterless function prototypes", | 431 | cases.add_2("Parameterless function prototypes", |
| ... | @@ -202,22 +466,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -202,22 +466,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 202 | \\} | 466 | \\} |
| 203 | }); | 467 | }); |
| 204 | | 468 | |
| 205 | cases.add_2("field struct", | | |
| 206 | \\union OpenGLProcs { | | |
| 207 | \\ struct { | | |
| 208 | \\ int Clear; | | |
| 209 | \\ } gl; | | |
| 210 | \\}; | | |
| 211 | , &[_][]const u8{ | | |
| 212 | \\pub const union_OpenGLProcs = extern union { | | |
| 213 | \\ gl: extern struct { | | |
| 214 | \\ Clear: c_int, | | |
| 215 | \\ }, | | |
| 216 | \\}; | | |
| 217 | , | | |
| 218 | \\pub const OpenGLProcs = union_OpenGLProcs; | | |
| 219 | }); | | |
| 220 | | | |
| 221 | cases.add_2("enums", | 469 | cases.add_2("enums", |
| 222 | \\typedef enum { | 470 | \\typedef enum { |
| 223 | \\ a, | 471 | \\ a, |
| ... | @@ -408,54 +656,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -408,54 +656,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 408 | , &[_][]const u8{ | 656 | , &[_][]const u8{ |
| 409 | \\pub inline fn BASIC(c: var) @TypeOf(c * 2) { | 657 | \\pub inline fn BASIC(c: var) @TypeOf(c * 2) { |
| 410 | \\ return c * 2; | 658 | \\ return c * 2; |
| 411 | \\} | 659 | \\} |
| 412 | }); | | |
| 413 | | | |
| 414 | cases.add_2("macro escape sequences", | | |
| 415 | \\#define FOO "aoeu\xab derp" | | |
| 416 | \\#define FOO2 "aoeu\a derp" | | |
| 417 | , &[_][]const u8{ | | |
| 418 | \\pub const FOO = "aoeu\xab derp"; | | |
| 419 | , | | |
| 420 | \\pub const FOO2 = "aoeu\x07 derp"; | | |
| 421 | }); | | |
| 422 | | | |
| 423 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// | | |
| 424 | | | |
| 425 | cases.add_both("typedef of function in struct field", | | |
| 426 | \\typedef void lws_callback_function(void); | | |
| 427 | \\struct Foo { | | |
| 428 | \\ void (*func)(void); | | |
| 429 | \\ lws_callback_function *callback_http; | | |
| 430 | \\}; | | |
| 431 | , &[_][]const u8{ | | |
| 432 | \\pub const lws_callback_function = extern fn () void; | | |
| 433 | \\pub const struct_Foo = extern struct { | | |
| 434 | \\ func: ?extern fn () void, | | |
| 435 | \\ callback_http: ?lws_callback_function, | | |
| 436 | \\}; | | |
| 437 | }); | 660 | }); |
| 438 | | 661 | |
| 439 | cases.add_both("pointer to struct demoted to opaque due to bit fields", | 662 | cases.add_2("macro escape sequences", |
| 440 | \\struct Foo { | 663 | \\#define FOO "aoeu\xab derp" |
| 441 | \\ unsigned int: 1; | 664 | \\#define FOO2 "aoeu\a derp" |
| 442 | \\}; | | |
| 443 | \\struct Bar { | | |
| 444 | \\ struct Foo *foo; | | |
| 445 | \\}; | | |
| 446 | , &[_][]const u8{ | 665 | , &[_][]const u8{ |
| 447 | \\pub const struct_Foo = @OpaqueType() | 666 | \\pub const FOO = "aoeu\xab derp"; |
| 448 | , | 667 | , |
| 449 | \\pub const struct_Bar = extern struct { | 668 | \\pub const FOO2 = "aoeu\x07 derp"; |
| 450 | \\ foo: ?*struct_Foo, | | |
| 451 | \\}; | | |
| 452 | }); | 669 | }); |
| 453 | | 670 | |
| 454 | cases.add_both("macro with left shift", | 671 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| 455 | \\#define REDISMODULE_READ (1<<0) | | |
| 456 | , &[_][]const u8{ | | |
| 457 | \\pub const REDISMODULE_READ = 1 << 0; | | |
| 458 | }); | | |
| 459 | | 672 | |
| 460 | if (builtin.os != builtin.Os.windows) { | 673 | if (builtin.os != builtin.Os.windows) { |
| 461 | // Windows treats this as an enum with type c_int | 674 | // Windows treats this as an enum with type c_int |
| ... | @@ -594,31 +807,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -594,31 +807,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 594 | \\} | 807 | \\} |
| 595 | }); | 808 | }); |
| 596 | | 809 | |
| 597 | cases.add_both("double define struct", | | |
| 598 | \\typedef struct Bar Bar; | | |
| 599 | \\typedef struct Foo Foo; | | |
| 600 | \\ | | |
| 601 | \\struct Foo { | | |
| 602 | \\ Foo *a; | | |
| 603 | \\}; | | |
| 604 | \\ | | |
| 605 | \\struct Bar { | | |
| 606 | \\ Foo *a; | | |
| 607 | \\}; | | |
| 608 | , &[_][]const u8{ | | |
| 609 | \\pub const struct_Foo = extern struct { | | |
| 610 | \\ a: [*c]Foo, | | |
| 611 | \\}; | | |
| 612 | , | | |
| 613 | \\pub const Foo = struct_Foo; | | |
| 614 | , | | |
| 615 | \\pub const struct_Bar = extern struct { | | |
| 616 | \\ a: [*c]Foo, | | |
| 617 | \\}; | | |
| 618 | , | | |
| 619 | \\pub const Bar = struct_Bar; | | |
| 620 | }); | | |
| 621 | | | |
| 622 | cases.addAllowWarnings("simple data types", | 810 | cases.addAllowWarnings("simple data types", |
| 623 | \\#include <stdint.h> | 811 | \\#include <stdint.h> |
| 624 | \\int foo(char a, unsigned char b, signed char c); | 812 | \\int foo(char a, unsigned char b, signed char c); |
| ... | @@ -643,70 +831,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -643,70 +831,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 643 | \\} | 831 | \\} |
| 644 | }); | 832 | }); |
| 645 | | 833 | |
| 646 | cases.add_both("enums", | | |
| 647 | \\enum Foo { | | |
| 648 | \\ FooA, | | |
| 649 | \\ FooB, | | |
| 650 | \\ Foo1, | | |
| 651 | \\}; | | |
| 652 | , &[_][]const u8{ | | |
| 653 | \\pub const enum_Foo = extern enum { | | |
| 654 | \\ A, | | |
| 655 | \\ B, | | |
| 656 | \\ @"1", | | |
| 657 | \\}; | | |
| 658 | , | | |
| 659 | \\pub const FooA = enum_Foo.A; | | |
| 660 | , | | |
| 661 | \\pub const FooB = enum_Foo.B; | | |
| 662 | , | | |
| 663 | \\pub const Foo1 = enum_Foo.@"1"; | | |
| 664 | , | | |
| 665 | \\pub const Foo = enum_Foo; | | |
| 666 | }); | | |
| 667 | | | |
| 668 | cases.add_both("enums", | | |
| 669 | \\enum Foo { | | |
| 670 | \\ FooA = 2, | | |
| 671 | \\ FooB = 5, | | |
| 672 | \\ Foo1, | | |
| 673 | \\}; | | |
| 674 | , &[_][]const u8{ | | |
| 675 | \\pub const enum_Foo = extern enum { | | |
| 676 | \\ A = 2, | | |
| 677 | \\ B = 5, | | |
| 678 | \\ @"1" = 6, | | |
| 679 | \\}; | | |
| 680 | , | | |
| 681 | \\pub const FooA = enum_Foo.A; | | |
| 682 | , | | |
| 683 | \\pub const FooB = enum_Foo.B; | | |
| 684 | , | | |
| 685 | \\pub const Foo1 = enum_Foo.@"1"; | | |
| 686 | , | | |
| 687 | \\pub const Foo = enum_Foo; | | |
| 688 | }); | | |
| 689 | | | |
| 690 | cases.add("restrict -> noalias", | 834 | cases.add("restrict -> noalias", |
| 691 | \\void foo(void *restrict bar, void *restrict); | 835 | \\void foo(void *restrict bar, void *restrict); |
| 692 | , &[_][]const u8{ | 836 | , &[_][]const u8{ |
| 693 | \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void; | 837 | \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void; |
| 694 | }); | 838 | }); |
| 695 | | 839 | |
| 696 | cases.add_both("simple struct", | | |
| 697 | \\struct Foo { | | |
| 698 | \\ int x; | | |
| 699 | \\ char *y; | | |
| 700 | \\}; | | |
| 701 | , &[_][]const u8{ | | |
| 702 | \\const struct_Foo = extern struct { | | |
| 703 | \\ x: c_int, | | |
| 704 | \\ y: [*c]u8, | | |
| 705 | \\}; | | |
| 706 | , | | |
| 707 | \\pub const Foo = struct_Foo; | | |
| 708 | }); | | |
| 709 | | | |
| 710 | cases.add("qualified struct and enum", | 840 | cases.add("qualified struct and enum", |
| 711 | \\struct Foo { | 841 | \\struct Foo { |
| 712 | \\ int x; | 842 | \\ int x; |
| ... | @@ -731,174 +861,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -731,174 +861,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 731 | \\pub const BarA = enum_Bar.A; | 861 | \\pub const BarA = enum_Bar.A; |
| 732 | , | 862 | , |
| 733 | \\pub const BarB = enum_Bar.B; | 863 | \\pub const BarB = enum_Bar.B; |
| 734 | , | 864 | , |
| 735 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void; | 865 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void; |
| 736 | , | 866 | , |
| 737 | \\pub const Foo = struct_Foo; | 867 | \\pub const Foo = struct_Foo; |
| 738 | , | 868 | , |
| 739 | \\pub const Bar = enum_Bar; | 869 | \\pub const Bar = enum_Bar; |
| 740 | }); | | |
| 741 | | | |
| 742 | cases.add("constant size array", | | |
| 743 | \\void func(int array[20]); | | |
| 744 | , &[_][]const u8{ | | |
| 745 | \\pub extern fn func(array: [*c]c_int) void; | | |
| 746 | }); | | |
| 747 | | | |
| 748 | cases.add_both("self referential struct with function pointer", | | |
| 749 | \\struct Foo { | | |
| 750 | \\ void (*derp)(struct Foo *foo); | | |
| 751 | \\}; | | |
| 752 | , &[_][]const u8{ | | |
| 753 | \\pub const struct_Foo = extern struct { | | |
| 754 | \\ derp: ?extern fn ([*c]struct_Foo) void, | | |
| 755 | \\}; | | |
| 756 | , | | |
| 757 | \\pub const Foo = struct_Foo; | | |
| 758 | }); | | |
| 759 | | | |
| 760 | cases.add_both("struct prototype used in func", | | |
| 761 | \\struct Foo; | | |
| 762 | \\struct Foo *some_func(struct Foo *foo, int x); | | |
| 763 | , &[_][]const u8{ | | |
| 764 | \\pub const struct_Foo = @OpaqueType(); | | |
| 765 | , | | |
| 766 | \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo; | | |
| 767 | , | | |
| 768 | \\pub const Foo = struct_Foo; | | |
| 769 | }); | | |
| 770 | | | |
| 771 | cases.add("#define a char literal", | | |
| 772 | \\#define A_CHAR 'a' | | |
| 773 | , &[_][]const u8{ | | |
| 774 | \\pub const A_CHAR = 97; | | |
| 775 | }); | | |
| 776 | | | |
| 777 | cases.add_both("#define an unsigned integer literal", | | |
| 778 | \\#define CHANNEL_COUNT 24 | | |
| 779 | , &[_][]const u8{ | | |
| 780 | \\pub const CHANNEL_COUNT = 24; | | |
| 781 | }); | | |
| 782 | | | |
| 783 | cases.add_both("#define referencing another #define", | | |
| 784 | \\#define THING2 THING1 | | |
| 785 | \\#define THING1 1234 | | |
| 786 | , &[_][]const u8{ | | |
| 787 | \\pub const THING1 = 1234; | | |
| 788 | , | | |
| 789 | \\pub const THING2 = THING1; | | |
| 790 | }); | | |
| 791 | | | |
| 792 | cases.add_both("circular struct definitions", | | |
| 793 | \\struct Bar; | | |
| 794 | \\ | | |
| 795 | \\struct Foo { | | |
| 796 | \\ struct Bar *next; | | |
| 797 | \\}; | | |
| 798 | \\ | | |
| 799 | \\struct Bar { | | |
| 800 | \\ struct Foo *next; | | |
| 801 | \\}; | | |
| 802 | , &[_][]const u8{ | | |
| 803 | \\pub const struct_Bar = extern struct { | | |
| 804 | \\ next: [*c]struct_Foo, | | |
| 805 | \\}; | | |
| 806 | , | | |
| 807 | \\pub const struct_Foo = extern struct { | | |
| 808 | \\ next: [*c]struct_Bar, | | |
| 809 | \\}; | | |
| 810 | }); | | |
| 811 | | | |
| 812 | cases.add("generate inline func for #define global extern fn", | | |
| 813 | \\extern void (*fn_ptr)(void); | | |
| 814 | \\#define foo fn_ptr | | |
| 815 | \\ | | |
| 816 | \\extern char (*fn_ptr2)(int, float); | | |
| 817 | \\#define bar fn_ptr2 | | |
| 818 | , &[_][]const u8{ | | |
| 819 | \\pub extern var fn_ptr: ?extern fn () void; | | |
| 820 | , | | |
| 821 | \\pub inline fn foo() void { | | |
| 822 | \\ return fn_ptr.?(); | | |
| 823 | \\} | | |
| 824 | , | | |
| 825 | \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8; | | |
| 826 | , | | |
| 827 | \\pub inline fn bar(arg0: c_int, arg1: f32) u8 { | | |
| 828 | \\ return fn_ptr2.?(arg0, arg1); | | |
| 829 | \\} | | |
| 830 | }); | | |
| 831 | | | |
| 832 | cases.add_both("#define string", | | |
| 833 | \\#define foo "a string" | | |
| 834 | , &[_][]const u8{ | | |
| 835 | \\pub const foo = "a string"; | | |
| 836 | }); | | |
| 837 | | | |
| 838 | cases.add("__cdecl doesn't mess up function pointers", | | |
| 839 | \\void foo(void (__cdecl *fn_ptr)(void)); | | |
| 840 | , &[_][]const u8{ | | |
| 841 | \\pub extern fn foo(fn_ptr: ?extern fn () void) void; | | |
| 842 | }); | | |
| 843 | | | |
| 844 | cases.add("comment after integer literal", | | |
| 845 | \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 846 | , &[_][]const u8{ | | |
| 847 | \\pub const SDL_INIT_VIDEO = 32; | | |
| 848 | }); | | |
| 849 | | | |
| 850 | cases.add("u integer suffix after hex literal", | | |
| 851 | \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 852 | , &[_][]const u8{ | | |
| 853 | \\pub const SDL_INIT_VIDEO = @as(c_uint, 32); | | |
| 854 | }); | | |
| 855 | | | |
| 856 | cases.add("l integer suffix after hex literal", | | |
| 857 | \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 858 | , &[_][]const u8{ | | |
| 859 | \\pub const SDL_INIT_VIDEO = @as(c_long, 32); | | |
| 860 | }); | | |
| 861 | | | |
| 862 | cases.add("ul integer suffix after hex literal", | | |
| 863 | \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 864 | , &[_][]const u8{ | | |
| 865 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); | | |
| 866 | }); | | |
| 867 | | | |
| 868 | cases.add("lu integer suffix after hex literal", | | |
| 869 | \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 870 | , &[_][]const u8{ | | |
| 871 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); | | |
| 872 | }); | | |
| 873 | | | |
| 874 | cases.add("ll integer suffix after hex literal", | | |
| 875 | \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 876 | , &[_][]const u8{ | | |
| 877 | \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32); | | |
| 878 | }); | | |
| 879 | | | |
| 880 | cases.add("ull integer suffix after hex literal", | | |
| 881 | \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | | |
| 882 | , &[_][]const u8{ | | |
| 883 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); | | |
| 884 | }); | 870 | }); |
| 885 | | 871 | |
| 886 | cases.add("llu integer suffix after hex literal", | 872 | cases.add("constant size array", |
| 887 | \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ | 873 | \\void func(int array[20]); |
| 888 | , &[_][]const u8{ | 874 | , &[_][]const u8{ |
| 889 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); | 875 | \\pub extern fn func(array: [*c]c_int) void; |
| 890 | }); | 876 | }); |
| 891 | | 877 | |
| 892 | cases.add_both("zig keywords in C code", | 878 | cases.add("__cdecl doesn't mess up function pointers", |
| 893 | \\struct comptime { | 879 | \\void foo(void (__cdecl *fn_ptr)(void)); |
| 894 | \\ int defer; | | |
| 895 | \\}; | | |
| 896 | , &[_][]const u8{ | 880 | , &[_][]const u8{ |
| 897 | \\pub const struct_comptime = extern struct { | 881 | \\pub extern fn foo(fn_ptr: ?extern fn () void) void; |
| 898 | \\ @"defer": c_int, | | |
| 899 | \\}; | | |
| 900 | , | | |
| 901 | \\pub const @"comptime" = struct_comptime; | | |
| 902 | }); | 882 | }); |
| 903 | | 883 | |
| 904 | cases.add("macro defines string literal with hex", | 884 | cases.add("macro defines string literal with hex", |
| ... | @@ -925,12 +905,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -925,12 +905,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 925 | \\pub const FOO_CHAR = 63; | 905 | \\pub const FOO_CHAR = 63; |
| 926 | }); | 906 | }); |
| 927 | | 907 | |
| 928 | cases.add_both("macro with parens around negative number", | | |
| 929 | \\#define LUA_GLOBALSINDEX (-10002) | | |
| 930 | , &[_][]const u8{ | | |
| 931 | \\pub const LUA_GLOBALSINDEX = -10002; | | |
| 932 | }); | | |
| 933 | | | |
| 934 | cases.addC("post increment", | 908 | cases.addC("post increment", |
| 935 | \\unsigned foo1(unsigned a) { | 909 | \\unsigned foo1(unsigned a) { |
| 936 | \\ a++; | 910 | \\ a++; |
| ... | @@ -1658,44 +1632,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1658,44 +1632,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1658 | \\} | 1632 | \\} |
| 1659 | }); | 1633 | }); |
| 1660 | | 1634 | |
| 1661 | cases.add("macros with field targets", | | |
| 1662 | \\typedef unsigned int GLbitfield; | | |
| 1663 | \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask); | | |
| 1664 | \\typedef void(*OpenGLProc)(void); | | |
| 1665 | \\union OpenGLProcs { | | |
| 1666 | \\ OpenGLProc ptr[1]; | | |
| 1667 | \\ struct { | | |
| 1668 | \\ PFNGLCLEARPROC Clear; | | |
| 1669 | \\ } gl; | | |
| 1670 | \\}; | | |
| 1671 | \\extern union OpenGLProcs glProcs; | | |
| 1672 | \\#define glClearUnion glProcs.gl.Clear | | |
| 1673 | \\#define glClearPFN PFNGLCLEARPROC | | |
| 1674 | , &[_][]const u8{ | | |
| 1675 | \\pub const GLbitfield = c_uint; | | |
| 1676 | , | | |
| 1677 | \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; | | |
| 1678 | , | | |
| 1679 | \\pub const OpenGLProc = ?extern fn () void; | | |
| 1680 | , | | |
| 1681 | \\pub const union_OpenGLProcs = extern union { | | |
| 1682 | \\ ptr: [1]OpenGLProc, | | |
| 1683 | \\ gl: extern struct { | | |
| 1684 | \\ Clear: PFNGLCLEARPROC, | | |
| 1685 | \\ }, | | |
| 1686 | \\}; | | |
| 1687 | , | | |
| 1688 | \\pub extern var glProcs: union_OpenGLProcs; | | |
| 1689 | , | | |
| 1690 | \\pub const glClearPFN = PFNGLCLEARPROC; | | |
| 1691 | , | | |
| 1692 | \\pub inline fn glClearUnion(arg0: GLbitfield) void { | | |
| 1693 | \\ return glProcs.gl.Clear.?(arg0); | | |
| 1694 | \\} | | |
| 1695 | , | | |
| 1696 | \\pub const OpenGLProcs = union_OpenGLProcs; | | |
| 1697 | }); | | |
| 1698 | | | |
| 1699 | cases.add("variable name shadowing", | 1635 | cases.add("variable name shadowing", |
| 1700 | \\int foo(void) { | 1636 | \\int foo(void) { |
| 1701 | \\ int x = 1; | 1637 | \\ int x = 1; |
| ... | @@ -1762,12 +1698,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1762,12 +1698,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1762 | \\} | 1698 | \\} |
| 1763 | }); | 1699 | }); |
| 1764 | | 1700 | |
| 1765 | cases.add("macro pointer cast", | | |
| 1766 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) | | |
| 1767 | , &[_][]const u8{ | | |
| 1768 | \\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); | | |
| 1769 | }); | | |
| 1770 | | | |
| 1771 | cases.add("if on non-bool", | 1701 | cases.add("if on non-bool", |
| 1772 | \\enum SomeEnum { A, B, C }; | 1702 | \\enum SomeEnum { A, B, C }; |
| 1773 | \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) { | 1703 | \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) { |
| ... | @@ -1869,70 +1799,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1869,70 +1799,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1869 | \\} | 1799 | \\} |
| 1870 | }); | 1800 | }); |
| 1871 | | 1801 | |
| 1872 | cases.add_both( | | |
| 1873 | "u integer suffix after 0 (zero) in macro definition", | | |
| 1874 | "#define ZERO 0U", | | |
| 1875 | &[_][]const u8{ | | |
| 1876 | "pub const ZERO = @as(c_uint, 0);", | | |
| 1877 | }, | | |
| 1878 | ); | | |
| 1879 | | | |
| 1880 | cases.add_both( | | |
| 1881 | "l integer suffix after 0 (zero) in macro definition", | | |
| 1882 | "#define ZERO 0L", | | |
| 1883 | &[_][]const u8{ | | |
| 1884 | "pub const ZERO = @as(c_long, 0);", | | |
| 1885 | }, | | |
| 1886 | ); | | |
| 1887 | | | |
| 1888 | cases.add_both( | | |
| 1889 | "ul integer suffix after 0 (zero) in macro definition", | | |
| 1890 | "#define ZERO 0UL", | | |
| 1891 | &[_][]const u8{ | | |
| 1892 | "pub const ZERO = @as(c_ulong, 0);", | | |
| 1893 | }, | | |
| 1894 | ); | | |
| 1895 | | | |
| 1896 | cases.add_both( | | |
| 1897 | "lu integer suffix after 0 (zero) in macro definition", | | |
| 1898 | "#define ZERO 0LU", | | |
| 1899 | &[_][]const u8{ | | |
| 1900 | "pub const ZERO = @as(c_ulong, 0);", | | |
| 1901 | }, | | |
| 1902 | ); | | |
| 1903 | | | |
| 1904 | cases.add_both( | | |
| 1905 | "ll integer suffix after 0 (zero) in macro definition", | | |
| 1906 | "#define ZERO 0LL", | | |
| 1907 | &[_][]const u8{ | | |
| 1908 | "pub const ZERO = @as(c_longlong, 0);", | | |
| 1909 | }, | | |
| 1910 | ); | | |
| 1911 | | | |
| 1912 | cases.add_both( | | |
| 1913 | "ull integer suffix after 0 (zero) in macro definition", | | |
| 1914 | "#define ZERO 0ULL", | | |
| 1915 | &[_][]const u8{ | | |
| 1916 | "pub const ZERO = @as(c_ulonglong, 0);", | | |
| 1917 | }, | | |
| 1918 | ); | | |
| 1919 | | | |
| 1920 | cases.add_both( | | |
| 1921 | "llu integer suffix after 0 (zero) in macro definition", | | |
| 1922 | "#define ZERO 0LLU", | | |
| 1923 | &[_][]const u8{ | | |
| 1924 | "pub const ZERO = @as(c_ulonglong, 0);", | | |
| 1925 | }, | | |
| 1926 | ); | | |
| 1927 | | | |
| 1928 | cases.add_both( | | |
| 1929 | "bitwise not on u-suffixed 0 (zero) in macro definition", | | |
| 1930 | "#define NOT_ZERO (~0U)", | | |
| 1931 | &[_][]const u8{ | | |
| 1932 | "pub const NOT_ZERO = ~@as(c_uint, 0);", | | |
| 1933 | }, | | |
| 1934 | ); | | |
| 1935 | | | |
| 1936 | cases.addC("implicit casts", | 1802 | cases.addC("implicit casts", |
| 1937 | \\#include <stdbool.h> | 1803 | \\#include <stdbool.h> |
| 1938 | \\ | 1804 | \\ |
| ... | @@ -2073,4 +1939,122 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2073,4 +1939,122 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2073 | \\pub export fn foo() void {} | 1939 | \\pub export fn foo() void {} |
| 2074 | \\pub export fn bar() void {} | 1940 | \\pub export fn bar() void {} |
| 2075 | }); | 1941 | }); |
| | 1942 | |
| | 1943 | cases.add("#define a char literal", |
| | 1944 | \\#define A_CHAR 'a' |
| | 1945 | , &[_][]const u8{ |
| | 1946 | \\pub const A_CHAR = 97; |
| | 1947 | }); |
| | 1948 | |
| | 1949 | cases.add("generate inline func for #define global extern fn", |
| | 1950 | \\extern void (*fn_ptr)(void); |
| | 1951 | \\#define foo fn_ptr |
| | 1952 | \\ |
| | 1953 | \\extern char (*fn_ptr2)(int, float); |
| | 1954 | \\#define bar fn_ptr2 |
| | 1955 | , &[_][]const u8{ |
| | 1956 | \\pub extern var fn_ptr: ?extern fn () void; |
| | 1957 | , |
| | 1958 | \\pub inline fn foo() void { |
| | 1959 | \\ return fn_ptr.?(); |
| | 1960 | \\} |
| | 1961 | , |
| | 1962 | \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8; |
| | 1963 | , |
| | 1964 | \\pub inline fn bar(arg0: c_int, arg1: f32) u8 { |
| | 1965 | \\ return fn_ptr2.?(arg0, arg1); |
| | 1966 | \\} |
| | 1967 | }); |
| | 1968 | cases.add("comment after integer literal", |
| | 1969 | \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 1970 | , &[_][]const u8{ |
| | 1971 | \\pub const SDL_INIT_VIDEO = 32; |
| | 1972 | }); |
| | 1973 | |
| | 1974 | cases.add("u integer suffix after hex literal", |
| | 1975 | \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 1976 | , &[_][]const u8{ |
| | 1977 | \\pub const SDL_INIT_VIDEO = @as(c_uint, 32); |
| | 1978 | }); |
| | 1979 | |
| | 1980 | cases.add("l integer suffix after hex literal", |
| | 1981 | \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 1982 | , &[_][]const u8{ |
| | 1983 | \\pub const SDL_INIT_VIDEO = @as(c_long, 32); |
| | 1984 | }); |
| | 1985 | |
| | 1986 | cases.add("ul integer suffix after hex literal", |
| | 1987 | \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 1988 | , &[_][]const u8{ |
| | 1989 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); |
| | 1990 | }); |
| | 1991 | |
| | 1992 | cases.add("lu integer suffix after hex literal", |
| | 1993 | \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 1994 | , &[_][]const u8{ |
| | 1995 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); |
| | 1996 | }); |
| | 1997 | |
| | 1998 | cases.add("ll integer suffix after hex literal", |
| | 1999 | \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 2000 | , &[_][]const u8{ |
| | 2001 | \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32); |
| | 2002 | }); |
| | 2003 | |
| | 2004 | cases.add("ull integer suffix after hex literal", |
| | 2005 | \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 2006 | , &[_][]const u8{ |
| | 2007 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); |
| | 2008 | }); |
| | 2009 | |
| | 2010 | cases.add("llu integer suffix after hex literal", |
| | 2011 | \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| | 2012 | , &[_][]const u8{ |
| | 2013 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); |
| | 2014 | }); |
| | 2015 | |
| | 2016 | cases.add("macros with field targets", |
| | 2017 | \\typedef unsigned int GLbitfield; |
| | 2018 | \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask); |
| | 2019 | \\typedef void(*OpenGLProc)(void); |
| | 2020 | \\union OpenGLProcs { |
| | 2021 | \\ OpenGLProc ptr[1]; |
| | 2022 | \\ struct { |
| | 2023 | \\ PFNGLCLEARPROC Clear; |
| | 2024 | \\ } gl; |
| | 2025 | \\}; |
| | 2026 | \\extern union OpenGLProcs glProcs; |
| | 2027 | \\#define glClearUnion glProcs.gl.Clear |
| | 2028 | \\#define glClearPFN PFNGLCLEARPROC |
| | 2029 | , &[_][]const u8{ |
| | 2030 | \\pub const GLbitfield = c_uint; |
| | 2031 | , |
| | 2032 | \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; |
| | 2033 | , |
| | 2034 | \\pub const OpenGLProc = ?extern fn () void; |
| | 2035 | , |
| | 2036 | \\pub const union_OpenGLProcs = extern union { |
| | 2037 | \\ ptr: [1]OpenGLProc, |
| | 2038 | \\ gl: extern struct { |
| | 2039 | \\ Clear: PFNGLCLEARPROC, |
| | 2040 | \\ }, |
| | 2041 | \\}; |
| | 2042 | , |
| | 2043 | \\pub extern var glProcs: union_OpenGLProcs; |
| | 2044 | , |
| | 2045 | \\pub const glClearPFN = PFNGLCLEARPROC; |
| | 2046 | , |
| | 2047 | \\pub inline fn glClearUnion(arg0: GLbitfield) void { |
| | 2048 | \\ return glProcs.gl.Clear.?(arg0); |
| | 2049 | \\} |
| | 2050 | , |
| | 2051 | \\pub const OpenGLProcs = union_OpenGLProcs; |
| | 2052 | }); |
| | 2053 | |
| | 2054 | cases.add("macro pointer cast", |
| | 2055 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) |
| | 2056 | , &[_][]const u8{ |
| | 2057 | \\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); |
| | 2058 | }); |
| | 2059 | |
| 2076 | } | 2060 | } |