aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2015-03-12 14:24:48 +0000
committerOlivier Hainque <hainque@gcc.gnu.org>2015-03-12 14:24:48 +0000
commitb72dfb6e2240c888132e10b769880b6a0ad12430 (patch)
treedf8905e8b80a1654ac38cb2c45731e31b75f8a95 /gcc/ada
parentad1cabfcc545a2074556368ce1e6e8923ce3b59f (diff)
downloadgcc-b72dfb6e2240c888132e10b769880b6a0ad12430.zip
gcc-b72dfb6e2240c888132e10b769880b6a0ad12430.tar.gz
gcc-b72dfb6e2240c888132e10b769880b6a0ad12430.tar.bz2
trans.c (Attribute_to_gnu): On targets where a function symbol designates a function descriptor...
2015-03-12 Olivier Hainque <hainque@adacore.com> * gcc-interface/trans.c (Attribute_to_gnu) <Code_Address case>: On targets where a function symbol designates a function descriptor, fetch the function code address from the descriptor. From-SVN: r221391
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/gcc-interface/trans.c29
2 files changed, 34 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9dc33a7..848f84a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-12 Olivier Hainque <hainque@adacore.com>
+
+ * gcc-interface/trans.c (Attribute_to_gnu) <Code_Address case>:
+ On targets where a function symbol designates a function descriptor,
+ fetch the function code address from the descriptor.
+
2015-03-04 Robert Dewar <dewar@adacore.com>
* sem_warn.adb: Minor reformatting.
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 070acbe..2b5485f 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -155,6 +155,14 @@ struct GTY(()) language_function {
#define f_gnat_ret \
DECL_STRUCT_FUNCTION (current_function_decl)->language->gnat_ret
+/* Expected to be defined from the tm headers, though not always available.
+ 0 indicates that function symbols designate function descriptors on the
+ target so we don't need to use runtime descriptors of our own. */
+
+#ifndef USE_RUNTIME_DESCRIPTORS
+#define USE_RUNTIME_DESCRIPTORS (-1)
+#endif
+
/* A structure used to gather together information about a statement group.
We use this to gather related statements, for example the "then" part
of a IF. In the case where it represents a lexical scope, we may also
@@ -1725,13 +1733,32 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
gnu_result_type, gnu_prefix);
/* For 'Code_Address, find an inner ADDR_EXPR and mark it so that we
- don't try to build a trampoline. */
+ don't try to build a trampoline. Then if the function address
+ denotes a function descriptor on this target, fetch the code address
+ from the descriptor. */
if (attribute == Attr_Code_Address)
{
gnu_expr = remove_conversions (gnu_result, false);
if (TREE_CODE (gnu_expr) == ADDR_EXPR)
TREE_NO_TRAMPOLINE (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
+
+ /* On targets on which function symbols denote a function
+ descriptor, the code address is always stored within the
+ first slot of the descriptor. */
+
+ if (USE_RUNTIME_DESCRIPTORS == 0)
+ {
+ /* result = * ((result_type *) result),
+ where we expect result to be of some pointer type already. */
+
+ const tree result_ptr_type
+ = build_pointer_type (gnu_result_type);
+
+ gnu_result = build_unary_op
+ (INDIRECT_REF, gnu_result_type,
+ convert (result_ptr_type, gnu_result));
+ }
}
/* For 'Access, issue an error message if the prefix is a C++ method