211 lines
6.0 KiB
C
211 lines
6.0 KiB
C
#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. */
|
|
}
|