Commit 0d0cd281 by Eric Botcazou Committed by Pierre-Marie de Rodat

[Ada] Support for C99 and C++ standard boolean types

This change the type Interfaces.C.Extensions.bool to be fully compatible
with the C99 and C++ standard boolean types by making it a fully-fledged
boolean type with convention C.

The following C+Ada program must compile quietly in LTO mode:

bool b;

struct S {};

bool foo (struct S *s) { return true; }

pragma Ada_2005;
pragma Style_Checks (Off);

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Extensions;

package t_c is

   b : aliased Extensions.bool;  -- t.c:3
   pragma Import (C, b, "b");

   type S is record
      null;
   end record;
   pragma Convention (C_Pass_By_Copy, S);  -- t.c:5

   function foo (the_s : access S) return Extensions.bool;  -- t.c:7
   pragma Import (C, foo, "foo");

end t_c;

with t_c; use t_c;

procedure P_C is

  Dummy : aliased S;

begin
  b := foo (Dummy'Access);
end;

2018-05-25  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* freeze.adb (Freeze_Enumeration_Type): Do not give integer size to a
	boolean type with convention C.
	* libgnat/i-cexten.ads (bool): Change to boolean with convention C.
	* gcc-interface/decl.c (gnat_to_gnu_entity): Add new local variable
	FOREIGN and use it throughout the function.
	<E_Enumeration_Type>: Set precision 1 on boolean types with foreign
	convention.
	<E_Enumeration_Subtype>: Likewise for subtypes.
	<E_Record_Type>: Force the size of a storage unit on empty classes.
	* gcc-interface/utils.c (make_type_from_size) <BOOLEAN_TYPE>: Skip
	boolean types with precision 1 if the size is the expected one.

From-SVN: r260721
parent 28e33720
2018-05-25 Eric Botcazou <ebotcazou@adacore.com>
* freeze.adb (Freeze_Enumeration_Type): Do not give integer size to a
boolean type with convention C.
* libgnat/i-cexten.ads (bool): Change to boolean with convention C.
* gcc-interface/decl.c (gnat_to_gnu_entity): Add new local variable
FOREIGN and use it throughout the function.
<E_Enumeration_Type>: Set precision 1 on boolean types with foreign
convention.
<E_Enumeration_Subtype>: Likewise for subtypes.
<E_Record_Type>: Force the size of a storage unit on empty classes.
* gcc-interface/utils.c (make_type_from_size) <BOOLEAN_TYPE>: Skip
boolean types with precision 1 if the size is the expected one.
2018-05-25 Arnaud Charlet <charlet@adacore.com>
* pprint.adb (Expression_Name): Do not print non ASCII characters.
......
......@@ -6877,12 +6877,15 @@ package body Freeze is
procedure Freeze_Enumeration_Type (Typ : Entity_Id) is
begin
-- By default, if no size clause is present, an enumeration type with
-- Convention C is assumed to interface to a C enum, and has integer
-- size. This applies to types. For subtypes, verify that its base
-- type has no size clause either. Treat other foreign conventions
-- in the same way, and also make sure alignment is set right.
-- Convention C is assumed to interface to a C enum and has integer
-- size, except for a boolean type because it is assumed to interface
-- to _Bool introduced in C99. This applies to types. For subtypes,
-- verify that its base type has no size clause either. Treat other
-- foreign conventions in the same way, and also make sure alignment
-- is set right.
if Has_Foreign_Convention (Typ)
and then not Is_Boolean_Type (Typ)
and then not Has_Size_Clause (Typ)
and then not Has_Size_Clause (Base_Type (Typ))
and then Esize (Typ) < Standard_Integer_Size
......
......@@ -282,6 +282,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* True if this entity is to be considered as imported. */
const bool imported_p
= (Is_Imported (gnat_entity) && No (Address_Clause (gnat_entity)));
/* True if this entity has a foreign convention. */
const bool foreign = Has_Foreign_Convention (gnat_entity);
/* For a type, contains the equivalent GNAT node to be used in gigi. */
Entity_Id gnat_equiv_type = Empty;
/* Temporary used to walk the GNAT tree. */
......@@ -658,8 +660,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
}
/* Get the type after elaborating the renamed object. */
if (Has_Foreign_Convention (gnat_entity)
&& Is_Descendant_Of_Address (Underlying_Type (gnat_type)))
if (foreign && Is_Descendant_Of_Address (Underlying_Type (gnat_type)))
gnu_type = ptr_type_node;
else
{
......@@ -1594,6 +1595,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
tree gnu_list = NULL_TREE;
Entity_Id gnat_literal;
/* Boolean types with foreign convention have precision 1. */
if (is_boolean && foreign)
esize = 1;
gnu_type = make_node (is_boolean ? BOOLEAN_TYPE : ENUMERAL_TYPE);
TYPE_PRECISION (gnu_type) = esize;
TYPE_UNSIGNED (gnu_type) = is_unsigned;
......@@ -1774,6 +1779,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
esize = UI_To_Int (RM_Size (gnat_entity));
/* Boolean types with foreign convention have precision 1. */
if (Is_Boolean_Type (gnat_entity) && foreign)
{
gnu_type = make_node (BOOLEAN_TYPE);
TYPE_PRECISION (gnu_type) = 1;
TYPE_UNSIGNED (gnu_type) = 1;
set_min_and_max_values_for_integral_type (gnu_type, 1, UNSIGNED);
layout_type (gnu_type);
}
/* First subtypes of Character are treated as Character; otherwise
this should be an unsigned type if the base type is unsigned or
if the lower bound is constant and non-negative or if the type
......@@ -1783,7 +1797,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
conversions to it and gives more leeway to the optimizer; but
this means that we will need to explicitly test for this case
when we change the representation based on the RM size. */
if (kind == E_Enumeration_Subtype
else if (kind == E_Enumeration_Subtype
&& No (First_Literal (Etype (gnat_entity)))
&& Esize (gnat_entity) == RM_Size (gnat_entity)
&& esize == CHAR_TYPE_SIZE
......@@ -1808,8 +1822,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
gnat_entity, "U", definition, true,
debug_info_p));
TYPE_BIASED_REPRESENTATION_P (gnu_type)
= Has_Biased_Representation (gnat_entity);
if (TREE_CODE (gnu_type) == INTEGER_TYPE)
TYPE_BIASED_REPRESENTATION_P (gnu_type)
= Has_Biased_Representation (gnat_entity);
/* Do the same processing for Character subtypes as for types. */
if (TYPE_STRING_FLAG (TREE_TYPE (gnu_type)))
......@@ -3300,6 +3315,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
all_rep ? NULL_TREE : bitsize_zero_node,
NULL);
/* Empty classes have the size of a storage unit in C++. */
if (TYPE_SIZE (gnu_type) == bitsize_zero_node
&& Convention (gnat_entity) == Convention_CPP)
{
TYPE_SIZE (gnu_type) = bitsize_unit_node;
TYPE_SIZE_UNIT (gnu_type) = size_one_node;
compute_record_mode (gnu_type);
}
/* If there are entities in the chain corresponding to components
that we did not elaborate, ensure we elaborate their types if
they are Itypes. */
......@@ -3966,8 +3990,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* If we should request stack realignment for a foreign convention
subprogram, do so. Note that this applies to task entry points
in particular. */
if (FOREIGN_FORCE_REALIGN_STACK
&& Has_Foreign_Convention (gnat_entity))
if (FOREIGN_FORCE_REALIGN_STACK && foreign)
prepend_one_attribute
(&attr_list, ATTR_MACHINE_ATTRIBUTE,
get_identifier ("force_align_arg_pointer"), NULL_TREE,
......
......@@ -1133,9 +1133,15 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
switch (TREE_CODE (type))
{
case BOOLEAN_TYPE:
/* Do not mess with boolean types that have foreign convention. */
if (TYPE_PRECISION (type) == 1 && TYPE_SIZE (type) == size_tree)
break;
/* ... fall through ... */
case INTEGER_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
biased_p = (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (type));
......
......@@ -56,7 +56,8 @@ package Interfaces.C.Extensions is
-- C bool
subtype bool is plain_char;
type bool is new Boolean;
pragma Convention (C, bool);
-- 64-bit integer types
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment