summaryrefslogtreecommitdiff
path: root/gcc/ada/layout.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/layout.adb')
-rw-r--r--gcc/ada/layout.adb100
1 files changed, 92 insertions, 8 deletions
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb
index 2cf97cb2fb8..8245e9556d7 100644
--- a/gcc/ada/layout.adb
+++ b/gcc/ada/layout.adb
@@ -8,7 +8,7 @@
-- --
-- $Revision$
-- --
--- Copyright (C) 2001 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2002 Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -171,6 +171,12 @@ package body Layout is
-- E are set (either from previously given values, or from the newly
-- computed values, as appropriate).
+ procedure Set_Composite_Alignment (E : Entity_Id);
+ -- This procedure is called for record types and subtypes, and also for
+ -- atomic array types and subtypes. If no alignment is set, and the size
+ -- is 2 or 4 (or 8 if the word size is 8), then the alignment is set to
+ -- match the size.
+
----------------------------
-- Adjust_Esize_Alignment --
----------------------------
@@ -930,16 +936,21 @@ package body Layout is
Insert_Typ := E;
end if;
- -- Cannot do anything if Esize of component type unknown
+ -- Deal with component size if base type
- if Unknown_Esize (Ctyp) then
- return;
- end if;
+ if Ekind (E) = E_Array_Type then
+
+ -- Cannot do anything if Esize of component type unknown
+
+ if Unknown_Esize (Ctyp) then
+ return;
+ end if;
- -- Set component size if not set already
+ -- Set component size if not set already
- if Unknown_Component_Size (E) then
- Set_Component_Size (E, Esize (Ctyp));
+ if Unknown_Component_Size (E) then
+ Set_Component_Size (E, Esize (Ctyp));
+ end if;
end if;
-- (RM 13.3 (48)) says that the size of an unconstrained array
@@ -2263,9 +2274,30 @@ package body Layout is
if Frontend_Layout_On_Target then
if Is_Array_Type (E) and then not Is_Bit_Packed_Array (E) then
Layout_Array_Type (E);
+ return;
elsif Is_Record_Type (E) then
Layout_Record_Type (E);
+ return;
end if;
+
+ -- Special remaining processing for record types with a known size
+ -- of 16, 32, or 64 bits whose alignment is not yet set. For these
+ -- types, we set a corresponding alignment matching the size if
+ -- possible, or as large as possible if not.
+
+ elsif Is_Record_Type (E) and not Debug_Flag_Q then
+ Set_Composite_Alignment (E);
+
+ -- For arrays, we only do this processing for arrays that are
+ -- required to be atomic. Here, we really need to have proper
+ -- alignment, but for the normal case of non-atomic arrays it
+ -- seems better to use the component alignment as the default.
+
+ elsif Is_Array_Type (E)
+ and then Is_Atomic (E)
+ and then not Debug_Flag_Q
+ then
+ Set_Composite_Alignment (E);
end if;
end Layout_Type;
@@ -2379,6 +2411,58 @@ package body Layout is
end if;
end Set_And_Check_Static_Size;
+ -----------------------------
+ -- Set_Composite_Alignment --
+ -----------------------------
+
+ procedure Set_Composite_Alignment (E : Entity_Id) is
+ Siz : Uint;
+ Align : Nat;
+
+ begin
+ if Unknown_Alignment (E) then
+ if Known_Static_Esize (E) then
+ Siz := Esize (E);
+
+ elsif Unknown_Esize (E)
+ and then Known_Static_RM_Size (E)
+ then
+ Siz := RM_Size (E);
+
+ else
+ return;
+ end if;
+
+ -- Size is known, alignment is not set
+
+ if Siz = System_Storage_Unit then
+ Align := 1;
+ elsif Siz = 2 * System_Storage_Unit then
+ Align := 2;
+ elsif Siz = 4 * System_Storage_Unit then
+ Align := 4;
+ elsif Siz = 8 * System_Storage_Unit then
+ Align := 8;
+ else
+ return;
+ end if;
+
+ if Align > Maximum_Alignment then
+ Align := Maximum_Alignment;
+ end if;
+
+ if Align > System_Word_Size / System_Storage_Unit then
+ Align := System_Word_Size / System_Storage_Unit;
+ end if;
+
+ Set_Alignment (E, UI_From_Int (Align));
+
+ if Unknown_Esize (E) then
+ Set_Esize (E, UI_From_Int (Align * System_Storage_Unit));
+ end if;
+ end if;
+ end Set_Composite_Alignment;
+
--------------------------
-- Set_Discrete_RM_Size --
--------------------------