github.com/gotranspile/cxgo@v0.3.7/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: "rename decl func", 680 src: ` 681 void foo() {} 682 `, 683 exp: ` 684 func Bar() { 685 } 686 `, 687 configFuncs: []configFunc{ 688 withRename("foo", "Bar"), 689 }, 690 }, 691 { 692 name: "rename decl struct", 693 src: ` 694 struct foo {}; 695 `, 696 exp: ` 697 type Bar struct { 698 } 699 `, 700 configFuncs: []configFunc{ 701 withRename("foo", "Bar"), 702 }, 703 }, 704 { 705 name: "args partially named", 706 src: ` 707 void (*foo)(void *a, int, const char *); 708 `, 709 exp: ` 710 var foo func(a unsafe.Pointer, a2 int32, a3 *byte) 711 `, 712 }, 713 { 714 name: "go ints", 715 src: ` 716 typedef unsigned int word; 717 `, 718 exp: ` 719 type word uint 720 `, 721 envFuncs: []envFunc{ 722 func(c *types.Config) { 723 c.UseGoInt = true 724 }, 725 }, 726 }, 727 { 728 name: "unused vars", 729 src: ` 730 void foo(int x) { 731 int a; 732 } 733 734 void bar() { 735 int a = 0; 736 int b; 737 int c = b; 738 } 739 `, 740 exp: ` 741 func foo(x int32) { 742 var a int32 743 _ = a 744 } 745 func bar() { 746 var a int32 = 0 747 _ = a 748 var b int32 749 var c int32 = b 750 _ = c 751 } 752 `, 753 }, 754 { 755 name: "tcc 10", 756 src: ` 757 struct z 758 { 759 int a; 760 } foo; 761 `, 762 exp: ` 763 type z struct { 764 A int32 765 } 766 767 var foo z 768 `, 769 }, 770 { 771 name: "stdlib forward decl", 772 src: ` 773 int printf(const char*, ...); 774 775 void foo() { 776 printf("%d\n", 1); 777 } 778 `, 779 exp: ` 780 func foo() { 781 stdio.Printf("%d\n", 1) 782 } 783 `, 784 }, 785 { 786 name: "macro empty", 787 src: ` 788 #define MY_DEF 789 790 int a; 791 `, 792 exp: ` 793 var a int32 794 `, 795 }, 796 { 797 name: "macro untyped int", 798 src: ` 799 #define MY_CONST 1 800 801 int a = MY_CONST; 802 `, 803 exp: ` 804 const MY_CONST = 1 805 806 var a int32 = MY_CONST 807 `, 808 }, 809 { 810 // TODO: cc.AST.Eval() doesn't support cast expressions? 811 skip: true, 812 name: "macro typed int", 813 src: ` 814 #define MY_CONST ((int)1) 815 816 int a = MY_CONST; 817 `, 818 exp: ` 819 const MY_CONST = int32(1) 820 821 var a int32 = MY_CONST 822 `, 823 }, 824 { 825 name: "macro string", 826 src: ` 827 #define MY_CONST "abc" 828 829 char* a = MY_CONST; 830 `, 831 exp: ` 832 const MY_CONST = "abc" 833 834 var a *byte = libc.CString(MY_CONST) 835 `, 836 }, 837 { 838 name: "macro order", 839 src: ` 840 #define MY_CONST 1 841 842 int a = MY_CONST; 843 844 #define MY_CONST_2 2 845 `, 846 exp: ` 847 const MY_CONST = 1 848 849 var a int32 = MY_CONST 850 851 const MY_CONST_2 = 2 852 `, 853 // TODO: we don't handle order yet 854 skipExp: ` 855 const MY_CONST = 1 856 const MY_CONST_2 = 2 857 858 var a int32 = MY_CONST 859 `, 860 }, 861 } 862 863 func TestDecls(t *testing.T) { 864 runTestTranslate(t, casesTranslateDecls) 865 }