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

     1  /* Area:		ffi_call
     2     Purpose:		Test passing struct in variable argument lists.
     3     Limitations:	none.
     4     PR:			none.
     5     Originator:	        ARM Ltd. */
     6  
     7  /* { dg-do run } */
     8  /* { dg-output "" { xfail avr32*-*-* } } */
     9  
    10  #include "ffitest.h"
    11  #include <stdarg.h>
    12  
    13  struct small_tag
    14  {
    15    unsigned char a;
    16    unsigned char b;
    17  };
    18  
    19  struct large_tag
    20  {
    21    unsigned a;
    22    unsigned b;
    23    unsigned c;
    24    unsigned d;
    25    unsigned e;
    26  };
    27  
    28  static int
    29  test_fn (int n, ...)
    30  {
    31    va_list ap;
    32    struct small_tag s1;
    33    struct small_tag s2;
    34    struct large_tag l;
    35    unsigned char uc;
    36    signed char sc;
    37    unsigned short us;
    38    signed short ss;
    39    unsigned int ui;
    40    signed int si;
    41    unsigned long ul;
    42    signed long sl;
    43    float f;
    44    double d;
    45  
    46    va_start (ap, n);
    47    s1 = va_arg (ap, struct small_tag);
    48    l = va_arg (ap, struct large_tag);
    49    s2 = va_arg (ap, struct small_tag);
    50  
    51    uc = va_arg (ap, unsigned);
    52    sc = va_arg (ap, signed);
    53  
    54    us = va_arg (ap, unsigned);
    55    ss = va_arg (ap, signed);
    56  
    57    ui = va_arg (ap, unsigned int);
    58    si = va_arg (ap, signed int);
    59  
    60    ul = va_arg (ap, unsigned long);
    61    sl = va_arg (ap, signed long);
    62  
    63    f = va_arg (ap, double);	/* C standard promotes float->double
    64  				   when anonymous */
    65    d = va_arg (ap, double);
    66  
    67    printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
    68  	  s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
    69  	  s2.a, s2.b,
    70  	  uc, sc,
    71  	  us, ss,
    72  	  ui, si,
    73  	  ul, sl,
    74  	  f, d);
    75    va_end (ap);
    76    return n + 1;
    77  }
    78  
    79  int
    80  main (void)
    81  {
    82    ffi_cif cif;
    83    void* args[15];
    84    ffi_type* arg_types[15];
    85  
    86    ffi_type s_type;
    87    ffi_type *s_type_elements[3];
    88  
    89    ffi_type l_type;
    90    ffi_type *l_type_elements[6];
    91  
    92    struct small_tag s1;
    93    struct small_tag s2;
    94    struct large_tag l1;
    95  
    96    int n;
    97    ffi_arg res;
    98  
    99    unsigned char uc;
   100    signed char sc;
   101    unsigned short us;
   102    signed short ss;
   103    unsigned int ui;
   104    signed int si;
   105    unsigned long ul;
   106    signed long sl;
   107    double d1;
   108    double f1;
   109  
   110    s_type.size = 0;
   111    s_type.alignment = 0;
   112    s_type.type = FFI_TYPE_STRUCT;
   113    s_type.elements = s_type_elements;
   114  
   115    s_type_elements[0] = &ffi_type_uchar;
   116    s_type_elements[1] = &ffi_type_uchar;
   117    s_type_elements[2] = NULL;
   118  
   119    l_type.size = 0;
   120    l_type.alignment = 0;
   121    l_type.type = FFI_TYPE_STRUCT;
   122    l_type.elements = l_type_elements;
   123  
   124    l_type_elements[0] = &ffi_type_uint;
   125    l_type_elements[1] = &ffi_type_uint;
   126    l_type_elements[2] = &ffi_type_uint;
   127    l_type_elements[3] = &ffi_type_uint;
   128    l_type_elements[4] = &ffi_type_uint;
   129    l_type_elements[5] = NULL;
   130  
   131    arg_types[0] = &ffi_type_sint;
   132    arg_types[1] = &s_type;
   133    arg_types[2] = &l_type;
   134    arg_types[3] = &s_type;
   135    arg_types[4] = &ffi_type_uchar;
   136    arg_types[5] = &ffi_type_schar;
   137    arg_types[6] = &ffi_type_ushort;
   138    arg_types[7] = &ffi_type_sshort;
   139    arg_types[8] = &ffi_type_uint;
   140    arg_types[9] = &ffi_type_sint;
   141    arg_types[10] = &ffi_type_ulong;
   142    arg_types[11] = &ffi_type_slong;
   143    arg_types[12] = &ffi_type_double;
   144    arg_types[13] = &ffi_type_double;
   145    arg_types[14] = NULL;
   146  
   147    CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK);
   148  
   149    s1.a = 5;
   150    s1.b = 6;
   151  
   152    l1.a = 10;
   153    l1.b = 11;
   154    l1.c = 12;
   155    l1.d = 13;
   156    l1.e = 14;
   157  
   158    s2.a = 7;
   159    s2.b = 8;
   160  
   161    n = 41;
   162  
   163    uc = 9;
   164    sc = 10;
   165    us = 11;
   166    ss = 12;
   167    ui = 13;
   168    si = 14;
   169    ul = 15;
   170    sl = 16;
   171    f1 = 2.12;
   172    d1 = 3.13;
   173  
   174    args[0] = &n;
   175    args[1] = &s1;
   176    args[2] = &l1;
   177    args[3] = &s2;
   178    args[4] = &uc;
   179    args[5] = &sc;
   180    args[6] = &us;
   181    args[7] = &ss;
   182    args[8] = &ui;
   183    args[9] = &si;
   184    args[10] = &ul;
   185    args[11] = &sl;
   186    args[12] = &f1;
   187    args[13] = &d1;
   188    args[14] = NULL;
   189  
   190    ffi_call(&cif, FFI_FN(test_fn), &res, args);
   191    /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
   192    printf("res: %d\n", (int) res);
   193    /* { dg-output "\nres: 42" } */
   194  
   195    return 0;
   196  }