12d2a3ad8SAndrii Nakryiko // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
22d2a3ad8SAndrii Nakryiko
32d2a3ad8SAndrii Nakryiko /*
42d2a3ad8SAndrii Nakryiko * BTF-to-C dumper test for majority of C syntax quirks.
52d2a3ad8SAndrii Nakryiko *
62d2a3ad8SAndrii Nakryiko * Copyright (c) 2019 Facebook
72d2a3ad8SAndrii Nakryiko */
82d2a3ad8SAndrii Nakryiko /* ----- START-EXPECTED-OUTPUT ----- */
92d2a3ad8SAndrii Nakryiko enum e1 {
102d2a3ad8SAndrii Nakryiko A = 0,
112d2a3ad8SAndrii Nakryiko B = 1,
122d2a3ad8SAndrii Nakryiko };
132d2a3ad8SAndrii Nakryiko
142d2a3ad8SAndrii Nakryiko enum e2 {
152d2a3ad8SAndrii Nakryiko C = 100,
167cb30aaaSAndrii Nakryiko D = 4294967295,
172d2a3ad8SAndrii Nakryiko E = 0,
182d2a3ad8SAndrii Nakryiko };
192d2a3ad8SAndrii Nakryiko
202d2a3ad8SAndrii Nakryiko typedef enum e2 e2_t;
212d2a3ad8SAndrii Nakryiko
222d2a3ad8SAndrii Nakryiko typedef enum {
232d2a3ad8SAndrii Nakryiko F = 0,
242d2a3ad8SAndrii Nakryiko G = 1,
252d2a3ad8SAndrii Nakryiko H = 2,
262d2a3ad8SAndrii Nakryiko } e3_t;
272d2a3ad8SAndrii Nakryiko
289d234974SAndrii Nakryiko /* ----- START-EXPECTED-OUTPUT ----- */
299d234974SAndrii Nakryiko /*
309d234974SAndrii Nakryiko *enum e_byte {
319d234974SAndrii Nakryiko * EBYTE_1 = 0,
329d234974SAndrii Nakryiko * EBYTE_2 = 1,
339d234974SAndrii Nakryiko *} __attribute__((mode(byte)));
349d234974SAndrii Nakryiko *
359d234974SAndrii Nakryiko */
369d234974SAndrii Nakryiko /* ----- END-EXPECTED-OUTPUT ----- */
379d234974SAndrii Nakryiko enum e_byte {
389d234974SAndrii Nakryiko EBYTE_1,
399d234974SAndrii Nakryiko EBYTE_2,
409d234974SAndrii Nakryiko } __attribute__((mode(byte)));
419d234974SAndrii Nakryiko
429d234974SAndrii Nakryiko /* ----- START-EXPECTED-OUTPUT ----- */
439d234974SAndrii Nakryiko /*
449d234974SAndrii Nakryiko *enum e_word {
459d234974SAndrii Nakryiko * EWORD_1 = 0LL,
469d234974SAndrii Nakryiko * EWORD_2 = 1LL,
479d234974SAndrii Nakryiko *} __attribute__((mode(word)));
489d234974SAndrii Nakryiko *
499d234974SAndrii Nakryiko */
509d234974SAndrii Nakryiko /* ----- END-EXPECTED-OUTPUT ----- */
519d234974SAndrii Nakryiko enum e_word {
529d234974SAndrii Nakryiko EWORD_1,
539d234974SAndrii Nakryiko EWORD_2,
549d234974SAndrii Nakryiko } __attribute__((mode(word))); /* force to use 8-byte backing for this enum */
559d234974SAndrii Nakryiko
569d234974SAndrii Nakryiko /* ----- START-EXPECTED-OUTPUT ----- */
579d234974SAndrii Nakryiko enum e_big {
589d234974SAndrii Nakryiko EBIG_1 = 1000000000000ULL,
599d234974SAndrii Nakryiko };
609d234974SAndrii Nakryiko
612d2a3ad8SAndrii Nakryiko typedef int int_t;
622d2a3ad8SAndrii Nakryiko
632d2a3ad8SAndrii Nakryiko typedef volatile const int * volatile const crazy_ptr_t;
642d2a3ad8SAndrii Nakryiko
652d2a3ad8SAndrii Nakryiko typedef int *****we_need_to_go_deeper_ptr_t;
662d2a3ad8SAndrii Nakryiko
672d2a3ad8SAndrii Nakryiko typedef volatile const we_need_to_go_deeper_ptr_t * restrict * volatile * const * restrict volatile * restrict const * volatile const * restrict volatile const how_about_this_ptr_t;
682d2a3ad8SAndrii Nakryiko
692d2a3ad8SAndrii Nakryiko typedef int *ptr_arr_t[10];
702d2a3ad8SAndrii Nakryiko
712d2a3ad8SAndrii Nakryiko typedef void (*fn_ptr1_t)(int);
722d2a3ad8SAndrii Nakryiko
732d2a3ad8SAndrii Nakryiko typedef void (*printf_fn_t)(const char *, ...);
742d2a3ad8SAndrii Nakryiko
752d2a3ad8SAndrii Nakryiko /* ------ END-EXPECTED-OUTPUT ------ */
762d2a3ad8SAndrii Nakryiko /*
772d2a3ad8SAndrii Nakryiko * While previous function pointers are pretty trivial (C-syntax-level
782d2a3ad8SAndrii Nakryiko * trivial), the following are deciphered here for future generations:
792d2a3ad8SAndrii Nakryiko *
802d2a3ad8SAndrii Nakryiko * - `fn_ptr2_t`: function, taking anonymous struct as a first arg and pointer
812d2a3ad8SAndrii Nakryiko * to a function, that takes int and returns int, as a second arg; returning
822d2a3ad8SAndrii Nakryiko * a pointer to a const pointer to a char. Equivalent to:
832d2a3ad8SAndrii Nakryiko * typedef struct { int a; } s_t;
842d2a3ad8SAndrii Nakryiko * typedef int (*fn_t)(int);
852d2a3ad8SAndrii Nakryiko * typedef char * const * (*fn_ptr2_t)(s_t, fn_t);
862d2a3ad8SAndrii Nakryiko *
87*df71a42cSTaichi Nishimura * - `fn_complex_t`: pointer to a function returning struct and accepting
882d2a3ad8SAndrii Nakryiko * union and struct. All structs and enum are anonymous and defined inline.
892d2a3ad8SAndrii Nakryiko *
902d2a3ad8SAndrii Nakryiko * - `signal_t: pointer to a function accepting a pointer to a function as an
912d2a3ad8SAndrii Nakryiko * argument and returning pointer to a function as a result. Sane equivalent:
922d2a3ad8SAndrii Nakryiko * typedef void (*signal_handler_t)(int);
932d2a3ad8SAndrii Nakryiko * typedef signal_handler_t (*signal_ptr_t)(int, signal_handler_t);
942d2a3ad8SAndrii Nakryiko *
952d2a3ad8SAndrii Nakryiko * - fn_ptr_arr1_t: array of pointers to a function accepting pointer to
962d2a3ad8SAndrii Nakryiko * a pointer to an int and returning pointer to a char. Easy.
972d2a3ad8SAndrii Nakryiko *
982d2a3ad8SAndrii Nakryiko * - fn_ptr_arr2_t: array of const pointers to a function taking no arguments
992d2a3ad8SAndrii Nakryiko * and returning a const pointer to a function, that takes pointer to a
1002d2a3ad8SAndrii Nakryiko * `int -> char *` function and returns pointer to a char. Equivalent:
1012d2a3ad8SAndrii Nakryiko * typedef char * (*fn_input_t)(int);
1022d2a3ad8SAndrii Nakryiko * typedef char * (*fn_output_outer_t)(fn_input_t);
1032d2a3ad8SAndrii Nakryiko * typedef const fn_output_outer_t (* fn_output_inner_t)();
1042d2a3ad8SAndrii Nakryiko * typedef const fn_output_inner_t fn_ptr_arr2_t[5];
1052d2a3ad8SAndrii Nakryiko */
1062d2a3ad8SAndrii Nakryiko /* ----- START-EXPECTED-OUTPUT ----- */
1072d2a3ad8SAndrii Nakryiko typedef char * const * (*fn_ptr2_t)(struct {
1082d2a3ad8SAndrii Nakryiko int a;
1092d2a3ad8SAndrii Nakryiko }, int (*)(int));
1102d2a3ad8SAndrii Nakryiko
1112d2a3ad8SAndrii Nakryiko typedef struct {
1122d2a3ad8SAndrii Nakryiko int a;
1132d2a3ad8SAndrii Nakryiko void (*b)(int, struct {
1142d2a3ad8SAndrii Nakryiko int c;
1152d2a3ad8SAndrii Nakryiko }, union {
1162d2a3ad8SAndrii Nakryiko char d;
1172d2a3ad8SAndrii Nakryiko int e[5];
1182d2a3ad8SAndrii Nakryiko });
1192d2a3ad8SAndrii Nakryiko } (*fn_complex_t)(union {
1202d2a3ad8SAndrii Nakryiko void *f;
1212d2a3ad8SAndrii Nakryiko char g[16];
1222d2a3ad8SAndrii Nakryiko }, struct {
1232d2a3ad8SAndrii Nakryiko int h;
1242d2a3ad8SAndrii Nakryiko });
1252d2a3ad8SAndrii Nakryiko
1262d2a3ad8SAndrii Nakryiko typedef void (* (*signal_t)(int, void (*)(int)))(int);
1272d2a3ad8SAndrii Nakryiko
1282d2a3ad8SAndrii Nakryiko typedef char * (*fn_ptr_arr1_t[10])(int **);
1292d2a3ad8SAndrii Nakryiko
1304050764cSYonghong Song typedef char * (* (* const fn_ptr_arr2_t[5])())(char * (*)(int));
1312d2a3ad8SAndrii Nakryiko
1322d2a3ad8SAndrii Nakryiko struct struct_w_typedefs {
1332d2a3ad8SAndrii Nakryiko int_t a;
1342d2a3ad8SAndrii Nakryiko crazy_ptr_t b;
1352d2a3ad8SAndrii Nakryiko we_need_to_go_deeper_ptr_t c;
1362d2a3ad8SAndrii Nakryiko how_about_this_ptr_t d;
1372d2a3ad8SAndrii Nakryiko ptr_arr_t e;
1382d2a3ad8SAndrii Nakryiko fn_ptr1_t f;
1392d2a3ad8SAndrii Nakryiko printf_fn_t g;
1402d2a3ad8SAndrii Nakryiko fn_ptr2_t h;
1412d2a3ad8SAndrii Nakryiko fn_complex_t i;
1422d2a3ad8SAndrii Nakryiko signal_t j;
1432d2a3ad8SAndrii Nakryiko fn_ptr_arr1_t k;
1442d2a3ad8SAndrii Nakryiko fn_ptr_arr2_t l;
1452d2a3ad8SAndrii Nakryiko };
1462d2a3ad8SAndrii Nakryiko
1472d2a3ad8SAndrii Nakryiko typedef struct {
1482d2a3ad8SAndrii Nakryiko int x;
1492d2a3ad8SAndrii Nakryiko int y;
1502d2a3ad8SAndrii Nakryiko int z;
1512d2a3ad8SAndrii Nakryiko } anon_struct_t;
1522d2a3ad8SAndrii Nakryiko
1532d2a3ad8SAndrii Nakryiko struct struct_fwd;
1542d2a3ad8SAndrii Nakryiko
1552d2a3ad8SAndrii Nakryiko typedef struct struct_fwd struct_fwd_t;
1562d2a3ad8SAndrii Nakryiko
1572d2a3ad8SAndrii Nakryiko typedef struct struct_fwd *struct_fwd_ptr_t;
1582d2a3ad8SAndrii Nakryiko
1592d2a3ad8SAndrii Nakryiko union union_fwd;
1602d2a3ad8SAndrii Nakryiko
1612d2a3ad8SAndrii Nakryiko typedef union union_fwd union_fwd_t;
1622d2a3ad8SAndrii Nakryiko
1632d2a3ad8SAndrii Nakryiko typedef union union_fwd *union_fwd_ptr_t;
1642d2a3ad8SAndrii Nakryiko
1652d2a3ad8SAndrii Nakryiko struct struct_empty {};
1662d2a3ad8SAndrii Nakryiko
1672d2a3ad8SAndrii Nakryiko struct struct_simple {
1682d2a3ad8SAndrii Nakryiko int a;
1692d2a3ad8SAndrii Nakryiko char b;
1702d2a3ad8SAndrii Nakryiko const int_t *p;
1712d2a3ad8SAndrii Nakryiko struct struct_empty s;
1722d2a3ad8SAndrii Nakryiko enum e2 e;
1732d2a3ad8SAndrii Nakryiko enum {
1742d2a3ad8SAndrii Nakryiko ANON_VAL1 = 1,
1752d2a3ad8SAndrii Nakryiko ANON_VAL2 = 2,
1762d2a3ad8SAndrii Nakryiko } f;
1772d2a3ad8SAndrii Nakryiko int arr1[13];
1782d2a3ad8SAndrii Nakryiko enum e2 arr2[5];
1792d2a3ad8SAndrii Nakryiko };
1802d2a3ad8SAndrii Nakryiko
1812d2a3ad8SAndrii Nakryiko union union_empty {};
1822d2a3ad8SAndrii Nakryiko
1832d2a3ad8SAndrii Nakryiko union union_simple {
1842d2a3ad8SAndrii Nakryiko void *ptr;
1852d2a3ad8SAndrii Nakryiko int num;
1862d2a3ad8SAndrii Nakryiko int_t num2;
1872d2a3ad8SAndrii Nakryiko union union_empty u;
1882d2a3ad8SAndrii Nakryiko };
1892d2a3ad8SAndrii Nakryiko
1902d2a3ad8SAndrii Nakryiko struct struct_in_struct {
1912d2a3ad8SAndrii Nakryiko struct struct_simple simple;
1922d2a3ad8SAndrii Nakryiko union union_simple also_simple;
1932d2a3ad8SAndrii Nakryiko struct {
1942d2a3ad8SAndrii Nakryiko int a;
1952d2a3ad8SAndrii Nakryiko } not_so_hard_as_well;
1962d2a3ad8SAndrii Nakryiko union {
1972d2a3ad8SAndrii Nakryiko int b;
1982d2a3ad8SAndrii Nakryiko int c;
1992d2a3ad8SAndrii Nakryiko } anon_union_is_good;
2002d2a3ad8SAndrii Nakryiko struct {
2012d2a3ad8SAndrii Nakryiko int d;
2022d2a3ad8SAndrii Nakryiko int e;
2032d2a3ad8SAndrii Nakryiko };
2042d2a3ad8SAndrii Nakryiko union {
2052d2a3ad8SAndrii Nakryiko int f;
2062d2a3ad8SAndrii Nakryiko int g;
2072d2a3ad8SAndrii Nakryiko };
2082d2a3ad8SAndrii Nakryiko };
2092d2a3ad8SAndrii Nakryiko
210f118aac6SJean-Philippe Brucker struct struct_in_array {};
211f118aac6SJean-Philippe Brucker
212f118aac6SJean-Philippe Brucker struct struct_in_array_typed {};
213f118aac6SJean-Philippe Brucker
214f118aac6SJean-Philippe Brucker typedef struct struct_in_array_typed struct_in_array_t[2];
215f118aac6SJean-Philippe Brucker
2162d2a3ad8SAndrii Nakryiko struct struct_with_embedded_stuff {
2172d2a3ad8SAndrii Nakryiko int a;
2182d2a3ad8SAndrii Nakryiko struct {
2192d2a3ad8SAndrii Nakryiko int b;
2202d2a3ad8SAndrii Nakryiko struct {
2212d2a3ad8SAndrii Nakryiko struct struct_with_embedded_stuff *c;
2222d2a3ad8SAndrii Nakryiko const char *d;
2232d2a3ad8SAndrii Nakryiko } e;
2242d2a3ad8SAndrii Nakryiko union {
2257e3cbd34SYucong Sun volatile long f;
2262d2a3ad8SAndrii Nakryiko void * restrict g;
2272d2a3ad8SAndrii Nakryiko };
2282d2a3ad8SAndrii Nakryiko };
2292d2a3ad8SAndrii Nakryiko union {
2302d2a3ad8SAndrii Nakryiko const int_t *h;
2312d2a3ad8SAndrii Nakryiko void (*i)(char, int, void *);
2322d2a3ad8SAndrii Nakryiko } j;
2332d2a3ad8SAndrii Nakryiko enum {
2342d2a3ad8SAndrii Nakryiko K = 100,
2352d2a3ad8SAndrii Nakryiko L = 200,
2362d2a3ad8SAndrii Nakryiko } m;
2372d2a3ad8SAndrii Nakryiko char n[16];
2382d2a3ad8SAndrii Nakryiko struct {
2392d2a3ad8SAndrii Nakryiko char o;
2402d2a3ad8SAndrii Nakryiko int p;
2412d2a3ad8SAndrii Nakryiko void (*q)(int);
2422d2a3ad8SAndrii Nakryiko } r[5];
2432d2a3ad8SAndrii Nakryiko struct struct_in_struct s[10];
2442d2a3ad8SAndrii Nakryiko int t[11];
245f118aac6SJean-Philippe Brucker struct struct_in_array (*u)[2];
246f118aac6SJean-Philippe Brucker struct_in_array_t *v;
2472d2a3ad8SAndrii Nakryiko };
2482d2a3ad8SAndrii Nakryiko
249ccb0e23cSIlya Leoshkevich struct float_struct {
250ccb0e23cSIlya Leoshkevich float f;
251ccb0e23cSIlya Leoshkevich const double *d;
252ccb0e23cSIlya Leoshkevich volatile long double *ld;
253ccb0e23cSIlya Leoshkevich };
254ccb0e23cSIlya Leoshkevich
2552d2a3ad8SAndrii Nakryiko struct root_struct {
2562d2a3ad8SAndrii Nakryiko enum e1 _1;
2572d2a3ad8SAndrii Nakryiko enum e2 _2;
2582d2a3ad8SAndrii Nakryiko e2_t _2_1;
2592d2a3ad8SAndrii Nakryiko e3_t _2_2;
2609d234974SAndrii Nakryiko enum e_byte _100;
2619d234974SAndrii Nakryiko enum e_word _101;
2629d234974SAndrii Nakryiko enum e_big _102;
2632d2a3ad8SAndrii Nakryiko struct struct_w_typedefs _3;
2642d2a3ad8SAndrii Nakryiko anon_struct_t _7;
2652d2a3ad8SAndrii Nakryiko struct struct_fwd *_8;
2662d2a3ad8SAndrii Nakryiko struct_fwd_t *_9;
2672d2a3ad8SAndrii Nakryiko struct_fwd_ptr_t _10;
2682d2a3ad8SAndrii Nakryiko union union_fwd *_11;
2692d2a3ad8SAndrii Nakryiko union_fwd_t *_12;
2702d2a3ad8SAndrii Nakryiko union_fwd_ptr_t _13;
2712d2a3ad8SAndrii Nakryiko struct struct_with_embedded_stuff _14;
272ccb0e23cSIlya Leoshkevich struct float_struct _15;
2732d2a3ad8SAndrii Nakryiko };
2742d2a3ad8SAndrii Nakryiko
2752d2a3ad8SAndrii Nakryiko /* ------ END-EXPECTED-OUTPUT ------ */
2762d2a3ad8SAndrii Nakryiko
f(struct root_struct * s)2772d2a3ad8SAndrii Nakryiko int f(struct root_struct *s)
2782d2a3ad8SAndrii Nakryiko {
2792d2a3ad8SAndrii Nakryiko return 0;
2802d2a3ad8SAndrii Nakryiko }
281