| ... | ... | @@ -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 | 429 | /////////////// Cases that pass for only stage2 //////////////// |
| 166 | 430 | |
| 167 | 431 | cases.add_2("Parameterless function prototypes", |
| ... | ... | @@ -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 | 469 | cases.add_2("enums", |
| 222 | 470 | \\typedef enum { |
| 223 | 471 | \\ a, |
| ... | ... | @@ -408,54 +656,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 408 | 656 | , &[_][]const u8{ |
| 409 | 657 | \\pub inline fn BASIC(c: var) @TypeOf(c * 2) { |
| 410 | 658 | \\ return c * 2; |
| 411 | | \\} |
| 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 | | \\}; |
| 659 | \\} |
| 437 | 660 | }); |
| 438 | 661 | |
| 439 | | cases.add_both("pointer to struct demoted to opaque due to bit fields", |
| 440 | | \\struct Foo { |
| 441 | | \\ unsigned int: 1; |
| 442 | | \\}; |
| 443 | | \\struct Bar { |
| 444 | | \\ struct Foo *foo; |
| 445 | | \\}; |
| 662 | cases.add_2("macro escape sequences", |
| 663 | \\#define FOO "aoeu\xab derp" |
| 664 | \\#define FOO2 "aoeu\a derp" |
| 446 | 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 { |
| 450 | | \\ foo: ?*struct_Foo, |
| 451 | | \\}; |
| 668 | \\pub const FOO2 = "aoeu\x07 derp"; |
| 452 | 669 | }); |
| 453 | 670 | |
| 454 | | cases.add_both("macro with left shift", |
| 455 | | \\#define REDISMODULE_READ (1<<0) |
| 456 | | , &[_][]const u8{ |
| 457 | | \\pub const REDISMODULE_READ = 1 << 0; |
| 458 | | }); |
| 671 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| 459 | 672 | |
| 460 | 673 | if (builtin.os != builtin.Os.windows) { |
| 461 | 674 | // Windows treats this as an enum with type c_int |
| ... | ... | @@ -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 | 810 | cases.addAllowWarnings("simple data types", |
| 623 | 811 | \\#include <stdint.h> |
| 624 | 812 | \\int foo(char a, unsigned char b, signed char c); |
| ... | ... | @@ -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 | 834 | cases.add("restrict -> noalias", |
| 691 | 835 | \\void foo(void *restrict bar, void *restrict); |
| 692 | 836 | , &[_][]const u8{ |
| 693 | 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 | 840 | cases.add("qualified struct and enum", |
| 711 | 841 | \\struct Foo { |
| 712 | 842 | \\ int x; |
| ... | ... | @@ -731,174 +861,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 731 | 861 | \\pub const BarA = enum_Bar.A; |
| 732 | 862 | , |
| 733 | 863 | \\pub const BarB = enum_Bar.B; |
| 734 | | , |
| 735 | | \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void; |
| 736 | | , |
| 737 | | \\pub const Foo = struct_Foo; |
| 738 | | , |
| 739 | | \\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); |
| 864 | , |
| 865 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void; |
| 866 | , |
| 867 | \\pub const Foo = struct_Foo; |
| 868 | , |
| 869 | \\pub const Bar = enum_Bar; |
| 884 | 870 | }); |
| 885 | 871 | |
| 886 | | cases.add("llu integer suffix after hex literal", |
| 887 | | \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 872 | cases.add("constant size array", |
| 873 | \\void func(int array[20]); |
| 888 | 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", |
| 893 | | \\struct comptime { |
| 894 | | \\ int defer; |
| 895 | | \\}; |
| 878 | cases.add("__cdecl doesn't mess up function pointers", |
| 879 | \\void foo(void (__cdecl *fn_ptr)(void)); |
| 896 | 880 | , &[_][]const u8{ |
| 897 | | \\pub const struct_comptime = extern struct { |
| 898 | | \\ @"defer": c_int, |
| 899 | | \\}; |
| 900 | | , |
| 901 | | \\pub const @"comptime" = struct_comptime; |
| 881 | \\pub extern fn foo(fn_ptr: ?extern fn () void) void; |
| 902 | 882 | }); |
| 903 | 883 | |
| 904 | 884 | cases.add("macro defines string literal with hex", |
| ... | ... | @@ -925,12 +905,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 925 | 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 | 908 | cases.addC("post increment", |
| 935 | 909 | \\unsigned foo1(unsigned a) { |
| 936 | 910 | \\ a++; |
| ... | ... | @@ -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 | 1635 | cases.add("variable name shadowing", |
| 1700 | 1636 | \\int foo(void) { |
| 1701 | 1637 | \\ int x = 1; |
| ... | ... | @@ -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 | 1701 | cases.add("if on non-bool", |
| 1772 | 1702 | \\enum SomeEnum { A, B, C }; |
| 1773 | 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 | 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 | 1802 | cases.addC("implicit casts", |
| 1937 | 1803 | \\#include <stdbool.h> |
| 1938 | 1804 | \\ |
| ... | ... | @@ -2073,4 +1939,122 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2073 | 1939 | \\pub export fn foo() void {} |
| 2074 | 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 | } |