1  #include <stdlib.h>
       2  #include <stdio.h>
       3  
       4  #include "libgccjit.h"
       5  
       6  #include "harness.h"
       7  
       8  struct bar
       9  {
      10    int x;
      11    int y;
      12  };
      13  
      14  void
      15  create_code (gcc_jit_context *ctxt, void *user_data)
      16  {
      17    /* Let's try to inject the equivalent of:
      18  
      19       int
      20       test_reading (const struct bar *f)
      21       {
      22         return f->x * f->y;
      23       }
      24  
      25       int
      26       test_writing ()
      27       {
      28         struct bar tmp;
      29         tmp.x = 5;
      30         tmp.y = 7;
      31         return test_reading (&tmp);
      32       }
      33    */
      34    gcc_jit_type *int_type =
      35      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
      36    gcc_jit_field *x =
      37      gcc_jit_context_new_field (ctxt,
      38                                 NULL,
      39                                 int_type,
      40                                 "x");
      41    gcc_jit_field *y =
      42      gcc_jit_context_new_field (ctxt,
      43                                 NULL,
      44                                 int_type,
      45                                 "y");
      46    gcc_jit_field *fields[] = {x, y};
      47    gcc_jit_type *struct_type =
      48      gcc_jit_struct_as_type (
      49        gcc_jit_context_new_struct_type (ctxt, NULL, "bar", 2, fields));
      50    gcc_jit_type *const_struct_type = gcc_jit_type_get_const (struct_type);
      51    gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (const_struct_type);
      52  
      53    /* Build "test_reading".  */
      54    gcc_jit_param *param_f =
      55      gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
      56    gcc_jit_function *fn_test_reading =
      57      gcc_jit_context_new_function (ctxt, NULL,
      58                                    GCC_JIT_FUNCTION_EXPORTED,
      59                                    int_type,
      60                                    "test_reading",
      61                                    1, ¶m_f,
      62                                    0);
      63  
      64    /* return f->x * f->y; */
      65    gcc_jit_block *reading_block = gcc_jit_function_new_block (fn_test_reading, NULL);
      66    gcc_jit_block_end_with_return (
      67      reading_block,
      68      NULL,
      69      gcc_jit_context_new_binary_op (
      70        ctxt, NULL,
      71        GCC_JIT_BINARY_OP_MULT,
      72        int_type,
      73        gcc_jit_lvalue_as_rvalue (
      74  	gcc_jit_rvalue_dereference_field (
      75  	  gcc_jit_param_as_rvalue (param_f),
      76  	  NULL,
      77  	  x)),
      78        gcc_jit_lvalue_as_rvalue (
      79  	gcc_jit_rvalue_dereference_field (
      80  	gcc_jit_param_as_rvalue (param_f),
      81  	NULL,
      82  	y))));
      83  
      84    /* Build "test_writing".  */
      85    gcc_jit_function *fn_test_writing =
      86      gcc_jit_context_new_function (ctxt, NULL,
      87                                    GCC_JIT_FUNCTION_EXPORTED,
      88                                    int_type,
      89                                    "test_writing",
      90                                    0, NULL,
      91                                    0);
      92  
      93    /* struct bar tmp; */
      94    gcc_jit_lvalue *local_tmp =
      95      gcc_jit_function_new_local (fn_test_writing, NULL,
      96  				struct_type,
      97  				"tmp");
      98    /* tmp.x = 5; */
      99    gcc_jit_block *writing_block = gcc_jit_function_new_block (fn_test_writing, NULL);
     100    gcc_jit_block_add_assignment (
     101      writing_block, NULL,
     102      gcc_jit_lvalue_access_field (local_tmp, NULL, x),
     103      gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 5));
     104  
     105    /* tmp.y = 7; */
     106    gcc_jit_block_add_assignment (
     107      writing_block, NULL,
     108      gcc_jit_lvalue_access_field (local_tmp, NULL, y),
     109      gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 7));
     110  
     111    /* return test_reading (&tmp); */
     112    gcc_jit_rvalue *arg = gcc_jit_lvalue_get_address (local_tmp, NULL);
     113    gcc_jit_block_end_with_return (
     114      writing_block,
     115      NULL,
     116      gcc_jit_context_new_call (
     117        ctxt, NULL,
     118        fn_test_reading,
     119        1, &arg));
     120  }
     121  
     122  void
     123  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
     124  {
     125    typedef int (*fn_type) (void);
     126    CHECK_NON_NULL (result);
     127  
     128    fn_type test_writing =
     129      (fn_type)gcc_jit_result_get_code (result, "test_writing");
     130    CHECK_NON_NULL (test_writing);
     131  
     132    /* Verify that the code correctly returns the product of the fields.  */
     133    CHECK_VALUE (test_writing (), 35);
     134  }
     135