mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 10:40:56 +08:00
decl.c (compatible_signatures_p): New function.
* decl.c (compatible_signatures_p): New function. The intended purpose is to check if two function signatures for a call-site and a callee are compatible enough for the call to be valid. The underlying purpose is to check if a call to a mapped builtin is using the right interface. The current code actually does not check antyhing - this a placeholder for future refinements. (gnat_to_gnu_entity) <E_Subprogram_Call>: Add preliminary bits to handle builtin calls for convention Intrinsic. * gigi.h (builtin_decl_for): Declare (new function). * utils.c (gnat_install_builtins): Install the target specific builtins. (builtin_decl_for): New function, provide a dummy body for now. From-SVN: r92833
This commit is contained in:
parent
ddda9d0f19
commit
c5e12904bc
@ -101,7 +101,8 @@ static void set_rm_size (Uint, tree, Entity_Id);
|
||||
static tree make_type_from_size (tree, tree, bool);
|
||||
static unsigned int validate_alignment (Uint, Entity_Id, unsigned int);
|
||||
static void check_ok_for_atomic (tree, Entity_Id, bool);
|
||||
|
||||
static int compatible_signatures_p (tree ftype1, tree ftype2);
|
||||
|
||||
/* Given GNAT_ENTITY, an entity in the incoming GNAT tree, return a
|
||||
GCC type corresponding to that entity. GNAT_ENTITY is assumed to
|
||||
refer to an Ada type. */
|
||||
@ -3242,6 +3243,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
corresponding to that field. This list will be saved in the
|
||||
TYPE_CI_CO_LIST field of the FUNCTION_TYPE node we create. */
|
||||
tree gnu_return_list = NULL_TREE;
|
||||
/* If an import pragma asks to map this subprogram to a GCC builtin,
|
||||
this is the builtin DECL node. */
|
||||
tree gnu_builtin_decl = NULL_TREE;
|
||||
Entity_Id gnat_param;
|
||||
bool inline_flag = Is_Inlined (gnat_entity);
|
||||
bool public_flag = Is_Public (gnat_entity);
|
||||
@ -3283,6 +3287,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If this subprogram is expectedly bound to a GCC builtin, fetch the
|
||||
corresponding DECL node.
|
||||
|
||||
We still want the parameter associations to take place because the
|
||||
proper generation of calls depends on it (a GNAT parameter without
|
||||
a corresponding GCC tree has a very specific meaning), so we don't
|
||||
just break here. */
|
||||
if (Convention (gnat_entity) == Convention_Intrinsic)
|
||||
gnu_builtin_decl = builtin_decl_for (gnu_ext_name);
|
||||
|
||||
/* ??? What if we don't find the builtin node above ? warn ? err ?
|
||||
In the current state we neither warn nor err, and calls will just
|
||||
be handled as for regular subprograms. */
|
||||
|
||||
if (kind == E_Function || kind == E_Subprogram_Type)
|
||||
gnu_return_type = gnat_to_gnu_type (Etype (gnat_entity));
|
||||
|
||||
@ -3378,9 +3396,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
bool copy_in_copy_out_flag = false;
|
||||
bool req_by_copy = false, req_by_ref = false;
|
||||
|
||||
/* See if a Mechanism was supplied that forced this
|
||||
/* Builtins are expanded inline and there is no real call sequence
|
||||
involved. so the type expected by the underlying expander is
|
||||
always the type of each argument "as is". */
|
||||
if (gnu_builtin_decl)
|
||||
req_by_copy = 1;
|
||||
|
||||
/* Otherwise, see if a Mechanism was supplied that forced this
|
||||
parameter to be passed one way or another. */
|
||||
if (Is_Valued_Procedure (gnat_entity) && parmnum == 0)
|
||||
else if (Is_Valued_Procedure (gnat_entity) && parmnum == 0)
|
||||
req_by_copy = true;
|
||||
else if (Mechanism (gnat_param) == Default)
|
||||
;
|
||||
@ -3638,6 +3662,23 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
|
||||
Sloc_to_locus (Sloc (gnat_entity), &input_location);
|
||||
|
||||
/* If we have a builtin decl for that function, check the signatures
|
||||
compatibilities. If the signatures are compatible, use the builtin
|
||||
decl. If they are not, we expect the checker predicate to have
|
||||
posted the appropriate errors, and just continue with what we have
|
||||
so far. */
|
||||
if (gnu_builtin_decl)
|
||||
{
|
||||
tree gnu_builtin_type = TREE_TYPE (gnu_builtin_decl);
|
||||
|
||||
if (compatible_signatures_p (gnu_type, gnu_builtin_type))
|
||||
{
|
||||
gnu_decl = gnu_builtin_decl;
|
||||
gnu_type = gnu_builtin_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there was no specified Interface_Name and the external and
|
||||
internal names of the subprogram are the same, only use the
|
||||
internal name to allow disambiguation of nested subprograms. */
|
||||
@ -6210,6 +6251,34 @@ check_ok_for_atomic (tree object, Entity_Id gnat_entity, bool comp_p)
|
||||
gnat_error_point, gnat_entity);
|
||||
}
|
||||
|
||||
/* Check if FTYPE1 and FTYPE2, two potentially different function type nodes,
|
||||
have compatible signatures so that a call using one type may be safely
|
||||
issued if the actual target function type is the other. Return 1 if it is
|
||||
the case, 0 otherwise, and post errors on the incompatibilities.
|
||||
|
||||
This is used when an Ada subprogram is mapped onto a GCC builtin, to ensure
|
||||
that calls to the subprogram will have arguments suitable for the later
|
||||
underlying builtin expansion. */
|
||||
|
||||
static int
|
||||
compatible_signatures_p (tree ftype1, tree ftype2)
|
||||
{
|
||||
/* As of now, we only perform very trivial tests and consider it's the
|
||||
programmer's responsability to ensure the type correctness in the Ada
|
||||
declaration, as in the regular Import cases.
|
||||
|
||||
Mismatches typically result in either error messages from the builtin
|
||||
expander, internal compiler errors, or in a real call sequence. This
|
||||
should be refined to issue diagnostics helping error detection and
|
||||
correction. */
|
||||
|
||||
/* Almost fake test, ensuring a use of each argument. */
|
||||
if (ftype1 == ftype2)
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Given a type T, a FIELD_DECL F, and a replacement value R, return a new type
|
||||
with all size expressions that contain F updated by replacing F with R.
|
||||
This is identical to GCC's substitute_in_type except that it knows about
|
||||
|
@ -687,6 +687,11 @@ extern bool gnat_mark_addressable (tree);
|
||||
extern tree builtin_function (const char *, tree, int, enum built_in_class,
|
||||
const char *, tree);
|
||||
|
||||
/* Search the chain of currently reachable declarations for a builtin
|
||||
FUNCTION_DECL node corresponding to function NAME (an IDENTIFIER_NODE).
|
||||
Return the first node found, if any, or NULL_TREE otherwise. */
|
||||
extern tree builtin_decl_for (tree);
|
||||
|
||||
/* This function is called by the front end to enumerate all the supported
|
||||
modes for the machine. We pass a function which is called back with
|
||||
the following integer parameters:
|
||||
|
@ -509,6 +509,9 @@ gnat_install_builtins ()
|
||||
ftype = build_function_type (ptr_void_type_node, tmp);
|
||||
gnat_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
|
||||
"alloca", false);
|
||||
|
||||
/* Target specific builtins, such as the AltiVec family on ppc. */
|
||||
targetm.init_builtins ();
|
||||
}
|
||||
|
||||
/* Create the predefined scalar types such as `integer_type_node' needed
|
||||
@ -3305,6 +3308,17 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Search the chain of currently reachable declarations for a builtin
|
||||
FUNCTION_DECL node corresponding to function NAME (an IDENTIFIER_NODE).
|
||||
Return the first node found, if any, or NULL_TREE otherwise. */
|
||||
tree
|
||||
builtin_decl_for (tree name __attribute__ ((unused)))
|
||||
{
|
||||
/* ??? not clear yet how to implement this function in tree-ssa, so
|
||||
return NULL_TREE for now */
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
#include "gt-ada-utils.h"
|
||||
#include "gtype-ada.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user