github.com/gotranspile/cxgo@v0.3.8-0.20240118201721-29871598a6a2/c_decl_test.go (about) 1 package cxgo 2 3 import ( 4 "testing" 5 6 "github.com/gotranspile/cxgo/types" 7 ) 8 9 var casesTranslateDecls = []parseCase{ 10 { 11 name: "typedef primitive", 12 src: `typedef int int_t;`, 13 exp: `type int_t int32`, 14 }, 15 { 16 name: "function decl", 17 src: ` 18 void foo() {} 19 `, 20 exp: ` 21 func foo() { 22 } 23 `, 24 }, 25 { 26 name: "function forward decl", 27 src: ` 28 void foo1(); 29 int foo2(); 30 int foo3(int*); 31 int (*a)(); 32 int (*b)(int*); 33 `, 34 exp: ` 35 func foo1() 36 func foo2() int32 37 func foo3(*int32) int32 38 39 var a func() int32 40 var b func(*int32) int32 41 `, 42 }, 43 { 44 name: "function forward decl 2", 45 src: ` 46 void foo1(); 47 int foo2(); 48 int foo3(int); 49 void foo1() {} 50 int foo2() {} 51 int foo3(int) {} 52 `, 53 exp: ` 54 func foo1() { 55 } 56 func foo2() int32 { 57 } 58 func foo3(int32) int32 { 59 } 60 `, 61 }, 62 { 63 name: "var", 64 src: ` 65 int foo; 66 char byte; 67 `, 68 exp: ` 69 var foo int32 70 var byte_ int8 71 `, 72 }, 73 { 74 name: "var init", 75 src: ` 76 int foo = 1; 77 `, 78 exp: ` 79 var foo int32 = 1 80 `, 81 }, 82 { 83 name: "multiple vars", 84 src: ` 85 int foo = 1, *bar; 86 `, 87 exp: ` 88 var foo int32 = 1 89 var bar *int32 90 `, 91 }, 92 { 93 name: "multiple vars 2", 94 src: ` 95 int a = 1, *p, f(void), (*pf)(double); 96 `, 97 exp: ` 98 var a int32 = 1 99 var p *int32 100 101 func f() int32 102 103 var pf func(float64) int32 104 `, 105 }, 106 { 107 name: "complex var", 108 src: ` 109 int (*(*foo)(double))[3] = 0; 110 `, 111 exp: ` 112 var foo func(float64) *[3]int32 = nil 113 `, 114 }, 115 { 116 name: "function var", 117 src: ` 118 void (*foo)(void); 119 `, 120 exp: ` 121 var foo func() 122 `, 123 }, 124 { 125 name: "struct forward decl", 126 src: ` 127 struct foo; 128 struct foo2; 129 130 struct foo { 131 int a; 132 }; 133 `, 134 exp: ` 135 type foo struct { 136 A int32 137 } 138 type foo2 struct { 139 } 140 `, 141 }, 142 { 143 name: "typedef struct", 144 inc: ` 145 typedef struct bar { 146 int d; 147 } BAR; 148 `, 149 src: ` 150 typedef struct { int a; } foo; 151 typedef struct foo2 { int b; } foo2; 152 typedef struct foo3 { int c; } FOO3; 153 struct bar bar1; 154 BAR bar2; 155 `, 156 exp: ` 157 type foo struct { 158 A int32 159 } 160 type foo2 struct { 161 B int32 162 } 163 type foo3 struct { 164 C int32 165 } 166 type FOO3 foo3 167 168 var bar1 bar 169 var bar2 BAR 170 `, 171 }, 172 { 173 name: "typedef struct 3", 174 src: ` 175 struct baz { int d; } bar3; 176 `, 177 exp: ` 178 type baz struct { 179 D int32 180 } 181 182 var bar3 baz 183 `, 184 }, 185 { 186 name: "typedef alias", 187 src: ` 188 typedef struct { int a; } A; 189 typedef A B; 190 typedef B C; 191 192 struct T1 { 193 C (*f1)[3]; 194 C *f2; 195 }; 196 typedef struct T1 T2; 197 198 void foo(C* c) {} 199 `, 200 exp: ` 201 type A struct { 202 A int32 203 } 204 type T1 struct { 205 F1 *[3]A 206 F2 *A 207 } 208 type T2 T1 209 210 func foo(c *A) { 211 } 212 `, 213 configFuncs: []configFunc{ 214 withAlias("B"), 215 withAlias("C"), 216 }, 217 }, 218 { 219 name: "typedef alias 2", 220 inc: ` 221 typedef struct { int a; } A; 222 typedef A B; 223 typedef B C; 224 `, 225 src: ` 226 struct T1 { 227 C (*f1)[3]; 228 C *f2; 229 }; 230 typedef struct T1 T2; 231 232 void foo(C* c) {} 233 `, 234 exp: ` 235 type T1 struct { 236 F1 *[3]A 237 F2 *A 238 } 239 type T2 T1 240 241 func foo(c *A) { 242 } 243 `, 244 configFuncs: []configFunc{ 245 withAlias("B"), 246 withAlias("C"), 247 }, 248 }, 249 { 250 name: "recursive struct", 251 inc: ` 252 typedef struct _A* HA; 253 typedef struct _B* HB; 254 `, 255 src: ` 256 struct _A { 257 HB b; 258 }; 259 struct _B { 260 HA a; 261 }; 262 `, 263 exp: ` 264 type _A struct { 265 B HB 266 } 267 type _B struct { 268 A HA 269 } 270 `, 271 }, 272 { 273 name: "named enum", 274 src: ` 275 enum Enum 276 { 277 VALUE_1, 278 VALUE_2, 279 }; 280 `, 281 exp: ` 282 type Enum int32 283 284 const ( 285 VALUE_1 = Enum(iota) 286 VALUE_2 287 ) 288 `, 289 }, 290 { 291 name: "forward enum", 292 src: ` 293 enum Enum; 294 enum Enum 295 { 296 VALUE_1, 297 VALUE_2, 298 }; 299 `, 300 exp: ` 301 type Enum int32 302 303 const ( 304 VALUE_1 = Enum(iota) 305 VALUE_2 306 ) 307 `, 308 }, 309 { 310 name: "return enum", 311 src: ` 312 enum Enum 313 { 314 VALUE_1, 315 VALUE_2, 316 }; 317 extern enum Enum foo(); 318 `, 319 exp: ` 320 type Enum int32 321 322 const ( 323 VALUE_1 = Enum(iota) 324 VALUE_2 325 ) 326 327 func foo() Enum 328 `, 329 }, 330 { 331 name: "unnamed enum", 332 src: ` 333 enum 334 { 335 VALUE_1, 336 VALUE_2, 337 }; 338 `, 339 exp: ` 340 const ( 341 VALUE_1 = iota 342 VALUE_2 343 ) 344 `, 345 }, 346 { 347 name: "typedef enum", 348 src: ` 349 typedef enum { 350 VALUE_1, 351 VALUE_2, 352 } Enum; 353 `, 354 exp: ` 355 type Enum int32 356 357 const ( 358 VALUE_1 = Enum(iota) 359 VALUE_2 360 ) 361 `, 362 }, 363 { 364 name: "enum zero", 365 src: ` 366 enum Enum 367 { 368 VALUE_1 = 0, 369 VALUE_2, 370 }; 371 `, 372 exp: ` 373 type Enum int32 374 375 const ( 376 VALUE_1 = Enum(iota) 377 VALUE_2 378 ) 379 `, 380 }, 381 { 382 name: "enum start", 383 src: ` 384 enum Enum 385 { 386 VALUE_1 = 1, 387 VALUE_2, 388 }; 389 `, 390 exp: ` 391 type Enum int32 392 393 const ( 394 VALUE_1 = Enum(iota + 1) 395 VALUE_2 396 ) 397 `, 398 }, 399 { 400 name: "enum fixed", 401 src: ` 402 enum Enum 403 { 404 VALUE_1 = 1, 405 VALUE_2 = 2, 406 }; 407 `, 408 exp: ` 409 type Enum int32 410 411 const ( 412 VALUE_1 Enum = 1 413 VALUE_2 Enum = 2 414 ) 415 `, 416 }, 417 { 418 name: "enum no zero", 419 src: ` 420 enum Enum 421 { 422 VALUE_1, 423 VALUE_2 = 1, 424 }; 425 `, 426 exp: ` 427 type Enum int32 428 429 const ( 430 VALUE_1 Enum = 0 431 VALUE_2 Enum = 1 432 ) 433 `, 434 }, 435 { 436 name: "enum no zero 2", 437 src: ` 438 enum Enum 439 { 440 VALUE_1, 441 VALUE_2 = 42, 442 VALUE_3, 443 }; 444 `, 445 exp: ` 446 type Enum int32 447 448 const ( 449 VALUE_1 Enum = 0 450 VALUE_2 Enum = 42 451 VALUE_3 Enum = 43 452 ) 453 `, 454 }, 455 { 456 name: "enum negative", 457 src: ` 458 enum Enum 459 { 460 VALUE_1 = -3, 461 VALUE_2, 462 VALUE_3 = 1, 463 }; 464 `, 465 exp: ` 466 type Enum int32 467 468 const ( 469 VALUE_1 Enum = -3 470 VALUE_2 Enum = -2 471 VALUE_3 Enum = 1 472 ) 473 `, 474 }, 475 { 476 name: "use enum", 477 src: ` 478 enum Enum 479 { 480 VALUE_1, 481 VALUE_2, 482 }; 483 enum Enum foo() { 484 return VALUE_1; 485 } 486 `, 487 exp: ` 488 type Enum int32 489 490 const ( 491 VALUE_1 = Enum(iota) 492 VALUE_2 493 ) 494 495 func foo() Enum { 496 return VALUE_1 497 } 498 `, 499 }, 500 { 501 name: "enum in func", 502 src: ` 503 void foo() { 504 typedef enum { A, B, C } Enum; 505 typedef enum { D, E, F } Enum2; 506 Enum x; 507 } 508 `, 509 exp: ` 510 func foo() { 511 type Enum int32 512 const ( 513 A = Enum(iota) 514 B 515 C 516 ) 517 type Enum2 int32 518 const ( 519 D = Enum2(iota) 520 E 521 F 522 ) 523 var x Enum 524 _ = x 525 } 526 `, 527 }, 528 { 529 name: "struct and func", skip: true, // TODO 530 src: ` 531 struct foo; 532 void foo(); 533 `, 534 exp: ` 535 type foo struct { 536 } 537 538 func foo_2() 539 `, 540 }, 541 { 542 name: "struct and var", 543 inc: ` 544 struct foo {}; 545 `, 546 src: ` 547 struct foo foo; 548 `, 549 exp: ` 550 var foo foo 551 `, 552 }, 553 { 554 name: "func arg", 555 src: ` 556 void foo(int (*a)(void)) { 557 } 558 `, 559 exp: ` 560 func foo(a func() int32) { 561 } 562 `, 563 }, 564 { 565 name: "local func var", 566 src: ` 567 void foo() { 568 int (*a)(); 569 } 570 `, 571 exp: ` 572 func foo() { 573 var a func() int32 574 _ = a 575 } 576 `, 577 }, 578 { 579 name: "for init", 580 src: ` 581 void foo() { 582 for (int i = 0; i < 5; i++) {} 583 } 584 `, 585 exp: ` 586 func foo() { 587 for i := int32(0); i < 5; i++ { 588 } 589 } 590 `, 591 }, 592 { 593 name: "for init multiple", 594 skip: true, // TODO 595 src: ` 596 void foo() { 597 for (int i = 0, j = 1; i < 5; i++) {} 598 } 599 `, 600 exp: ` 601 func foo() { 602 for i, j := int32(0), int32(1); i < 5; i++ { 603 } 604 } 605 `, 606 }, 607 { 608 name: "extern var", 609 src: ` 610 extern int a; 611 `, 612 exp: ` 613 `, 614 }, 615 { 616 name: "use incomplete type", 617 src: ` 618 typedef struct MyType MyType; 619 MyType *new_type(void) { 620 return 0; 621 } 622 `, 623 exp: ` 624 type MyType struct { 625 } 626 627 func new_type() *MyType { 628 return nil 629 } 630 `, 631 }, 632 { 633 name: "unnamed struct var", 634 src: ` 635 void foo() { 636 struct{ 637 int field; 638 } a = {0}; 639 struct{ 640 int field; 641 int field2; 642 } b = {0}; 643 } 644 `, 645 exp: ` 646 func foo() { 647 var a struct { 648 Field int32 649 } = struct { 650 Field int32 651 }{} 652 _ = a 653 var b struct { 654 Field int32 655 Field2 int32 656 } = struct { 657 Field int32 658 Field2 int32 659 }{} 660 _ = b 661 } 662 `, 663 }, 664 { 665 name: "empty array decl", 666 src: ` 667 void foo() { 668 int a[1][0]; 669 } 670 `, 671 exp: ` 672 func foo() { 673 var a [1][0]int32 674 _ = a 675 } 676 `, 677 }, 678 { 679 name: "dyn array arg", 680 src: ` 681 void foo(int a[]) { 682 } 683 `, 684 exp: ` 685 func foo(a []int32) { 686 } 687 `, 688 }, 689 { 690 name: "rename decl func", 691 src: ` 692 void foo() {} 693 `, 694 exp: ` 695 func Bar() { 696 } 697 `, 698 configFuncs: []configFunc{ 699 withRename("foo", "Bar"), 700 }, 701 }, 702 { 703 name: "rename decl struct", 704 src: ` 705 struct foo {}; 706 `, 707 exp: ` 708 type Bar struct { 709 } 710 `, 711 configFuncs: []configFunc{ 712 withRename("foo", "Bar"), 713 }, 714 }, 715 { 716 name: "args partially named", 717 src: ` 718 void (*foo)(void *a, int, const char *); 719 `, 720 exp: ` 721 var foo func(a unsafe.Pointer, a2 int32, a3 *byte) 722 `, 723 }, 724 { 725 name: "go ints", 726 src: ` 727 typedef unsigned int word; 728 `, 729 exp: ` 730 type word uint 731 `, 732 envFuncs: []envFunc{ 733 func(c *types.Config) { 734 c.UseGoInt = true 735 }, 736 }, 737 }, 738 { 739 name: "unused vars", 740 src: ` 741 void foo(int x) { 742 int a; 743 } 744 745 void bar() { 746 int a = 0; 747 int b; 748 int c = b; 749 } 750 `, 751 exp: ` 752 func foo(x int32) { 753 var a int32 754 _ = a 755 } 756 func bar() { 757 var a int32 = 0 758 _ = a 759 var b int32 760 var c int32 = b 761 _ = c 762 } 763 `, 764 }, 765 { 766 name: "tcc 10", 767 src: ` 768 struct z 769 { 770 int a; 771 } foo; 772 `, 773 exp: ` 774 type z struct { 775 A int32 776 } 777 778 var foo z 779 `, 780 }, 781 { 782 name: "stdlib forward decl", 783 src: ` 784 int printf(const char*, ...); 785 786 void foo() { 787 printf("%d\n", 1); 788 } 789 `, 790 exp: ` 791 func foo() { 792 stdio.Printf("%d\n", 1) 793 } 794 `, 795 }, 796 { 797 name: "macro empty", 798 src: ` 799 #define MY_DEF 800 801 int a; 802 `, 803 exp: ` 804 var a int32 805 `, 806 }, 807 { 808 name: "macro untyped int", 809 src: ` 810 #define MY_CONST 1 811 812 int a = MY_CONST; 813 `, 814 exp: ` 815 const MY_CONST = 1 816 817 var a int32 = MY_CONST 818 `, 819 }, 820 { 821 // TODO: cc.AST.Eval() doesn't support cast expressions? 822 skip: true, 823 name: "macro typed int", 824 src: ` 825 #define MY_CONST ((int)1) 826 827 int a = MY_CONST; 828 `, 829 exp: ` 830 const MY_CONST = int32(1) 831 832 var a int32 = MY_CONST 833 `, 834 }, 835 { 836 name: "macro string", 837 src: ` 838 #define MY_CONST "abc" 839 840 char* a = MY_CONST; 841 `, 842 exp: ` 843 const MY_CONST = "abc" 844 845 var a *byte = libc.CString(MY_CONST) 846 `, 847 }, 848 { 849 name: "macro order", 850 src: ` 851 #define MY_CONST 1 852 853 int a = MY_CONST; 854 855 #define MY_CONST_2 2 856 `, 857 exp: ` 858 const MY_CONST = 1 859 860 var a int32 = MY_CONST 861 862 const MY_CONST_2 = 2 863 `, 864 // TODO: we don't handle order yet 865 skipExp: ` 866 const MY_CONST = 1 867 const MY_CONST_2 = 2 868 869 var a int32 = MY_CONST 870 `, 871 }, 872 } 873 874 func TestDecls(t *testing.T) { 875 runTestTranslate(t, casesTranslateDecls) 876 }