/* { dg-do compile { target x86_64-*-* } } */

#include <stdlib.h>
#include <stdio.h>

#include "libgccjit.h"

#define TEST_ESCHEWS_SET_OPTIONS
static void set_options (gcc_jit_context *ctxt, const char *argv0)
{
  // Set "-O0".
  gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 0);
}

#define TEST_COMPILING_TO_FILE
#define OUTPUT_KIND      GCC_JIT_OUTPUT_KIND_ASSEMBLER
#define OUTPUT_FILENAME  "output-of-test-always_inline-attribute.c.s"
#include "harness.h"

gcc_jit_function*
create_function (gcc_jit_context *ctxt,
		 const char *func_name,
		 gcc_jit_type *int_type,
		 gcc_jit_type *pint_type)
{
  /* The `a` function argument */
  gcc_jit_param *a = gcc_jit_context_new_param (ctxt, NULL, pint_type, "a");
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
          GCC_JIT_FUNCTION_INTERNAL,
          int_type,
          func_name,
          1, &a,
          0);

  gcc_jit_block *if_cond =
    gcc_jit_function_new_block (func, "if_cond");
  gcc_jit_block *if_body =
    gcc_jit_function_new_block (func, "if_body");
  gcc_jit_block *after_if =
    gcc_jit_function_new_block (func, "after_if");

  /* if (!a) */
  gcc_jit_block_end_with_conditional (
    if_cond, NULL,
    gcc_jit_context_new_comparison (
      ctxt, NULL,
      GCC_JIT_COMPARISON_EQ,
      gcc_jit_param_as_rvalue (a),
      gcc_jit_context_null (ctxt, pint_type)),
    if_body,
    after_if);
  /* return -1; */
  gcc_jit_block_end_with_return (
    if_body, NULL,
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, -1));

  /* return *a; */
  gcc_jit_block_end_with_return (
    after_if, NULL,
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_rvalue_dereference (
	gcc_jit_param_as_rvalue (a), NULL)));

  return func;
}


void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
__attribute__ ((always_inline))
static inline int removed (int *a) {
  if (!a) {
    return -1;
  }
  return *a;
}
static int not_removed (int *a) {
  if (!a) {
    return -1;
  }
  return *a;
}
int foo () {
  int x = 0;
  x += removed(NULL);
  x += not_removed(NULL);
  return x;
}
  */
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *pint_type = gcc_jit_type_get_pointer (int_type);

  /* Creating the `removed` function. */
  gcc_jit_function *removed_func =
    create_function (ctxt, "removed", int_type, pint_type);
  /* This one is to declare the function as "inline" */
  gcc_jit_function_add_attribute(removed_func, GCC_JIT_FN_ATTRIBUTE_INLINE);
  /* __attribute__ ((always_inline)) */
  gcc_jit_function_add_attribute(removed_func, GCC_JIT_FN_ATTRIBUTE_ALWAYS_INLINE);

  /* Creating the `not_removed` function. */
  gcc_jit_function *not_removed_func =
    create_function (ctxt, "not_removed", int_type, pint_type);

  /* Creating the `foo` function. */
  gcc_jit_function *foo_func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  int_type,
				  "foo",
				  0, NULL,
				  0);

  gcc_jit_block *foo_block = gcc_jit_function_new_block (foo_func, NULL);

  /* Build locals:  */
  gcc_jit_lvalue *x =
    gcc_jit_function_new_local (foo_func, NULL, int_type, "x");

  /* int x = 0; */
  gcc_jit_block_add_assignment (
    foo_block, NULL,
    x,
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0));

  /* x += removed(NULL); */
  gcc_jit_rvalue *null = gcc_jit_context_null (ctxt, pint_type);
  gcc_jit_block_add_assignment_op (
    foo_block, NULL,
    x,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_new_call (ctxt, NULL, removed_func, 1, &null));
  
  /* x += not_removed(NULL); */
  gcc_jit_block_add_assignment_op (
    foo_block, NULL,
    x,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_new_call (ctxt, NULL, not_removed_func, 1, &null));

  /* return x; */
  gcc_jit_block_end_with_return (foo_block, NULL, gcc_jit_lvalue_as_rvalue(x));
}

/* { dg-final { jit-verify-output-file-was-created "" } } */
/* Check that the "removed" function was inlined, but not the others */
/* { dg-final { jit-verify-assembler-output-not ".type\\s+removed,\\s+@function" { target { ! *-*-darwin* } } } } */
/* { dg-final { jit-verify-assembler-output ".type\\s+not_removed,\\s+@function" { target { ! *-*-darwin* } } } } */
/* { dg-final { jit-verify-assembler-output ".type\\s+foo,\\s+@function" { target { ! *-*-darwin* } } } } */

/* { dg-final { jit-verify-assembler-output-not "\\n_removed:" { target *-*-darwin* } } } */
/* { dg-final { jit-verify-assembler-output "\\n_not_removed:" { target *-*-darwin* } } } */
/* { dg-final { jit-verify-assembler-output "\\n_foo:" { target *-*-darwin* } } } */
