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

#include "libgccjit.h"

#include "harness.h"

/* Build various compound expressions, and verify that they have sane debug
   strings.  */
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Make a singly-linked list type:
      struct node
      {
       struct node *next;
       int value;
      };
  */
  gcc_jit_type *t_int =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_struct *t_node =
    gcc_jit_context_new_opaque_struct (ctxt, NULL, "node");
  gcc_jit_type *t_node_ptr =
    gcc_jit_type_get_pointer (gcc_jit_struct_as_type (t_node));
  gcc_jit_field *f_next =
    gcc_jit_context_new_field (ctxt, NULL, t_node_ptr, "next");
  gcc_jit_field *f_value =
    gcc_jit_context_new_field (ctxt, NULL, t_int, "value");
  gcc_jit_field *fields[] = {f_next, f_value};
  gcc_jit_struct_set_fields (t_node, NULL, 2, fields);

  /* Create a dummy function so that we have locals/params to build
     expressions with.  */
  gcc_jit_type *t_void =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_function *fn =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  t_void,
				  "test_debug_strings",
				  0, NULL, 0);
  gcc_jit_rvalue *ptr =
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_function_new_local (fn,
				  NULL,
				  t_node_ptr,
				  "ptr"));
  gcc_jit_rvalue *a =
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_function_new_local (fn, NULL, t_int, "a"));
  gcc_jit_rvalue *b =
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_function_new_local (fn, NULL, t_int, "b"));
  gcc_jit_rvalue *c =
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_function_new_local (fn, NULL, t_int, "c"));
  gcc_jit_rvalue *d =
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_function_new_local (fn, NULL, t_int, "d"));

#define CHECK_RVALUE_DEBUG_STRING(RVALUE, EXPECTED) \
  CHECK_STRING_VALUE ( \
    gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (RVALUE)), \
    (EXPECTED))

#define CHECK_LVALUE_DEBUG_STRING(LVALUE, EXPECTED) \
  CHECK_STRING_VALUE ( \
    gcc_jit_object_get_debug_string (gcc_jit_lvalue_as_object (LVALUE)), \
    (EXPECTED))

  /* Verify various simple compound expressions.  */
  {
    CHECK_RVALUE_DEBUG_STRING (ptr, "ptr");

    gcc_jit_lvalue *deref =
      gcc_jit_rvalue_dereference_field (ptr,
					NULL,
					f_value);
    CHECK_LVALUE_DEBUG_STRING (deref, "ptr->value");

    gcc_jit_rvalue *deref_as_rvalue = gcc_jit_lvalue_as_rvalue (deref);

#define BINOP(OP, A, B) \
    gcc_jit_context_new_binary_op (ctxt, NULL, \
				   GCC_JIT_BINARY_OP_##OP, t_int, (A), (B))
#define COMPARISON(OP, A, B) \
    gcc_jit_context_new_comparison (ctxt, NULL, \
				    GCC_JIT_COMPARISON_##OP,(A), (B))

    CHECK_RVALUE_DEBUG_STRING (
      BINOP (PLUS, deref_as_rvalue, deref_as_rvalue),
      "ptr->value + ptr->value");
    CHECK_RVALUE_DEBUG_STRING (
      BINOP (MULT, deref_as_rvalue, deref_as_rvalue),
      "ptr->value * ptr->value");

   /* Multiplication has higher precedence in C than addition, so this
       dump shouldn't contain parentheses.  */
    CHECK_RVALUE_DEBUG_STRING (
      BINOP (PLUS,
	     BINOP (MULT, a, b),
	     BINOP (MULT, c, d)),
      "a * b + c * d");

    /* ...but this one should.  */
    CHECK_RVALUE_DEBUG_STRING (
      BINOP (MULT,
	     BINOP (PLUS, a, b),
	     BINOP (PLUS, c, d)),
      "(a + b) * (c + d)");

    /* Equal precedences don't need parentheses.  */
    CHECK_RVALUE_DEBUG_STRING (
      BINOP (MULT,
	     BINOP (MULT, a, b),
	     BINOP (MULT, c, d)),
      "a * b * c * d");

    /* Comparisons and logical ops.  */
    CHECK_RVALUE_DEBUG_STRING (
      COMPARISON (LT, a, b),
      "a < b");

    CHECK_RVALUE_DEBUG_STRING (
      BINOP (LOGICAL_AND,
	     COMPARISON (LT, a, b),
	     COMPARISON (GT, c, d)),
      "a < b && c > d");

    CHECK_RVALUE_DEBUG_STRING (
      BINOP (LOGICAL_AND,
	     BINOP (LOGICAL_OR,
		    COMPARISON (LT, a, b),
		    COMPARISON (LT, a, c)),
	     BINOP (LOGICAL_OR,
		    COMPARISON (GT, d, b),
		    COMPARISON (GT, d, c))),
      "(a < b || a < c) && (d > b || d > c)");

    CHECK_RVALUE_DEBUG_STRING (
      BINOP (LOGICAL_OR,
	     BINOP (LOGICAL_AND,
		    COMPARISON (LT, a, b),
		    COMPARISON (LT, a, c)),
	     BINOP (LOGICAL_AND,
		    COMPARISON (GT, d, b),
		    COMPARISON (GT, d, c))),
      "a < b && a < c || d > b && d > c");

#undef BINOP
#undef COMPARISON
  }

  /* PR jit/66539 "Missing parentheses in jit dumps".
     Construct the equivalent of
       ((cast)ptr->next)->next
     and verify that the appropriate parentheses appear in the debug
     string.   */
  {
    /* "ptr->next". */
    gcc_jit_lvalue *inner_deref =
      gcc_jit_rvalue_dereference_field (ptr,
					NULL,
					f_next);
    /* "((node *)ptr->next)"; the cast is redundant, purely
       to exercise dumping.  */
    gcc_jit_rvalue *test_cast =
      gcc_jit_context_new_cast (ctxt, NULL,
				gcc_jit_lvalue_as_rvalue (inner_deref),
				t_node_ptr);
    /* "((node *)ptr->next)->next".  */
    gcc_jit_lvalue *outer_deref =
      gcc_jit_rvalue_dereference_field (test_cast, /* gcc_jit_rvalue *ptr */
					NULL, /* gcc_jit_location *loc */
					f_next); /* gcc_jit_field *field */
    CHECK_LVALUE_DEBUG_STRING (outer_deref,
			       "((struct node *)ptr->next)->next");
  }

  /* Check string literal escaping.  */
  {
    CHECK_RVALUE_DEBUG_STRING
      (gcc_jit_context_new_string_literal (ctxt, ""),
       "\"\"");
    CHECK_RVALUE_DEBUG_STRING
      (gcc_jit_context_new_string_literal (ctxt, "foo"),
       "\"foo\"");
    CHECK_RVALUE_DEBUG_STRING
      (gcc_jit_context_new_string_literal (ctxt, "\""),
       "\"\\\"\"");
    CHECK_RVALUE_DEBUG_STRING
      (gcc_jit_context_new_string_literal (ctxt, "line 1\nline 2\n"),
       "\"line 1\\nline 2\\n\"");
    CHECK_RVALUE_DEBUG_STRING
      (gcc_jit_context_new_string_literal (ctxt, "foo\tbar"),
       "\"foo\\tbar\"");
  }

#undef CHECK_RVALUE_DEBUG_STRING
#undef CHECK_LVALUE_DEBUG_STRING
}

void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
  CHECK_NON_NULL (result);
  /* We don't actually build any functions above;
     nothing more to verify.  */
}
