github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/testsuite/libffi.call/nested_struct2.c (about)

     1  /* Area:	ffi_call, closure_call
     2     Purpose:	Check structure passing with different structure size.
     3  		Contains structs as parameter of the struct itself.
     4  		Sample taken from Alan Modras patch to src/prep_cif.c.
     5     Limitations:	none.
     6     PR:		none.
     7     Originator:	<andreast@gcc.gnu.org> 20030911	 */
     8  
     9  /* { dg-do run } */
    10  #include "ffitest.h"
    11  
    12  typedef struct A {
    13    unsigned long a;
    14    unsigned char b;
    15  } A;
    16  
    17  typedef struct B {
    18    struct A x;
    19    unsigned char y;
    20  } B;
    21  
    22  B B_fn(struct A b0, struct B b1)
    23  {
    24    struct B result;
    25  
    26    result.x.a = b0.a + b1.x.a;
    27    result.x.b = b0.b + b1.x.b + b1.y;
    28    result.y = b0.b + b1.x.b;
    29  
    30    printf("%lu %d %lu %d %d: %lu %d %d\n", b0.a, b0.b, b1.x.a, b1.x.b, b1.y,
    31  	 result.x.a, result.x.b, result.y);
    32  
    33    return result;
    34  }
    35  
    36  static void
    37  B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
    38       void* userdata __UNUSED__)
    39  {
    40    struct A b0;
    41    struct B b1;
    42  
    43    b0 = *(struct A*)(args[0]);
    44    b1 = *(struct B*)(args[1]);
    45  
    46    *(B*)resp = B_fn(b0, b1);
    47  }
    48  
    49  int main (void)
    50  {
    51    ffi_cif cif;
    52    void *code;
    53    ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
    54    void* args_dbl[3];
    55    ffi_type* cls_struct_fields[3];
    56    ffi_type* cls_struct_fields1[3];
    57    ffi_type cls_struct_type, cls_struct_type1;
    58    ffi_type* dbl_arg_types[3];
    59  
    60    struct A e_dbl = { 1, 7};
    61    struct B f_dbl = {{12 , 127}, 99};
    62  
    63    struct B res_dbl;
    64  
    65    cls_struct_type.size = 0;
    66    cls_struct_type.alignment = 0;
    67    cls_struct_type.type = FFI_TYPE_STRUCT;
    68    cls_struct_type.elements = cls_struct_fields;
    69  
    70    cls_struct_type1.size = 0;
    71    cls_struct_type1.alignment = 0;
    72    cls_struct_type1.type = FFI_TYPE_STRUCT;
    73    cls_struct_type1.elements = cls_struct_fields1;
    74  
    75    cls_struct_fields[0] = &ffi_type_ulong;
    76    cls_struct_fields[1] = &ffi_type_uchar;
    77    cls_struct_fields[2] = NULL;
    78  
    79    cls_struct_fields1[0] = &cls_struct_type;
    80    cls_struct_fields1[1] = &ffi_type_uchar;
    81    cls_struct_fields1[2] = NULL;
    82  
    83  
    84    dbl_arg_types[0] = &cls_struct_type;
    85    dbl_arg_types[1] = &cls_struct_type1;
    86    dbl_arg_types[2] = NULL;
    87  
    88    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
    89  		     dbl_arg_types) == FFI_OK);
    90  
    91    args_dbl[0] = &e_dbl;
    92    args_dbl[1] = &f_dbl;
    93    args_dbl[2] = NULL;
    94  
    95    ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
    96    /* { dg-output "1 7 12 127 99: 13 233 134" } */
    97    CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
    98    CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
    99    CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
   100  
   101    CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
   102  
   103    res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
   104    /* { dg-output "\n1 7 12 127 99: 13 233 134" } */
   105    CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
   106    CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
   107    CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
   108  
   109    exit(0);
   110  }