Commit 8dc10d38 by Arnaud Charlet

[multiple changes]

2009-05-06  Robert Dewar  <dewar@adacore.com>

	* freeze.adb (Freeze_Record_Type): Implement Implicit_Packing for
	records

	* gnat_rm.texi:
	Add documentation for pragma Implicit_Packing applied to record
	types.

2009-05-06  Ed Schonberg  <schonberg@adacore.com>

	* sem.adb (Walk_Library_Items): Place all with_clauses of an
	instantiation on the spec, because late instance bodies may generate
	with_clauses for the instance body but are inserted in the instance
	spec.

From-SVN: r147158
parent 3249690d
2009-05-06 Robert Dewar <dewar@adacore.com>
* freeze.adb (Freeze_Record_Type): Implement Implicit_Packing for
records
* gnat_rm.texi:
Add documentation for pragma Implicit_Packing applied to record
types.
2009-05-06 Ed Schonberg <schonberg@adacore.com>
* sem.adb (Walk_Library_Items): Place all with_clauses of an
instantiation on the spec, because late instance bodies may generate
with_clauses for the instance body but are inserted in the instance
spec.
2009-05-06 Emmanuel Briot <briot@adacore.com> 2009-05-06 Emmanuel Briot <briot@adacore.com>
* prj-nmsc.adb (Locate_Directory): Remove unused parameters, and add * prj-nmsc.adb (Locate_Directory): Remove unused parameters, and add
......
----------------------------------------------------------------------------- ------------------------------------------------------------------------------
-- -- -- --
-- GNAT COMPILER COMPONENTS -- -- GNAT COMPILER COMPONENTS --
-- -- -- --
...@@ -1545,7 +1545,16 @@ package body Freeze is ...@@ -1545,7 +1545,16 @@ package body Freeze is
Placed_Component : Boolean := False; Placed_Component : Boolean := False;
-- Set True if we find at least one component with a component -- Set True if we find at least one component with a component
-- clause (used to warn about useless Bit_Order pragmas). -- clause (used to warn about useless Bit_Order pragmas, and also
-- to detect cases where Implicit_Packing may have an effect).
All_Scalar_Components : Boolean := True;
-- Set False if we encounter a component of a non-scalar type
Scalar_Component_Total_RM_Size : Uint := Uint_0;
Scalar_Component_Total_Esize : Uint := Uint_0;
-- Accumulates total RM_Size values and total Esize values of all
-- scalar components. Used for processing of Implicit_Packing.
function Check_Allocator (N : Node_Id) return Node_Id; function Check_Allocator (N : Node_Id) return Node_Id;
-- If N is an allocator, possibly wrapped in one or more level of -- If N is an allocator, possibly wrapped in one or more level of
...@@ -1855,6 +1864,19 @@ package body Freeze is ...@@ -1855,6 +1864,19 @@ package body Freeze is
end; end;
end if; end if;
-- Processing for possible Implicit_Packing later
if Implicit_Packing then
if not Is_Scalar_Type (Etype (Comp)) then
All_Scalar_Components := False;
else
Scalar_Component_Total_RM_Size :=
Scalar_Component_Total_RM_Size + RM_Size (Etype (Comp));
Scalar_Component_Total_Esize :=
Scalar_Component_Total_Esize + Esize (Etype (Comp));
end if;
end if;
-- If the component is an Itype with Delayed_Freeze and is either -- If the component is an Itype with Delayed_Freeze and is either
-- a record or array subtype and its base type has not yet been -- a record or array subtype and its base type has not yet been
-- frozen, we must remove this from the entity list of this -- frozen, we must remove this from the entity list of this
...@@ -2061,7 +2083,7 @@ package body Freeze is ...@@ -2061,7 +2083,7 @@ package body Freeze is
-- Finally, enforce the restriction that access attributes with a -- Finally, enforce the restriction that access attributes with a
-- current instance prefix can only apply to limited types. -- current instance prefix can only apply to limited types.
if Ekind (Rec) = E_Record_Type then if Ekind (Rec) = E_Record_Type then
if Present (Corresponding_Remote_Type (Rec)) then if Present (Corresponding_Remote_Type (Rec)) then
Freeze_And_Append Freeze_And_Append
(Corresponding_Remote_Type (Rec), Loc, Result); (Corresponding_Remote_Type (Rec), Loc, Result);
...@@ -2163,6 +2185,18 @@ package body Freeze is ...@@ -2163,6 +2185,18 @@ package body Freeze is
end if; end if;
end; end;
end if; end if;
-- Apply implicit packing if all conditions are met
if Implicit_Packing
and then Has_Size_Clause (Rec)
and then All_Scalar_Components
and then not Has_Discriminants (Rec)
and then Esize (Rec) < Scalar_Component_Total_Esize
and then Esize (Rec) >= Scalar_Component_Total_RM_Size
then
Set_Is_Packed (Rec);
end if;
end Freeze_Record_Type; end Freeze_Record_Type;
-- Start of processing for Freeze_Entity -- Start of processing for Freeze_Entity
......
...@@ -2409,7 +2409,8 @@ pragma Implicit_Packing; ...@@ -2409,7 +2409,8 @@ pragma Implicit_Packing;
@noindent @noindent
This is a configuration pragma that requests implicit packing for packed This is a configuration pragma that requests implicit packing for packed
arrays for which a size clause is given but no explicit pragma Pack or arrays for which a size clause is given but no explicit pragma Pack or
specification of Component_Size is present. Consider this example: specification of Component_Size is present. It also applies to records
where no record representation clause is present. Consider this example:
@smallexample @c ada @smallexample @c ada
type R is array (0 .. 7) of Boolean; type R is array (0 .. 7) of Boolean;
...@@ -2431,6 +2432,21 @@ specify the exact size that corresponds to the length of the array multiplied ...@@ -2431,6 +2432,21 @@ specify the exact size that corresponds to the length of the array multiplied
by the size in bits of the component type. by the size in bits of the component type.
@cindex Array packing @cindex Array packing
Similarly, the following example shows the use in the record case
@smallexample @c ada
type r is record
a, b, c, d, e, f, g, h : boolean;
chr : character;
end record;
for r'size use 16;
@end smallexample
@noindent
Without a pragma Pack, each Boolean field requires 8 bits, so the
minimum size is 72 bits, but with a pragma Pack, 16 bits would be
sufficient. The use of pragma Implciit_Packing allows this record
declaration to compile without an explicit pragma Pack.
@node Pragma Import_Exception @node Pragma Import_Exception
@unnumberedsec Pragma Import_Exception @unnumberedsec Pragma Import_Exception
@cindex OpenVMS @cindex OpenVMS
......
...@@ -1760,7 +1760,7 @@ package body Sem is ...@@ -1760,7 +1760,7 @@ package body Sem is
-- If it's a body, then ignore it, unless it's an instance (in -- If it's a body, then ignore it, unless it's an instance (in
-- which case we do the spec), or it's the main unit (in which -- which case we do the spec), or it's the main unit (in which
-- case we do it). Note that it could be both, in which case we -- case we do it). Note that it could be both, in which case we
-- do the spec first. -- do the with_clauses of spec and body first,
when N_Package_Body | N_Subprogram_Body => when N_Package_Body | N_Subprogram_Body =>
declare declare
...@@ -1783,7 +1783,15 @@ package body Sem is ...@@ -1783,7 +1783,15 @@ package body Sem is
if Is_Generic_Instance (Entity) then if Is_Generic_Instance (Entity) then
declare declare
Spec_Unit : constant Node_Id := Library_Unit (CU); Spec_Unit : constant Node_Id := Library_Unit (CU);
begin begin
-- Move context of body to that of spec, so it
-- appears before the spec itself, in case it
-- contains nested instances that generate late
-- with_clauses that got attached to the body.
Append_List
(Context_Items (CU), Context_Items (Spec_Unit));
Do_Unit_And_Dependents Do_Unit_And_Dependents
(Spec_Unit, Unit (Spec_Unit)); (Spec_Unit, Unit (Spec_Unit));
end; end;
......
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