libgccjit: Add option to allow special characters in function names
gcc/jit/ChangeLog:
* docs/topics/contexts.rst: Add documentation for new option.
* jit-recording.cc (recording::context::get_bool_option): New
method.
* jit-recording.h (get_bool_option): New method.
* libgccjit.cc (gcc_jit_context_new_function): Allow special
characters in function names.
* libgccjit.h (enum gcc_jit_bool_option): New option.
gcc/testsuite/ChangeLog:
* jit.dg/test-special-chars.c: New test.
diff --git a/gcc/jit/docs/topics/contexts.rst b/gcc/jit/docs/topics/contexts.rst
index 10a0e50..4af75ea 100644
--- a/gcc/jit/docs/topics/contexts.rst
+++ b/gcc/jit/docs/topics/contexts.rst
@@ -453,6 +453,10 @@
If true, the :type:`gcc_jit_context` will not clean up intermediate files
written to the filesystem, and will display their location on stderr.
+ .. macro:: GCC_JIT_BOOL_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES
+
+ If true, allow special characters like . and $ in function names.
+
.. function:: void \
gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt, \
int bool_value)
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 83a8b29..962c37e 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1511,6 +1511,18 @@
log_bool_option (opt);
}
+int
+recording::context::get_bool_option (enum gcc_jit_bool_option opt)
+{
+ if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
+ {
+ add_error (NULL,
+ "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
+ return 0;
+ }
+ return m_bool_options[opt];
+}
+
void
recording::context::set_inner_bool_option (enum inner_bool_option inner_opt,
int value)
@@ -1863,7 +1875,8 @@
"GCC_JIT_BOOL_OPTION_DUMP_SUMMARY",
"GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING",
"GCC_JIT_BOOL_OPTION_SELFCHECK_GC",
- "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES"
+ "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES",
+ "GCC_JIT_BOOL_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES",
};
static const char * const
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4833b2d..377b60c 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -267,6 +267,9 @@
set_bool_option (enum gcc_jit_bool_option opt,
int value);
+ int
+ get_bool_option (enum gcc_jit_bool_option opt);
+
void
set_inner_bool_option (enum inner_bool_option inner_opt,
int value);
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 5a1308b..8365800 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -1222,10 +1222,13 @@
Eventually we'll need some way to interact with e.g. C++ name
mangling. */
{
+ int special_chars_allowed
+ = ctxt->get_bool_option (GCC_JIT_BOOL_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES);
/* Leading char: */
char ch = *name;
RETURN_NULL_IF_FAIL_PRINTF2 (
- ISALPHA (ch) || ch == '_',
+ ISALPHA (ch) || ch == '_' || (special_chars_allowed
+ && (ch == '.' || ch == '$' || ch == '*')),
ctxt, loc,
"name \"%s\" contains invalid character: '%c'",
name, ch);
@@ -1233,7 +1236,8 @@
for (const char *ptr = name + 1; (ch = *ptr); ptr++)
{
RETURN_NULL_IF_FAIL_PRINTF2 (
- ISALNUM (ch) || ch == '_',
+ ISALNUM (ch) || ch == '_' || (special_chars_allowed
+ && (ch == '.' || ch == '$' || ch == '*')),
ctxt, loc,
"name \"%s\" contains invalid character: '%c'",
name, ch);
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index d45b767..694f45f 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -244,6 +244,9 @@
their location on stderr. */
GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
+ /* If true, allow special characters like . and $ in function names. */
+ GCC_JIT_BOOL_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES,
+
GCC_JIT_NUM_BOOL_OPTIONS
};
diff --git a/gcc/testsuite/jit.dg/test-special-chars.c b/gcc/testsuite/jit.dg/test-special-chars.c
new file mode 100644
index 0000000..1bca711
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-special-chars.c
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_context_set_bool_option (ctxt,
+ GCC_JIT_BOOL_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES, 1);
+
+ /* Let's try to inject the equivalent of:
+ void
+ name$with.special_chars (void)
+ {
+ }
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "name$with.special_chars",
+ 0, NULL,
+ 0);
+
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+ gcc_jit_block_end_with_void_return (
+ block, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+}