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_lvalue_add_attribute.
* jit-playback.cc: Handle the weak attribute.
* jit-playback.h: Add support for variable attributes without
arguments.
* jit-recording.cc: Handle the weak attribute.
* jit-recording.h: Add support for variable attributes without
arguments.
* libgccjit.cc (gcc_jit_lvalue_add_attribute): New function.
* libgccjit.h (gcc_jit_lvalue_add_attribute): New function.
(GCC_JIT_VARIABLE_ATTRIBUTE_WEAK): New enum variant.
* libgccjit.map: New function.
gcc/testsuite/ChangeLog:
* jit.dg/all-non-failing-tests.h: Mention new test.
* jit.dg/test-weak-var-attribute.c: New test.
---
gcc/jit/docs/topics/compatibility.rst | 8 +++++
gcc/jit/docs/topics/expressions.rst | 13 ++++++++
gcc/jit/jit-playback.cc | 32 +++++++++++++++----
gcc/jit/jit-playback.h | 8 +++--
gcc/jit/jit-recording.cc | 20 ++++++++++++
gcc/jit/jit-recording.h | 5 ++-
gcc/jit/libgccjit.cc | 18 +++++++++++
gcc/jit/libgccjit.h | 8 +++++
gcc/jit/libgccjit.map | 5 +++
gcc/testsuite/jit.dg/all-non-failing-tests.h | 3 ++
.../jit.dg/test-weak-var-attribute.c | 31 ++++++++++++++++++
11 files changed, 142 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/jit.dg/test-weak-var-attribute.c
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 19be33eb4b5..c70fbd07929 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -466,3 +466,11 @@ 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
+
+ * :func:`gcc_jit_lvalue_add_attribute`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index 5dcb5d10bce..66538003706 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -1037,6 +1037,19 @@ Variables
#ifdef LIBGCCJIT_HAVE_ATTRIBUTES
+.. function:: void\
+ gcc_jit_lvalue_add_attribute (gcc_jit_lvalue *variable,
+ enum gcc_jit_variable_attribute attribute);
+
+ Add an attribute ``attribute`` without value to a variable ``variable``.
+
+ This entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for
+ its presence using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_add_attribute
+
.. function:: void\
gcc_jit_global_set_readonly (gcc_jit_lvalue *global)
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 291ddeb2cca..2a4d4860d39 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -559,6 +559,8 @@ const char* variable_attribute_to_string (gcc_jit_variable_attribute attr)
{
case GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY:
return "visibility";
+ case GCC_JIT_VARIABLE_ATTRIBUTE_WEAK:
+ return "weak";
case GCC_JIT_VARIABLE_ATTRIBUTE_MAX:
return NULL;
}
@@ -743,7 +745,8 @@ global_new_decl (location *loc,
const char *name,
enum global_var_flags flags,
const std::vector<std::pair<gcc_jit_variable_attribute,
- std::string>> &attributes,
+ std::string>> &string_attributes,
+ const std::vector<gcc_jit_variable_attribute> &attributes,
bool readonly)
{
gcc_assert (type);
@@ -789,7 +792,19 @@ global_new_decl (location *loc,
if (loc)
set_tree_location (inner, loc);
- set_variable_string_attribute (attributes, inner);
+ set_variable_string_attribute (string_attributes, inner);
+
+ tree var_attributes = NULL_TREE;
+ for (auto attr: attributes)
+ {
+ const char* attribute = variable_attribute_to_string (attr);
+ if (attribute)
+ {
+ tree ident = get_identifier (attribute);
+ var_attributes = tree_cons (ident, NULL_TREE, var_attributes);
+ }
+ }
+ decl_attributes (&inner, var_attributes, 0);
return inner;
}
@@ -836,11 +851,13 @@ new_global (location *loc,
const char *name,
enum global_var_flags flags,
const std::vector<std::pair<gcc_jit_variable_attribute,
- std::string>> &attributes,
+ std::string>> &string_attributes,
+ const std::vector<gcc_jit_variable_attribute> &attributes,
bool readonly)
{
tree inner =
- global_new_decl (loc, kind, type, name, flags, attributes, readonly);
+ global_new_decl (loc, kind, type, name, flags, string_attributes,
+ attributes, readonly);
return global_finalize_lvalue (inner);
}
@@ -987,10 +1004,13 @@ new_global_initialized (location *loc,
const char *name,
enum global_var_flags flags,
const std::vector<std::pair<gcc_jit_variable_attribute,
- std::string>> &attributes,
+ std::string>> &string_attributes,
+ const std::vector<gcc_jit_variable_attribute>
+ &attributes,
bool readonly)
{
- tree inner = global_new_decl (loc, kind, type, name, flags, attributes, readonly);
+ tree inner = global_new_decl (loc, kind, type, name, flags,
+ string_attributes, attributes, readonly);
vec<constructor_elt, va_gc> *constructor_elements = NULL;
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 07dab6fa389..e1088409d33 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -139,7 +139,8 @@ public:
const char *name,
enum global_var_flags flags,
const std::vector<std::pair<gcc_jit_variable_attribute,
- std::string>> &attributes,
+ std::string>> &string_attributes,
+ const std::vector<gcc_jit_variable_attribute> &attributes,
bool readonly);
lvalue *
@@ -154,6 +155,8 @@ public:
const std::vector<std::pair<
gcc_jit_variable_attribute,
std::string>>
+ &string_attributes,
+ const std::vector<gcc_jit_variable_attribute>
&attributes,
bool readonly);
@@ -375,7 +378,8 @@ private:
const char *name,
enum global_var_flags flags,
const std::vector<std::pair<gcc_jit_variable_attribute,
- std::string>> &attributes,
+ std::string>> &string_attributes,
+ const std::vector<gcc_jit_variable_attribute> &attributes,
bool readonly);
lvalue *
global_finalize_lvalue (tree inner);
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index 2f4ecc31825..c0b9afe5c5b 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -4285,6 +4285,12 @@ void recording::lvalue::add_string_attribute (
m_string_attributes.push_back (std::make_pair (attribute, std::string (value)));
}
+void recording::lvalue::add_attribute (
+ gcc_jit_variable_attribute attribute)
+{
+ m_attributes.push_back (attribute);
+}
+
/* The implementation of class gcc::jit::recording::param. */
/* Implementation of pure virtual hook recording::memento::replay_into
@@ -5278,6 +5284,7 @@ recording::global::replay_into (replayer *r)
playback_string (m_name),
m_flags,
m_string_attributes,
+ m_attributes,
m_readonly)
: r->new_global (playback_location (r, m_loc),
m_kind,
@@ -5285,6 +5292,7 @@ recording::global::replay_into (replayer *r)
playback_string (m_name),
m_flags,
m_string_attributes,
+ m_attributes,
m_readonly);
if (m_tls_model != GCC_JIT_TLS_MODEL_NONE)
@@ -5353,6 +5361,13 @@ recording::global::write_to_dump (dump &d)
if (attribute)
d.write ("__attribute(%s(\"%s\"))__\n", attribute, value.c_str());
}
+ for (auto name: m_attributes)
+ {
+ const char* attribute = variable_attribute_to_string (name);
+
+ if (attribute)
+ d.write ("__attribute (%s)__\n", attribute);
+ }
d.write ("%s %s",
m_type->get_debug_string (),
get_debug_string ());
@@ -5425,6 +5440,7 @@ static const char * const tls_model_enum_strings[] = {
static const char * const gcc_jit_variable_attribute_enum_strings[] = {
"GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY",
+ "GCC_JIT_VARIABLE_ATTRIBUTE_WEAK",
};
void
@@ -5462,6 +5478,10 @@ recording::global::write_reproducer (reproducer &r)
gcc_jit_variable_attribute_enum_strings[std::get<0>(attribute)],
std::get<1>(attribute).c_str());
+ for (auto attribute: m_attributes)
+ r.write (" gcc_jit_lvalue_add_attribute (%s, %s);\n", id,
+ gcc_jit_variable_attribute_enum_strings[attribute]);
+
if (m_readonly)
r.write (" gcc_jit_global_set_readonly (%s /* gcc_jit_lvalue *lvalue */);\n",
id);
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 4d41faa0446..e7d4d79cfe7 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -1439,7 +1439,8 @@ public:
m_reg_name (NULL),
m_tls_model (GCC_JIT_TLS_MODEL_NONE),
m_alignment (0),
- m_string_attributes ()
+ m_string_attributes (),
+ m_attributes ()
{}
playback::lvalue *
@@ -1461,6 +1462,7 @@ public:
const char *access_as_rvalue (reproducer &r) override;
void add_string_attribute (gcc_jit_variable_attribute attribute, const char* value);
+ void add_attribute (gcc_jit_variable_attribute attribute);
bool get_readonly () const
{
@@ -1488,6 +1490,7 @@ protected:
unsigned m_alignment;
std::vector<std::pair<gcc_jit_variable_attribute,
std::string>> m_string_attributes;
+ std::vector<gcc_jit_variable_attribute> m_attributes;
bool m_readonly = false;
};
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 33369447074..01e9f2875cd 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -4603,6 +4603,24 @@ gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
gcc::jit::recording::extended_asm::set_volatile_flag, in
jit-recording.cc. */
+void
+gcc_jit_lvalue_add_attribute (gcc_jit_lvalue *variable,
+ gcc_jit_variable_attribute attribute)
+{
+ RETURN_IF_FAIL (variable, NULL, NULL, "NULL variable");
+ RETURN_IF_FAIL (variable->is_global () || variable->is_local (),
+ NULL,
+ NULL,
+ "variable should be a variable");
+ RETURN_IF_FAIL ((attribute >= 0
+ && attribute < GCC_JIT_VARIABLE_ATTRIBUTE_MAX),
+ NULL,
+ NULL,
+ "attribute should be a `gcc_jit_variable_attribute` enum value");
+
+ variable->add_attribute (attribute);
+}
+
void
gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
int flag)
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index a5855100793..6628e619d8b 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -2199,6 +2199,7 @@ gcc_jit_function_add_integer_array_attribute (
enum gcc_jit_variable_attribute
{
GCC_JIT_VARIABLE_ATTRIBUTE_VISIBILITY,
+ GCC_JIT_VARIABLE_ATTRIBUTE_WEAK,
/* Maximum value of this enum, should always be last. */
GCC_JIT_VARIABLE_ATTRIBUTE_MAX,
@@ -2210,6 +2211,13 @@ gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
enum gcc_jit_variable_attribute attribute,
const char* value);
+/* Add an attribute to a variable. */
+extern void
+gcc_jit_lvalue_add_attribute (gcc_jit_lvalue *variable,
+ enum gcc_jit_variable_attribute attribute);
+
+#define LIBGCCJIT_HAVE_gcc_jit_lvalue_add_attribute
+
extern void
gcc_jit_context_set_output_ident (gcc_jit_context *ctxt,
const char* output_ident);
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 4662ca4b3c0..3cc51810554 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -334,3 +334,8 @@ 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_lvalue_add_attribute;
+} 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 4aa18e3b767..f72c1ccd131 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -474,6 +474,9 @@
/* test-weak-attribute.c: This can't be in the testcases array as it
doesn't have a verify_code implementation. */
+/* test-weak-var-attribute.c: This can't be in the testcases array as it
+ doesn't have a verify_code implementation. */
+
/* test-vector-perm.c */
#define create_code create_code_vector_perm
#define verify_code verify_code_vector_perm
diff --git a/gcc/testsuite/jit.dg/test-weak-var-attribute.c b/gcc/testsuite/jit.dg/test-weak-var-attribute.c
new file mode 100644
index 00000000000..2c1dc96556c
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-weak-var-attribute.c
@@ -0,0 +1,31 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#define TEST_COMPILING_TO_FILE
+#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER
+#define OUTPUT_FILENAME "output-of-test-weak-var-attribute.c.s"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+__attribute__ ((weak))
+int var;
+ */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_lvalue *variable =
+ gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, int_type,
+ "my_var");
+ gcc_jit_lvalue_add_attribute (variable, GCC_JIT_VARIABLE_ATTRIBUTE_WEAK);
+}
+
+/* { dg-final { jit-verify-output-file-was-created "" } } */
+/* Check that the attribute was applied correctly */
+/* { dg-final { jit-verify-assembler-output ".weak\\s+my_var" { target { ! *-*-darwin* } } } } */