aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPetter Tomner <tomner@kth.se>2021-09-09 00:50:06 +0200
committerPetter Tomner <tomner@kth.se>2021-09-11 01:00:48 +0200
commit332a9f7636ca2a49be3a6ee9c610c5dba9e7e2da (patch)
tree8fd2bb6dc81eedfa6db9a6b65ff17e49ed05a5f4 /gcc
parent57b7c432cce893e1ba60d9b94a9606df6b419379 (diff)
downloadgcc-332a9f7636ca2a49be3a6ee9c610c5dba9e7e2da.zip
gcc-332a9f7636ca2a49be3a6ee9c610c5dba9e7e2da.tar.gz
gcc-332a9f7636ca2a49be3a6ee9c610c5dba9e7e2da.tar.bz2
libgccjit: Generate debug info for variables
Finalize declares via available helpers after location is set. Set TYPE_NAME of primitives and friends to "int" etc. Debug info is now set properly for variables. Signed-off-by: 2021-09-09 Petter Tomner <tomner@kth.se> gcc/jit/ * jit-playback.c: Moved global var processing to after loc handling. Setting TYPE_NAME for fundamental types. Using common functions for finalizing globals. * jit-playback.h: New method init_types(). Changed get_tree_node_for_type() to method. gcc/testsuite/ * jit.dg/test-error-array-bounds.c: Array is not unsigned * jit.dg/jit.exp: Helper function * jit.dg/test-debuginfo.c: New testcase
Diffstat (limited to 'gcc')
-rw-r--r--gcc/jit/jit-playback.c70
-rw-r--r--gcc/jit/jit-playback.h5
-rw-r--r--gcc/testsuite/jit.dg/jit.exp28
-rw-r--r--gcc/testsuite/jit.dg/test-debuginfo.c72
-rw-r--r--gcc/testsuite/jit.dg/test-error-array-bounds.c2
5 files changed, 162 insertions, 15 deletions
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 79ac525..59399de 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -165,7 +165,8 @@ gt_ggc_mx ()
/* Given an enum gcc_jit_types value, get a "tree" type. */
-static tree
+tree
+playback::context::
get_tree_node_for_type (enum gcc_jit_types type_)
{
switch (type_)
@@ -192,11 +193,7 @@ get_tree_node_for_type (enum gcc_jit_types type_)
return short_unsigned_type_node;
case GCC_JIT_TYPE_CONST_CHAR_PTR:
- {
- tree const_char = build_qualified_type (char_type_node,
- TYPE_QUAL_CONST);
- return build_pointer_type (const_char);
- }
+ return m_const_char_ptr;
case GCC_JIT_TYPE_INT:
return integer_type_node;
@@ -579,10 +576,6 @@ playback::lvalue *
playback::context::
global_finalize_lvalue (tree inner)
{
- varpool_node::get_create (inner);
-
- varpool_node::finalize_decl (inner);
-
m_globals.safe_push (inner);
return new lvalue (this, inner);
@@ -2952,9 +2945,7 @@ replay ()
{
JIT_LOG_SCOPE (get_logger ());
- m_const_char_ptr
- = build_pointer_type (build_qualified_type (char_type_node,
- TYPE_QUAL_CONST));
+ init_types ();
/* Replay the recorded events: */
timevar_push (TV_JIT_REPLAY);
@@ -2984,10 +2975,17 @@ replay ()
{
int i;
function *func;
-
+ tree global;
/* No GC can happen yet; process the cached source locations. */
handle_locations ();
+ /* Finalize globals. See how FORTRAN 95 does it in gfc_be_parse_file()
+ for a simple reference. */
+ FOR_EACH_VEC_ELT (m_globals, i, global)
+ rest_of_decl_compilation (global, true, true);
+
+ wrapup_global_declarations (m_globals.address(), m_globals.length());
+
/* We've now created tree nodes for the stmts in the various blocks
in each function, but we haven't built each function's single stmt
list yet. Do so now. */
@@ -3081,6 +3079,50 @@ location_comparator (const void *lhs, const void *rhs)
return loc_lhs->get_column_num () - loc_rhs->get_column_num ();
}
+/* Initialize the NAME_TYPE of the primitive types as well as some
+ others. */
+void
+playback::context::
+init_types ()
+{
+ /* See lto_init() in lto-lang.c or void visit (TypeBasic *t) in D's types.cc
+ for reference. If TYPE_NAME is not set, debug info will not contain types */
+#define NAME_TYPE(t,n) \
+if (t) \
+ TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, \
+ get_identifier (n), t)
+
+ NAME_TYPE (integer_type_node, "int");
+ NAME_TYPE (char_type_node, "char");
+ NAME_TYPE (long_integer_type_node, "long int");
+ NAME_TYPE (unsigned_type_node, "unsigned int");
+ NAME_TYPE (long_unsigned_type_node, "long unsigned int");
+ NAME_TYPE (long_long_integer_type_node, "long long int");
+ NAME_TYPE (long_long_unsigned_type_node, "long long unsigned int");
+ NAME_TYPE (short_integer_type_node, "short int");
+ NAME_TYPE (short_unsigned_type_node, "short unsigned int");
+ if (signed_char_type_node != char_type_node)
+ NAME_TYPE (signed_char_type_node, "signed char");
+ if (unsigned_char_type_node != char_type_node)
+ NAME_TYPE (unsigned_char_type_node, "unsigned char");
+ NAME_TYPE (float_type_node, "float");
+ NAME_TYPE (double_type_node, "double");
+ NAME_TYPE (long_double_type_node, "long double");
+ NAME_TYPE (void_type_node, "void");
+ NAME_TYPE (boolean_type_node, "bool");
+ NAME_TYPE (complex_float_type_node, "complex float");
+ NAME_TYPE (complex_double_type_node, "complex double");
+ NAME_TYPE (complex_long_double_type_node, "complex long double");
+
+ m_const_char_ptr = build_pointer_type(
+ build_qualified_type (char_type_node, TYPE_QUAL_CONST));
+
+ NAME_TYPE (m_const_char_ptr, "char");
+ NAME_TYPE (size_type_node, "size_t");
+ NAME_TYPE (fileptr_type_node, "FILE");
+#undef NAME_TYPE
+}
+
/* Our API allows locations to be created in arbitrary orders, but the
linemap API requires locations to be created in ascending order
as if we were tokenizing files.
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 825a3e1..f670c9e 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -271,8 +271,13 @@ private:
source_file *
get_source_file (const char *filename);
+ tree
+ get_tree_node_for_type (enum gcc_jit_types type_);
+
void handle_locations ();
+ void init_types ();
+
const char * get_path_c_file () const;
const char * get_path_s_file () const;
const char * get_path_so_file () const;
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 005ba01..4459dbc 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -377,6 +377,34 @@ proc dg-jit-set-exe-params { args } {
}
}
+# For test-debuginfo.c. Starts gdb, does cmds and checks the output against match
+proc jit-check-debug-info { obj_file cmds match } {
+ verbose "Checking debug info for $obj_file with match: $match"
+
+ if { [catch {exec gdb -v} fid] } {
+ verbose "No gdb seems to be in path. Can't check debug info. Reporting 'unsupported'."
+ unsupported "No gdb seems to be in path. Can't check debug info"
+ return
+ }
+
+ spawn gdb $obj_file
+
+ verbose "Disable color styling in GDB newer then 8.3 (errors on older)"
+ send "set style enabled off\n"
+
+ foreach cmd $cmds {
+ send $cmd
+ }
+ expect {
+ -re $match { pass OK }
+ default { fail FAIL }
+ }
+
+ # Quit gdb
+ send "set confirm off\n"
+ send "q\n"
+}
+
proc jit-dg-test { prog do_what extra_tool_flags } {
verbose "within jit-dg-test..."
verbose " prog: $prog"
diff --git a/gcc/testsuite/jit.dg/test-debuginfo.c b/gcc/testsuite/jit.dg/test-debuginfo.c
new file mode 100644
index 0000000..49e8834
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-debuginfo.c
@@ -0,0 +1,72 @@
+/* Essentially this test checks that debug info are generated for globals
+ locals and functions, including type info. The comment bellow is used
+ as fake code (does not affect the test, use for manual debugging). */
+/*
+int a_global_for_test_debuginfo;
+int main (int argc, char **argv)
+{
+ int a_local_for_test_debuginfo = 2;
+ return a_global_for_test_debuginfo + a_local_for_test_debuginfo;
+}
+*/
+#include "libgccjit.h"
+
+/* We don't want set_options() in harness.h to set -O3 so our little local
+ is optimized away. */
+#define TEST_ESCHEWS_SET_OPTIONS
+static void set_options (gcc_jit_context *ctxt, const char *argv0)
+{
+ gcc_jit_context_set_bool_option(ctxt, GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
+}
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_EXECUTABLE
+#define OUTPUT_FILENAME "jit-debuginfo.o"
+#include "harness.h"
+
+#define LOC(row, col) gcc_jit_context_new_location(ctxt, "test-debuginfo.c", row, col)
+
+void
+create_code (gcc_jit_context *ctxt, void* p)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_INT);
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global(ctxt,
+ LOC(5,1), GCC_JIT_GLOBAL_EXPORTED,
+ int_type, "a_global_for_test_debuginfo");
+
+ gcc_jit_param *argc_para = gcc_jit_context_new_param(ctxt, LOC(6,15),
+ int_type, "argc");
+ gcc_jit_param *argv_para = gcc_jit_context_new_param(ctxt, LOC(6,28),
+ gcc_jit_type_get_pointer(
+ gcc_jit_type_get_pointer(
+ gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_CHAR))),
+ "argc");
+
+ gcc_jit_param *params[] = {argc_para, argv_para};
+
+ gcc_jit_function *foo_fn = gcc_jit_context_new_function(ctxt, LOC(6,5),
+ GCC_JIT_FUNCTION_EXPORTED, int_type, "main", 2, params, 0);
+ gcc_jit_block *start_block = gcc_jit_function_new_block(foo_fn,
+ "start_block");
+
+ gcc_jit_lvalue *a = gcc_jit_function_new_local(foo_fn, LOC(8,5),
+ int_type, "a_local_for_test_debuginfo");
+ gcc_jit_block_add_assignment(start_block, LOC(8,36), a,
+ gcc_jit_context_new_rvalue_from_int(ctxt, int_type, 2));
+ gcc_jit_rvalue *add = gcc_jit_context_new_binary_op(ctxt, LOC(9,40),
+ GCC_JIT_BINARY_OP_PLUS, int_type,
+ gcc_jit_lvalue_as_rvalue(a), gcc_jit_lvalue_as_rvalue(bar));
+
+ gcc_jit_block_end_with_return(start_block, LOC(9,5), add);
+}
+
+#undef LOC
+
+/* jit-check-debug-info fires up gdb and checks that the variables have
+ debug info */
+
+/* { dg-final { jit-check-debug-info "jit-debuginfo.o" {"info variables\n"} "int\\s+a_global_for_test_debuginfo;" } } */
+/* { dg-final { jit-check-debug-info "jit-debuginfo.o" {"pt main\n"} "int\\s*\\(\\s*int\\s*,\\s*char\\s*\\*\\*\\s*\\)"} } */
+/* { dg-final { jit-check-debug-info "jit-debuginfo.o" {"start\n" "info locals\n"} "a_local_for_test_debuginfo"} } */
+/* { dg-final { jit-check-debug-info "jit-debuginfo.o" {"start\n" "pt a_local_for_test_debuginfo\n"} "int"} } */ \ No newline at end of file
diff --git a/gcc/testsuite/jit.dg/test-error-array-bounds.c b/gcc/testsuite/jit.dg/test-error-array-bounds.c
index cd9361f..b6c0ee5 100644
--- a/gcc/testsuite/jit.dg/test-error-array-bounds.c
+++ b/gcc/testsuite/jit.dg/test-error-array-bounds.c
@@ -70,5 +70,5 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
/* ...and that the message was captured by the API. */
CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
"array subscript 10 is above array bounds of"
- " 'unsigned char[10]' [-Warray-bounds]");
+ " 'char[10]' [-Warray-bounds]");
}