mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-24 08:50:26 +08:00
exp_disp.adb (Expand_Dispatching_Call): Propagate the convention on the designated subprogram type and also set...
* exp_disp.adb (Expand_Dispatching_Call): Propagate the convention on the designated subprogram type and also set Is_Dispatch_Table_Entity. (Expand_Interface_Thunk): Propagate the convention on the thunk. (Set_CPP_Constructors_Old): Set Is_Constructor and Convention_CPP on the internal view of the constructors. (Set_CPP_Constructors): Likewise. * sem_prag.adb (Analyze_Pragma) <Pragma_CPP_Constructor>: Set the convention on the function. * gcc-interface/gigi.h (is_cplusplus_method): Declare. * gcc-interface/decl.c (Has_Thiscall_Convention): New macro. (gnat_to_gnu_entity) <E_Subprogram_Type>: Test it to set the `thiscall' calling convention (get_minimal_subprog_decl): Likewise. (is_cplusplus_method): New predicate. * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Access>: Issue an error on access to C++ constructor or member function. From-SVN: r189199
This commit is contained in:
parent
d4d05b5247
commit
28dd005525
@ -1,3 +1,22 @@
|
||||
2012-07-03 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* exp_disp.adb (Expand_Dispatching_Call): Propagate the convention on
|
||||
the designated subprogram type and also set Is_Dispatch_Table_Entity.
|
||||
(Expand_Interface_Thunk): Propagate the convention on the thunk.
|
||||
(Set_CPP_Constructors_Old): Set Is_Constructor and Convention_CPP on
|
||||
the internal view of the constructors.
|
||||
(Set_CPP_Constructors): Likewise.
|
||||
* sem_prag.adb (Analyze_Pragma) <Pragma_CPP_Constructor>: Set the
|
||||
convention on the function.
|
||||
* gcc-interface/gigi.h (is_cplusplus_method): Declare.
|
||||
* gcc-interface/decl.c (Has_Thiscall_Convention): New macro.
|
||||
(gnat_to_gnu_entity) <E_Subprogram_Type>: Test it to set the `thiscall'
|
||||
calling convention
|
||||
(get_minimal_subprog_decl): Likewise.
|
||||
(is_cplusplus_method): New predicate.
|
||||
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Access>: Issue an
|
||||
error on access to C++ constructor or member function.
|
||||
|
||||
2012-07-03 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/utils.c (gnat_pushdecl): Set TYPE_CONTEXT for types
|
||||
|
@ -803,6 +803,11 @@ package body Exp_Disp is
|
||||
Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
|
||||
Set_Etype (Subp_Typ, Res_Typ);
|
||||
Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
|
||||
Set_Convention (Subp_Typ, Convention (Subp));
|
||||
|
||||
-- Notify gigi that the designated type is a dispatching primitive
|
||||
|
||||
Set_Is_Dispatch_Table_Entity (Subp_Typ);
|
||||
|
||||
-- Create a new list of parameters which is a copy of the old formal
|
||||
-- list including the creation of a new set of matching entities.
|
||||
@ -1850,6 +1855,7 @@ package body Exp_Disp is
|
||||
|
||||
Thunk_Id := Make_Temporary (Loc, 'T');
|
||||
Set_Is_Thunk (Thunk_Id);
|
||||
Set_Convention (Thunk_Id, Convention (Prim));
|
||||
|
||||
-- Procedure case
|
||||
|
||||
@ -8468,8 +8474,9 @@ package body Exp_Disp is
|
||||
|
||||
Set_Init_Proc (Typ, Init);
|
||||
Set_Is_Imported (Init);
|
||||
Set_Is_Constructor (Init);
|
||||
Set_Interface_Name (Init, Interface_Name (E));
|
||||
Set_Convention (Init, Convention_C);
|
||||
Set_Convention (Init, Convention_CPP);
|
||||
Set_Is_Public (Init);
|
||||
Set_Has_Completion (Init);
|
||||
end if;
|
||||
@ -8562,8 +8569,9 @@ package body Exp_Disp is
|
||||
Parameter_Specifications => Parms));
|
||||
|
||||
Set_Is_Imported (Constructor_Id);
|
||||
Set_Is_Constructor (Constructor_Id);
|
||||
Set_Interface_Name (Constructor_Id, Interface_Name (E));
|
||||
Set_Convention (Constructor_Id, Convention_C);
|
||||
Set_Convention (Constructor_Id, Convention_CPP);
|
||||
Set_Is_Public (Constructor_Id);
|
||||
Set_Has_Completion (Constructor_Id);
|
||||
|
||||
|
@ -50,19 +50,23 @@
|
||||
#include "ada-tree.h"
|
||||
#include "gigi.h"
|
||||
|
||||
/* Convention_Stdcall should be processed in a specific way on 32 bits
|
||||
Windows targets only. The macro below is a helper to avoid having to
|
||||
check for a Windows specific attribute throughout this unit. */
|
||||
/* "stdcall" and "thiscall" conventions should be processed in a specific way
|
||||
on 32-bit x86/Windows only. The macros below are helpers to avoid having
|
||||
to check for a Windows specific attribute throughout this unit. */
|
||||
|
||||
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
|
||||
#ifdef TARGET_64BIT
|
||||
#define Has_Stdcall_Convention(E) \
|
||||
(!TARGET_64BIT && Convention (E) == Convention_Stdcall)
|
||||
#define Has_Thiscall_Convention(E) \
|
||||
(!TARGET_64BIT && is_cplusplus_method (E))
|
||||
#else
|
||||
#define Has_Stdcall_Convention(E) (Convention (E) == Convention_Stdcall)
|
||||
#define Has_Thiscall_Convention(E) (is_cplusplus_method (E))
|
||||
#endif
|
||||
#else
|
||||
#define Has_Stdcall_Convention(E) 0
|
||||
#define Has_Thiscall_Convention(E) 0
|
||||
#endif
|
||||
|
||||
/* Stack realignment is necessary for functions with foreign conventions when
|
||||
@ -4413,6 +4417,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|
||||
(&attr_list, ATTR_MACHINE_ATTRIBUTE,
|
||||
get_identifier ("stdcall"), NULL_TREE,
|
||||
gnat_entity);
|
||||
else if (Has_Thiscall_Convention (gnat_entity))
|
||||
prepend_one_attribute_to
|
||||
(&attr_list, ATTR_MACHINE_ATTRIBUTE,
|
||||
get_identifier ("thiscall"), NULL_TREE,
|
||||
gnat_entity);
|
||||
|
||||
/* If we should request stack realignment for a foreign convention
|
||||
subprogram, do so. Note that this applies to task entry points in
|
||||
@ -5276,6 +5285,10 @@ get_minimal_subprog_decl (Entity_Id gnat_entity)
|
||||
prepend_one_attribute_to (&attr_list, ATTR_MACHINE_ATTRIBUTE,
|
||||
get_identifier ("stdcall"), NULL_TREE,
|
||||
gnat_entity);
|
||||
else if (Has_Thiscall_Convention (gnat_entity))
|
||||
prepend_one_attribute_to (&attr_list, ATTR_MACHINE_ATTRIBUTE,
|
||||
get_identifier ("thiscall"), NULL_TREE,
|
||||
gnat_entity);
|
||||
|
||||
if (No (Interface_Name (gnat_entity)) && gnu_ext_name == gnu_entity_name)
|
||||
gnu_ext_name = NULL_TREE;
|
||||
@ -5285,6 +5298,39 @@ get_minimal_subprog_decl (Entity_Id gnat_entity)
|
||||
false, true, true, true, attr_list, gnat_entity);
|
||||
}
|
||||
|
||||
/* Return whether the E_Subprogram_Type/E_Function/E_Procedure GNAT_ENTITY is
|
||||
a C++ imported method or equivalent.
|
||||
|
||||
We use the predicate on 32-bit x86/Windows to find out whether we need to
|
||||
use the "thiscall" calling convention for GNAT_ENTITY. This convention is
|
||||
used for C++ methods (functions with METHOD_TYPE) by the back-end. */
|
||||
|
||||
bool
|
||||
is_cplusplus_method (Entity_Id gnat_entity)
|
||||
{
|
||||
if (Convention (gnat_entity) != Convention_CPP)
|
||||
return False;
|
||||
|
||||
/* This is the main case: C++ method imported as a primitive operation. */
|
||||
if (Is_Dispatching_Operation (gnat_entity))
|
||||
return True;
|
||||
|
||||
/* A thunk needs to be handled like its associated primitive operation. */
|
||||
if (Is_Subprogram (gnat_entity) && Is_Thunk (gnat_entity))
|
||||
return True;
|
||||
|
||||
/* C++ classes with no virtual functions can be imported as limited
|
||||
record types, but we need to return true for the constructors. */
|
||||
if (Is_Constructor (gnat_entity))
|
||||
return True;
|
||||
|
||||
/* This is set on the E_Subprogram_Type built for a dispatching call. */
|
||||
if (Is_Dispatch_Table_Entity (gnat_entity))
|
||||
return True;
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Finalize the processing of From_With_Type incomplete types. */
|
||||
|
||||
void
|
||||
|
@ -116,6 +116,10 @@ extern tree get_unpadded_type (Entity_Id gnat_entity);
|
||||
alias is already present, in which case it is returned instead. */
|
||||
extern tree get_minimal_subprog_decl (Entity_Id gnat_entity);
|
||||
|
||||
/* Return whether the E_Subprogram_Type/E_Function/E_Procedure GNAT_ENTITY is
|
||||
a C++ imported method or equivalent. */
|
||||
extern bool is_cplusplus_method (Entity_Id gnat_entity);
|
||||
|
||||
/* Create a record type that contains a SIZE bytes long field of TYPE with a
|
||||
starting bit position so that it is aligned to ALIGN bits, and leaving at
|
||||
least ROOM bytes free before the field. BASE_ALIGN is the alignment the
|
||||
|
@ -1424,6 +1424,15 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
|
||||
TREE_NO_TRAMPOLINE (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;
|
||||
}
|
||||
|
||||
/* For 'Access, issue an error message if the prefix is a C++ method
|
||||
since it can use a special calling convention on some platforms,
|
||||
which cannot be propagated to the access type. */
|
||||
else if (attribute == Attr_Access
|
||||
&& Nkind (Prefix (gnat_node)) == N_Identifier
|
||||
&& is_cplusplus_method (Entity (Prefix (gnat_node))))
|
||||
post_error ("access to C++ constructor or member function not allowed",
|
||||
gnat_node);
|
||||
|
||||
/* For other address attributes applied to a nested function,
|
||||
find an inner ADDR_EXPR and annotate it so that we can issue
|
||||
a useful warning with -Wtrampolines. */
|
||||
|
@ -7865,6 +7865,7 @@ package body Sem_Prag is
|
||||
|
||||
Set_Has_Completion (Def_Id);
|
||||
Set_Is_Constructor (Def_Id);
|
||||
Set_Convention (Def_Id, Convention_CPP);
|
||||
|
||||
-- Imported C++ constructors are not dispatching primitives
|
||||
-- because in C++ they don't have a dispatch table slot.
|
||||
|
Loading…
x
Reference in New Issue
Block a user