From: Antoni Boucher <[email protected]>

gcc/jit/ChangeLog:

        * docs/topics/compatibility.rst (LIBGCCJIT_ABI_36): New ABI tag.
        * docs/topics/expressions.rst: Document gcc_jit_rvalue_set_location.
        * docs/topics/functions.rst: Document gcc_jit_function_set_location.
        * docs/topics/types.rst: Document gcc_jit_field_set_location.
        * jit-recording.h (set_location): New methods.
        * libgccjit.cc (gcc_jit_field_set_location,
        gcc_jit_rvalue_set_location, gcc_jit_function_set_location): New
        methods.
        * libgccjit.h (gcc_jit_field_set_location,
        gcc_jit_rvalue_set_location, gcc_jit_function_set_location): New
        methods.
        * libgccjit.map (LIBGCCJIT_ABI_36): New ABI tag.

gcc/testsuite/ChangeLog:

        * jit.dg/all-non-failing-tests.h: Mention new test.
        * jit.dg/test-set-debuginfo.c: New test.

Co-authored-by: tempdragon <[email protected]>
---
 gcc/jit/docs/topics/compatibility.rst        | 11 +++
 gcc/jit/docs/topics/expressions.rst          | 13 ++++
 gcc/jit/docs/topics/functions.rst            | 13 ++++
 gcc/jit/docs/topics/types.rst                | 13 ++++
 gcc/jit/jit-recording.h                      |  7 ++
 gcc/jit/libgccjit.cc                         | 43 +++++++++++
 gcc/jit/libgccjit.h                          | 12 ++++
 gcc/jit/libgccjit.map                        |  7 ++
 gcc/testsuite/jit.dg/all-non-failing-tests.h |  3 +
 gcc/testsuite/jit.dg/test-set-debuginfo.c    | 76 ++++++++++++++++++++
 10 files changed, 198 insertions(+)
 create mode 100644 gcc/testsuite/jit.dg/test-set-debuginfo.c

diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 19be33eb4b50..43582b5a669c 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -466,3 +466,14 @@ information:
   * :func:`gcc_jit_target_info_cpu_supports`
   * :func:`gcc_jit_target_info_arch`
   * :func:`gcc_jit_target_info_supports_target_dependent_type`
+
+.. _LIBGCCJIT_ABI_36:
+
+``LIBGCCJIT_ABI_36``
+--------------------
+``LIBGCCJIT_ABI_36`` covers the addition of functions to set the debug info
+location:
+
+  * :func:`gcc_jit_field_set_location`
+  * :func:`gcc_jit_function_set_location`
+  * :func:`gcc_jit_rvalue_set_location`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 5dcb5d10bce8..c976ac3bd924 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -154,6 +154,19 @@ Simple expressions
 
      _Alignof (type)
 
+.. function:: void *\
+              gcc_jit_rvalue_set_location (gcc_jit_rvalue *rvalue, \
+					   gcc_jit_location *loc)
+
+   Set the location of ``rvalue``.
+
+   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for
+   their presence using:
+
+   .. code-block:: c
+
+     #ifdef LIBGCCJIT_HAVE_SET_LOCATIONS
+
 Constructor expressions
 ***********************
 
diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst
index ceedc4b82a32..7f23e71c3b38 100644
--- a/gcc/jit/docs/topics/functions.rst
+++ b/gcc/jit/docs/topics/functions.rst
@@ -299,6 +299,19 @@ Functions
 
       #ifdef LIBGCCJIT_HAVE_ATTRIBUTES
 
+.. function:: void *\
+              gcc_jit_function_set_location (gcc_jit_function *func, \
+					     gcc_jit_location *loc)
+
+   Set the location of ``func``.
+
+   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for
+   their presence using:
+
+   .. code-block:: c
+
+     #ifdef LIBGCCJIT_HAVE_SET_LOCATIONS
+
 Blocks
 ------
 .. type:: gcc_jit_block
diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index e699ee5301b5..ef53d53963da 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -324,6 +324,19 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct` and
 
    Upcast from field to object.
 
+.. function:: void *\
+              gcc_jit_field_set_location (gcc_jit_field *field, \
+					  gcc_jit_location *loc)
+
+   Set the location of ``field``.
+
+   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for
+   their presence using:
+
+   .. code-block:: c
+
+     #ifdef LIBGCCJIT_HAVE_SET_LOCATIONS
+
 .. function:: gcc_jit_struct *\
    gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,\
                                     gcc_jit_location *loc,\
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4d41faa0446a..3dd98a5b1e25 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -1067,6 +1067,7 @@ class array_type : public type
   bool is_signed () const final override { return false; }
 
   void replay_into (replayer *) final override;
+  void set_loc (location * loc) { m_loc = loc; }
 
  private:
   string * make_debug_string () final override;
@@ -1157,6 +1158,7 @@ public:
 
   compound_type * get_container () const { return m_container; }
   void set_container (compound_type *c) { m_container = c; }
+  void set_loc (location * loc) { m_loc = loc; }
 
   void replay_into (replayer *) override;
 
@@ -1231,6 +1233,7 @@ public:
   bool is_signed () const final override { return false; }
 
   bool has_known_size () const final override { return m_fields != NULL; }
+  void set_loc (location * loc) { m_loc = loc; }
 
   playback::compound_type *
   playback_compound_type ()
@@ -1372,6 +1375,7 @@ public:
   }
 
   location * get_loc () const { return m_loc; }
+  void set_loc (location * loc) { m_loc = loc; }
 
   /* Get the recording::type of this rvalue.
 
@@ -1568,6 +1572,7 @@ public:
   new_block (const char *name);
 
   location *get_loc () const { return m_loc; }
+  void set_loc (location * loc) { m_loc = loc; }
   type *get_return_type () const { return m_return_type; }
   string * get_name () const { return m_name; }
   const vec<param *> &get_params () const { return m_params; }
@@ -1696,6 +1701,7 @@ public:
   bool validate ();
 
   location *get_loc () const;
+  void set_loc (location * loc);
 
   statement *get_first_statement () const;
   statement *get_last_statement () const;
@@ -2484,6 +2490,7 @@ public:
 
   block *get_block () const { return m_block; }
   location *get_loc () const { return m_loc; }
+  void set_loc (location * loc) { m_loc = loc; }
 
 protected:
   statement (block *b, location *loc)
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 33369447074b..18838548ed7f 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -4706,3 +4706,46 @@ gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
   RETURN_IF_FAIL (asm_stmts, ctxt, NULL, "NULL asm_stmts");
   ctxt->add_top_level_asm (loc, asm_stmts);
 }
+
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, this calls the trivial
+   gcc::jit::recording::field::set_loc method, in jit-recording.h.  */
+
+void
+gcc_jit_field_set_location (gcc_jit_field *field,
+			    gcc_jit_location *loc)
+{
+  RETURN_IF_FAIL (field, NULL, NULL, "NULL field");
+
+  field->set_loc (loc);
+}
+
+
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, this calls the trivial
+   gcc::jit::recording::rvalue::set_loc method , in jit-recording.h.  */
+
+void
+gcc_jit_rvalue_set_location (gcc_jit_rvalue *rvalue,
+			     gcc_jit_location *loc)
+{
+  RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
+
+  rvalue->set_loc (loc);
+}
+
+/* Public entrypoint.  See description in libgccjit.h.
+
+   After error-checking, this calls the trivial
+   gcc::jit::recording::function::set_loc method, in jit-recording.h.  */
+
+void
+gcc_jit_function_set_location (gcc_jit_function *func,
+			       gcc_jit_location *loc)
+{
+  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
+
+  func->set_loc (loc);
+}
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index a58551007931..df34729a2649 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -2216,6 +2216,18 @@ gcc_jit_context_set_output_ident (gcc_jit_context *ctxt,
 
 #define LIBGCCJIT_HAVE_gcc_jit_context_set_output_ident
 
+extern void
+gcc_jit_field_set_location (gcc_jit_field *field,
+			    gcc_jit_location *loc);
+extern void
+gcc_jit_function_set_location (gcc_jit_function *func,
+			       gcc_jit_location *loc);
+extern void
+gcc_jit_rvalue_set_location (gcc_jit_rvalue *rvalue,
+			     gcc_jit_location *loc);
+
+#define LIBGCCJIT_HAVE_SET_LOCATIONS
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 4662ca4b3c02..4b355430166c 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -334,3 +334,10 @@ LIBGCCJIT_ABI_35 {
     gcc_jit_target_info_arch;
     gcc_jit_target_info_supports_target_dependent_type;
 } LIBGCCJIT_ABI_34;
+
+LIBGCCJIT_ABI_36 {
+   global:
+    gcc_jit_field_set_location;
+    gcc_jit_function_set_location;
+    gcc_jit_rvalue_set_location;
+} LIBGCCJIT_ABI_35;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 4aa18e3b7678..e6d887c45c4f 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -380,6 +380,9 @@
 /* test-register-variable.c: This can't be in the testcases array as it
    is target-specific.  */
 
+/* test-set-debuginfo.c: This can't be in the testcases array as it needs
+   the `-g` flag.  */
+
 /* test-setting-alignment.c: This can't be in the testcases array as it
    is target-specific.  */
 
diff --git a/gcc/testsuite/jit.dg/test-set-debuginfo.c b/gcc/testsuite/jit.dg/test-set-debuginfo.c
new file mode 100644
index 000000000000..83ac24a18f99
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-set-debuginfo.c
@@ -0,0 +1,76 @@
+/* Essentially this test checks that debug info are generated for globals
+   locals and functions, including type info. The comment below 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-set-debuginfo.o"
+#include "harness.h"
+
+#define LOC(row, col) gcc_jit_context_new_location(ctxt, "test-set-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,
+    NULL, GCC_JIT_GLOBAL_EXPORTED,
+    int_type, "a_global_for_test_debuginfo");
+
+  gcc_jit_param *argc_para = gcc_jit_context_new_param(ctxt, NULL,
+    int_type, "argc");
+  gcc_jit_param *argv_para = gcc_jit_context_new_param(ctxt, NULL,
+    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_location *func_loc = LOC(6,5);
+  gcc_jit_function *foo_fn = gcc_jit_context_new_function(ctxt, NULL,
+    GCC_JIT_FUNCTION_EXPORTED, int_type, "main", 2, params, 0);
+  gcc_jit_function_set_location (foo_fn, func_loc);
+  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, NULL,
+    int_type, "a_local_for_test_debuginfo");
+  gcc_jit_block_add_assignment(start_block, NULL, a,
+    gcc_jit_context_new_rvalue_from_int(ctxt, int_type, 2));
+  gcc_jit_location *add_loc = LOC(9,40);
+  gcc_jit_rvalue *add = gcc_jit_context_new_binary_op(ctxt, NULL,
+    GCC_JIT_BINARY_OP_PLUS, int_type,
+    gcc_jit_lvalue_as_rvalue(a), gcc_jit_lvalue_as_rvalue(bar));
+  gcc_jit_rvalue_set_location (add, add_loc);
+
+  gcc_jit_block_end_with_return(start_block, NULL, 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-set-debuginfo.o" {"info variables\n"} "int\\s+a_global_for_test_debuginfo;" } } */
+/*  { dg-final { jit-check-debug-info "jit-set-debuginfo.o" {"pt main\n"} "int\\s*\\(\\s*int\\s*,\\s*char\\s*\\*\\*\\s*\\)"} } */
+/*  { dg-final { jit-check-debug-info "jit-set-debuginfo.o" {"start\n" "info locals\n"} "a_local_for_test_debuginfo"} } */
+/*  { dg-final { jit-check-debug-info "jit-set-debuginfo.o" {"start\n" "pt a_local_for_test_debuginfo\n"} "int"} } */

Reply via email to