Committed to dmalcolm/jit:
gcc/jit/
* TODO.rst ("the C unary prefix "&" operator"): Remove completed item.
* internal-api.c (gcc::jit::lvalue::get_address): New.
* internal-api.h (gcc::jit::lvalue::get_address): New.
* libgccjit.c (gcc_jit_lvalue_get_address): New.
* libgccjit.h (gcc_jit_lvalue_get_address): New.
* libgccjit.map (gcc_jit_lvalue_get_address): New.
gcc/testsuite/
* jit.dg/test-expressions.c (test_global): New.
(make_test_of_get_address): New.
(verify_get_address): New.
(code_making_callback): Add call to make_test_of_get_address.
(verify_code): Add call to verify_get_address.
---
gcc/jit/ChangeLog.jit | 9 ++++++
gcc/jit/TODO.rst | 5 ---
gcc/jit/internal-api.c | 13 ++++++++
gcc/jit/internal-api.h | 3 ++
gcc/jit/libgccjit.c | 9 ++++++
gcc/jit/libgccjit.h | 7 +++++
gcc/jit/libgccjit.map | 1 +
gcc/testsuite/ChangeLog.jit | 8 +++++
gcc/testsuite/jit.dg/test-expressions.c | 54 +++++++++++++++++++++++++++++++++
9 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 7c574e8..e16902d 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,12 @@
+2013-10-21 David Malcolm <[email protected]>
+
+ * TODO.rst ("the C unary prefix "&" operator"): Remove completed item.
+ * internal-api.c (gcc::jit::lvalue::get_address): New.
+ * internal-api.h (gcc::jit::lvalue::get_address): New.
+ * libgccjit.c (gcc_jit_lvalue_get_address): New.
+ * libgccjit.h (gcc_jit_lvalue_get_address): New.
+ * libgccjit.map (gcc_jit_lvalue_get_address): New.
+
2013-10-18 David Malcolm <[email protected]>
* internal-api.c (gcc::jit::context::new_param): Add context
diff --git a/gcc/jit/TODO.rst b/gcc/jit/TODO.rst
index 41cc4ad..d0daeb4 100644
--- a/gcc/jit/TODO.rst
+++ b/gcc/jit/TODO.rst
@@ -55,11 +55,6 @@ Initial Release
and, indeed, clarify all of the other operations.
-* the C unary prefix "&" operator::
-
- extern gcc_jit_rvalue *
- gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue);
-
* array types, in case they're needed for structs::
extern gcc_jit_type *
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 81178e1..8f84e14 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -757,6 +757,19 @@ dereference (gcc::jit::location *loc)
return new lvalue (get_context (), datum);
}
+gcc::jit::rvalue *
+gcc::jit::lvalue::
+get_address (location *loc)
+{
+ tree t_lvalue = as_tree ();
+ tree t_thistype = TREE_TYPE (t_lvalue);
+ tree t_ptrtype = build_pointer_type (t_thistype);
+ tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
+ if (loc)
+ get_context ()->set_tree_location (ptr, loc);
+ return new rvalue (get_context (), ptr);
+}
+
void *
gcc::jit::wrapper::
operator new (size_t sz)
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index e31dbc8..1a8499f 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -422,6 +422,9 @@ public:
access_field (location *loc,
const char *fieldname);
+ rvalue *
+ get_address (location *loc);
+
};
class param : public lvalue
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 023c213..8d77761 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -529,6 +529,15 @@ gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
return (gcc_jit_lvalue *)rvalue->dereference (loc);
}
+gcc_jit_rvalue *
+gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
+ gcc_jit_location *loc)
+{
+ RETURN_NULL_IF_FAIL (lvalue, NULL, "NULL lvalue");
+
+ return (gcc_jit_rvalue *)lvalue->get_address (loc);
+}
+
gcc_jit_lvalue *
gcc_jit_function_new_local (gcc_jit_function *func,
gcc_jit_location *loc,
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 2187ede..12a715d 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -601,6 +601,13 @@ extern gcc_jit_lvalue *
gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
gcc_jit_location *loc);
+/* Taking the address of an lvalue; analogous to:
+ &(EXPR)
+ in C. */
+extern gcc_jit_rvalue *
+gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
+ gcc_jit_location *loc);
+
extern gcc_jit_lvalue *
gcc_jit_function_new_local (gcc_jit_function *func,
gcc_jit_location *loc,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 7700788..e2503e4 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -41,6 +41,7 @@
gcc_jit_loop_end;
gcc_jit_lvalue_as_rvalue;
gcc_jit_lvalue_access_field;
+ gcc_jit_lvalue_get_address;
gcc_jit_param_as_lvalue;
gcc_jit_param_as_rvalue;
gcc_jit_result_get_code;
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 987353d..7190e09 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,11 @@
+2013-10-21 David Malcolm <[email protected]>
+
+ * jit.dg/test-expressions.c (test_global): New.
+ (make_test_of_get_address): New.
+ (verify_get_address): New.
+ (code_making_callback): Add call to make_test_of_get_address.
+ (verify_code): Add call to verify_get_address.
+
2013-10-18 David Malcolm <[email protected]>
* jit.dg/test-expressions.c: New.
diff --git a/gcc/testsuite/jit.dg/test-expressions.c
b/gcc/testsuite/jit.dg/test-expressions.c
index 91103f8..aaaf394 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -492,6 +492,58 @@ verify_dereferences (gcc_jit_result *result)
}
/**********************************************************************
+ gcc_jit_lvalue_get_address
+ **********************************************************************/
+
+int test_global;
+static void
+make_test_of_get_address (gcc_jit_context *ctxt)
+{
+ /*
+ void *test_get_address (void)
+ {
+ return &test_global;
+ }
+ */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_lvalue *test_global =
+ gcc_jit_context_new_global (
+ ctxt,
+ NULL,
+ int_type,
+ "test_global");
+
+ gcc_jit_type *void_ptr_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+
+ gcc_jit_function *test_get_address =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_ptr_type,
+ "test_get_address",
+ 0, NULL,
+ 0);
+ gcc_jit_function_add_return (
+ test_get_address,
+ NULL,
+ gcc_jit_lvalue_get_address (
+ test_global,
+ NULL));
+}
+
+static void
+verify_get_address (gcc_jit_result *result)
+{
+ typedef void *(*test_fn) (void);
+ test_fn test_get_address =
+ (test_fn)gcc_jit_result_get_code (result,
+ "test_get_address");
+ CHECK_NON_NULL (test_get_address);
+ CHECK_VALUE (test_get_address (), &test_global);
+}
+
+/**********************************************************************
Code for harness
**********************************************************************/
@@ -502,6 +554,7 @@ code_making_callback (gcc_jit_context *ctxt, void
*user_data)
make_tests_of_binary_ops (ctxt);
make_tests_of_comparisons (ctxt);
make_tests_of_dereferences (ctxt);
+ make_test_of_get_address (ctxt);
return 0;
}
@@ -515,4 +568,5 @@ verify_code (gcc_jit_result *result)
verify_binary_ops (result);
verify_comparisons (result);
verify_dereferences (result);
+ verify_get_address (result);
}
--
1.7.11.7