DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦17c02c53f⟧ Ada Source

    Length: 48128 (0xbc00)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Size_Utilities, seg_00462f

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦5a81ac88f⟧ »Space Info Vol 1« 
        └─⟦this⟧ 

E3 Source Code



with Io;
with Lrm_Utilities;
with Sizing_Parameters;
use Sizing_Parameters;
with String_Utilities;
with Representation_Clauses;
with Names_And_Expressions;
with Bounds_Utilities;
with Declarations;
with Ada_Program;
with Type_Information;
with Lrm_Renames;
use Lrm_Renames;
package body Size_Utilities is

    function Static_Value
                (Expression : Ada_Program.Expression) return Long_Integer
        renames Lrm_Utilities.Static_Value;

    function Static_Value (Expression : Ada_Program.Expression) return Float
        renames Lrm_Utilities.Static_Value;

    function "=" (Left, Right : Types.Type_Definition_Kinds) return Boolean
        renames Types."=";

    function "=" (Left, Right : Ada.Element) return Boolean renames Ada."=";

    procedure Size (Ref_Id             : Ada_Program.Identifier_Reference :=
                       Ada_Program.Nil_Element;
                    Ignore_Rep_Clauses : Boolean;
                    Original           : Type_Information.Type_Definition;
                    Constraint         : Type_Information.Type_Constraint;
                    Result             : out Long_Natural;
                    Requires_Alignment : in out Boolean;
                    Static             : in out Boolean);

    procedure Size (For_Type           : Type_Information.Type_Definition;
                    Ignore_Rep_Clauses : Boolean;
                    Result             : out Long_Natural;
                    Requires_Alignment : in out Boolean;
                    Static             : in out Boolean);

    function Round_Up_To_Alignment
                (Exact_Size : Long_Natural; Alignment : Long_Natural)
                return Long_Natural is
    begin
        if Exact_Size mod Alignment = 0 then
            return Exact_Size;
        else
            return ((Exact_Size / Alignment) + 1) * Alignment;
        end if;
    end Round_Up_To_Alignment;

    procedure Expression_Value (Of_Expression :     Ada.Element;
                                Result        : out Long_Natural;
                                Static        : out Boolean) is
    begin
        Result := Static_Value (Of_Expression);
        Static := True;
    exception
        when Lrm_Utilities.Not_Static =>
            Result := 0;
            Static := False;
    end Expression_Value;

    procedure Access_Size (Of_Access :        Types.Type_Definition;
                           Result    : out    Long_Natural;
                           Static    : in out Boolean) is

        Storage_Size : Names_And_Expressions.Expression;
    begin
--        Storage_Size := Rep_Specs.Associated_Storage_Size (Of_Access);
-- could be used to compute the collection size

        Result := Access_Type_Size;
        Static := True;
    end Access_Size;


    function Size_Of_Dimension
                (Lower_Bound, Upper_Bound : Long_Integer) return Long_Natural is
        Size : Long_Natural;
    begin
        Size := Upper_Bound - Lower_Bound + 1;
        return Size;
    exception
        when Constraint_Error =>
            return 0;
        when Numeric_Error =>
            return 0;
    end Size_Of_Dimension;

    procedure Record_Rep_Spec_Size (Rep_Spec :        Ada.Element;
                                    Result   : out    Long_Natural;
                                    Static   : in out Boolean) is
        Components : Ada.Element_Iterator;  
        Component : Ada.Element;
        Current_Offset : Long_Natural := 0;
        Current_Size, Max_Size : Long_Natural := 0;
        Ubound, Lbound : Long_Integer := 0;
        Non_Static_Lbound, Non_Static_Ubound : Ada.Element;
    begin
        Components := Rep_Specs.Clause_Components (Rep_Spec);

        while not Ada.Done (Components) loop       -- iterate through component
                                                   -- rep specs
            Component := Ada.Value (Components);

            if Rep_Specs.Valid_Component (Component) then

                Expression_Value (Rep_Specs.Component_Offset (Component),
                                  Current_Offset, Static);
                Bounds_Utilities.Find_Range
                   (Rep_Specs.Component_Range (Component), Lbound, Ubound,
                    Static, Non_Static_Lbound, Non_Static_Ubound);

                Current_Size := Current_Offset * Bytes + Ubound + 1;

                if Current_Size > Max_Size then  -- multiple offsets with
                                                 -- different ranges
                    Max_Size := Current_Size;
                end if;
            end if;
            Ada.Next (Components);
        end loop;

        Result := Max_Size;
    end Record_Rep_Spec_Size;


    function Get_Referenced_Enum_Literal
                (Constraint : Ada.Element) return Ada.Element is
    begin
        case Names_And_Expressions.Kind (Constraint) is
            when Names_And_Expressions.An_Enumeration_Literal =>
                return Ada.Definition (Constraint);
            when others =>
                return Ada.Nil_Element;
        end case;
    end Get_Referenced_Enum_Literal;

    function Choice_Matches_Constraint
                (Choices : Ada.Element_Iterator; Constraint : Ada.Element)
                return Boolean is
        Local_Choices : Ada.Element_Iterator := Choices;
        Choice        : Ada.Element;
    begin
        if Ada.Is_Nil (Constraint) then
            return False;
        end if;

        while not Ada.Done (Local_Choices) loop
            Choice := Ada.Value (Local_Choices);
            case Type_Information.Choice_Kind (Choice) is
                when Type_Information.A_Simple_Expression =>
                    null;
                when Type_Information.A_Discrete_Range =>
                    null;
                when Type_Information.Others_Choice =>
                    null;
                    -- return True;  could be if all others implemented
                when Type_Information.An_Identifier_Reference =>
                    return Ada.Definition (Choice) =
                              Get_Referenced_Enum_Literal (Constraint);
                when Type_Information.Not_A_Choice =>
                    return False;
            end case;
            Ada.Next (Local_Choices);
        end loop;

        return False;
    end Choice_Matches_Constraint;

    procedure Component_List_Size
                 (Components         : in out Ada.Element_Iterator;
                  Ignore_Rep_Clauses :        Boolean;
                  With_Constraints   :        Type_Information.Type_Constraint;
                  Result             : out    Long_Natural;
                  Requires_Alignment : in out Boolean;
                  Static             : in out Boolean) is

        -- compute the total size of all components

        Component, Component_Type            : Ada.Element;
        Current_Size, Temp_Size, Accume_Size : Long_Natural := 0;

        Inner_Components, Variant_Items : Ada.Element_Iterator;
        Component_Requires_Alignment : Boolean;
        Variant_Component_Requires_Alignment : Boolean;
        Variant : Ada.Element;
        Variant_Choices : Ada.Element_Iterator;

        Number_Of_Id_Decls : Long_Natural := 1;
    begin
        Requires_Alignment := False;
        while not Ada.Done (Components) loop
            Component := Ada.Value (Components);

            Current_Size := 0;
            case Types.Component_Kind (Component) is
                when Types.A_Variable_Component =>
                    Number_Of_Ids (Component, Number_Of_Id_Decls);

                    Component_Type := Declarations.Object_Type (Component);
                    Size (Component_Type, Ignore_Rep_Clauses, Current_Size,
                          Component_Requires_Alignment, Static);



                when Types.A_Variant_Part_Component =>
                    -- compute the size of the largest variant
                    -- unless constraint selects a variant

                    Variant_Items := Types.Variant_Item_List (Component);
                    while not Ada.Done (Variant_Items) loop
                        Variant         := Ada.Value (Variant_Items);
                        Variant_Choices :=
                           Type_Information.Variant_Choices (Variant);

                        Inner_Components :=
                           Types.Inner_Record_Components (Variant);

                        Component_List_Size
                           (Inner_Components, Ignore_Rep_Clauses,
                            With_Constraints, Temp_Size,
                            Variant_Component_Requires_Alignment, Static);

                        if Static then
                            if Choice_Matches_Constraint
                                  (Variant_Choices, With_Constraints) then
                                Current_Size := Temp_Size;

                                Component_Requires_Alignment :=
                                   Variant_Component_Requires_Alignment;

                                exit;  -- this variant is selected by the
                                       -- constraint
                            elsif Temp_Size > Current_Size then
                                Current_Size := Temp_Size;

                                Component_Requires_Alignment :=
                                   Variant_Component_Requires_Alignment;

                            end if;
                        else
                            Result := 0;
                            return;
                        end if;
                        Ada.Next (Variant_Items);
                    end loop;

                when Types.A_Null_Component =>
                    Current_Size := 0;
                    Static       := True;

                when Types.Not_A_Component =>
                    Result := 0;
                    Static := False;
                    return;
            end case;

            if Static then
                if Component_Requires_Alignment then
                    Requires_Alignment := True;
                    Accume_Size        :=
                       Current_Size +
                          Number_Of_Id_Decls *
                             Round_Up_To_Alignment
                                (Accume_Size, Record_Component_Alignment);
                else
                    Accume_Size := Accume_Size +
                                      (Number_Of_Id_Decls * Current_Size);
                end if;
            else
                Result := 0;
                return;
            end if;

            Ada.Next (Components);
        end loop;

        Result := Accume_Size;

    end Component_List_Size;

    function Has_Default_Values
                (Discriminants : Ada.Element_Iterator) return Boolean is
        Local        : Ada.Element_Iterator := Discriminants;
        Discriminant : Ada.Element;
    begin
        while not Ada.Done (Local) loop
            Discriminant := Ada.Value (Local);
            if Lrm_Utilities.Is_Initialized (Discriminant) then
                return True;
            end if;

            Ada.Next (Local);
        end loop;
        return False;
    end Has_Default_Values;

    procedure Record_Size (Of_Record : Type_Information.Type_Definition;
                           Ignore_Rep_Clauses : Boolean;
                           With_Constraints : Type_Information.Type_Constraint;
                           Result : out Long_Natural;
                           Requires_Alignment : in out Boolean;
                           Static : in out Boolean) is
        Record_Components : Ada.Element_Iterator;
        Rep_Spec          : Ada.Element;
    begin
        Rep_Spec := Rep_Specs.Associated_Record_Representation (Of_Record);

        if Ignore_Rep_Clauses or else Ada.Is_Nil (Rep_Spec) then

            Record_Components := Types.Record_Components (Of_Record);

            if Type_Information.Is_Discriminated (Of_Record) and then
               Has_Default_Values
                  (Type_Information.Discriminants (Of_Record)) then

                Component_List_Size (Components         => Record_Components,
                                     Ignore_Rep_Clauses => Ignore_Rep_Clauses,
                                     With_Constraints   => Ada.Nil_Element,
                                     Result             => Result,
                                     Requires_Alignment => Requires_Alignment,
                                     Static             => Static);

            else
                Component_List_Size (Components         => Record_Components,
                                     Ignore_Rep_Clauses => Ignore_Rep_Clauses,
                                     With_Constraints   => With_Constraints,
                                     Result             => Result,
                                     Requires_Alignment => Requires_Alignment,
                                     Static             => Static);
            end if;

        else
            Record_Rep_Spec_Size (Rep_Spec, Result, Static);
            Requires_Alignment := False;
        end if;
    end Record_Size;

    procedure Number_Of_Elements
                 (Index_Constraints :        Ada_Program.Element_Iterator;
                  Count             : out    Long_Natural;
                  Static            : in out Boolean) is
        Indices          : Ada.Element_Iterator := Index_Constraints;
        Index_Constraint : Types.Subtype_Indication;

        Lower_Expression, Upper_Expression : Types.Expression;
        Lower, Upper : Long_Integer;
        Total_Elements : Long_Natural := 1;

    begin  
        Static := True;

        while not Ada.Done (Indices) loop

            Index_Constraint := Ada.Value (Indices);

            Bounds_Utilities.Find_Range (Index_Constraint, Lower, Upper, Static,
                                         Lower_Expression, Upper_Expression);
            exit when not Static;

            Total_Elements := Total_Elements * Size_Of_Dimension (Lower, Upper);
            Ada.Next (Indices);
        end loop;

        Count := Total_Elements;
    end Number_Of_Elements;

    function Is_Character (Type_Def : Types.Type_Definition) return Boolean is
        Last : Ada.Element := Types.Last_Constraint (Type_Def);
    begin
        return String_Utilities.Equal (Ada.Image (Last), "CHARACTER") or else
                  String_Utilities.Equal
                     (Declarations.Name (Ada.Parent (Last)), "CHARACTER");
    end Is_Character;

    function Is_Boolean (Type_Def : Types.Type_Definition) return Boolean is
        Last : Ada.Element := Types.Last_Constraint (Type_Def);
    begin
        return String_Utilities.Equal (Ada.Image (Last), "BOOLEAN") or else
                  String_Utilities.Equal
                     (Declarations.Name (Ada.Parent (Last)), "BOOLEAN");

    end Is_Boolean;

    procedure Array_Size (Of_Array           : Type_Information.Type_Definition;
                          Ignore_Rep_Clauses : Boolean;  
                          Index_Constraints  : Ada_Program.Element_Iterator;
                          Result             : out Long_Natural;
                          Static             : in out Boolean) is
        Array_Elements       : Long_Natural;
        Array_Component_Type : Types.Type_Definition;
        Component_Size       : Long_Natural;
        Requires_Alignment   : Boolean := False;
    begin
        Result               := 0;
        Array_Component_Type := Types.Component_Type (Of_Array);

        if Is_Character (Array_Component_Type) then  -- string type
            Component_Size := Character_Size;
        elsif Is_Boolean (Array_Component_Type) then -- bit string
            Component_Size := Boolean_Size;
        else
            Size (For_Type           => Array_Component_Type,
                  Ignore_Rep_Clauses => Ignore_Rep_Clauses,
                  Result             => Component_Size,
                  Requires_Alignment => Requires_Alignment,
                  Static             => Static);

            Component_Size := Round_Up_To_Alignment
                                 (Component_Size, Array_Component_Alignment);
        end if;

        if Static then
            Number_Of_Elements (Index_Constraints, Array_Elements, Static);

            if Static then
                if Requires_Alignment then
                    Result := Array_Elements * Round_Up_To_Alignment
                                                  (Component_Size,
                                                   Record_Component_Alignment);
                else
                    Result := Array_Elements * Component_Size;
                end if;
            end if;
        end if;

    end Array_Size;

    procedure Find_Fixed_Constraints
                 (Ref_Id : Ada.Identifier_Reference := Ada.Nil_Element;
                  Root : Types.Type_Definition;
                  First : Types.Type_Constraint;
                  Range_Constraint : out Types.Type_Constraint;
                  Delta_Constraint : out Types.Type_Constraint) is
        Got_Range, Got_Delta : Boolean := False;
        Element              : Ada.Element;

        procedure Process_Constraint (Current : Types.Type_Constraint) is
        begin
            case Types.Constraint_Kind (Current) is
                when Types.A_Simple_Range | Types.A_Range_Attribute =>
                    if not Got_Range then
                        Range_Constraint := Current;
                        Got_Range        := True;
                    end if;

                when Types.A_Fixed_Point_Constraint =>
                    if not Got_Delta then
                        Delta_Constraint := Current;
                        Got_Delta        := True;
                    end if;

                    if not Got_Range and then
                       not Ada.Is_Nil (Types.Fixed_Point_Constraint
                                          (Current)) then
                        Range_Constraint :=
                           Types.Fixed_Point_Constraint (Current);
                        Got_Range        := True;
                    end if;

                when others =>
                    null;
            end case;
        end Process_Constraint;
    begin
        Range_Constraint := Ada.Nil_Element;
        Delta_Constraint := Ada.Nil_Element;
        Element          := Ref_Id;

        Process_Constraint (First);

        while not Got_Range or else not Got_Delta loop
            if Ada.Is_Nil (Element) then
                Process_Constraint (Types.Ground_Type (Root));
                exit;
            end if;

            Element := Ada.Definition (Element);  
            exit when Ada.Is_Nil (Element); -- For Generic Formal types.

            Element := Types.Last_Constraint
                          (Decls.Type_Specification (Element));

            case Types.Kind (Element) is
                when Types.A_Subtype_Indication =>
                    Process_Constraint (Types.Constraint (Element));
                when Types.A_Fixed_Type_Definition =>
                    Process_Constraint (Element);
                when others =>
                    exit;      -- shouldn't happen
            end case;

        end loop;
    end Find_Fixed_Constraints;

    procedure Size (For_Type           : Type_Information.Type_Definition;
                    Ignore_Rep_Clauses : Boolean;
                    Result             : out Long_Natural;
                    Requires_Alignment : in out Boolean;
                    Static             : in out Boolean) is

        Element : Ada.Element := Types.Last_Constraint (For_Type);

        Size_Expression : Ada_Program.Element;

        Ubound, Lbound : Long_Integer;
        U_Bound, L_Bound : Float;  
        Digits_Accuracy : Long_Natural;
        Constraint, Range_Constraint, Delta_Constraint : Types.Type_Constraint;

        Is_Packed : Boolean;
    begin
        Result             := 0;
        Requires_Alignment := False;
        loop

            if Ada.Is_Nil (Element) then
                Static := False;
                return;
            end if;
            Size_Expression := Rep_Specs.Associated_Size (Element);

            if Ignore_Rep_Clauses or else Ada.Is_Nil (Size_Expression) then

                case Types.Kind (Element) is
                    when Types.A_Subtype_Indication =>
                        Constraint := Types.Constraint (Element);

                        if Ada.Is_Nil (Constraint) then
                            -- Can't happen, LAST_CONSTRAINT returns
                            -- a constrained subtype or a base type ...
                            Static := False;
                            exit;
                        end if;

                        Size (Ref_Id             => Types.Type_Mark (Element),
                              Ignore_Rep_Clauses => Ignore_Rep_Clauses,
                              Original           => Element,
                              Constraint         => Constraint,
                              Result             => Result,
                              Requires_Alignment => Requires_Alignment,
                              Static             => Static);
                        exit;

                    when Types.An_Enumeration_Type_Definition =>
                        if Is_Character (Element) then
                            Result := Character_Size;
                            Static := True;
                        elsif Is_Boolean (Element) then
                            Result := Boolean_Size;
                            Static := True;
                        else
                            Bounds_Utilities.Enumeration_Range
                               (Element, Lbound, Ubound);
                            Result := Enumeration_Type_Size
                                         (Lbound, Ubound, Is_Packed);
                            Static := Ubound >= Lbound;
                        end if;
                        exit;
                    when Types.An_Integer_Type_Definition =>

                        Bounds_Utilities.Integer_Range_Constraint_Bounds
                           (Types.Integer_Constraint (Element),
                            Lbound, Ubound, Static);
                        if Static then
                            Result := Integer_Type_Size (Lbound, Ubound);
                        end if;
                        exit;
                    when Types.A_Float_Type_Definition =>
                        Bounds_Utilities.Float_Range_Constraint_Bounds
                           (Types.Floating_Point_Constraint (Element),
                            L_Bound, U_Bound, Static);
                        Expression_Value
                           (Types.Digits_Accuracy_Definition (Element),
                            Digits_Accuracy, Static);
                        if Static then
                            Result := Float_Type_Size
                                         (L_Bound, U_Bound, Digits_Accuracy);
                        end if;
                        exit;
                    when Types.A_Task_Type_Definition =>
                        Result             := Task_Type_Size;
                        Static             := True;
                        Requires_Alignment := True;
                        exit;

                    when Types.A_Fixed_Type_Definition =>
                        Find_Fixed_Constraints
                           (Root             => Element,
                            First            => Element,
                            Range_Constraint => Range_Constraint,
                            Delta_Constraint => Delta_Constraint);
                        Bounds_Utilities.Fixed_Range_Constraint_Bounds
                           (Delta_Constraint, Range_Constraint,
                            Lbound, Ubound, Static);
                        if Static then
                            Result := Integer_Type_Size
                                         (Lbound, Ubound, Is_Packed);
                            exit;

                        end if;
                    when Types.An_Array_Type_Definition =>
                        if Types.Is_Constrained_Array (Element) then
                            Array_Size (Element, Ignore_Rep_Clauses,
                                        Types.Index_Constraints (Element),
                                        Result, Static);
                        else
                            Result := 0;
                            Static := False;
                        end if;
                        exit;

                    when Types.An_Access_Type_Definition =>
                        Access_Size (Element, Result, Static);
                        Requires_Alignment := True;
                        exit;
                    when Types.A_Record_Type_Definition =>
                        Record_Size (Element, Ignore_Rep_Clauses,
                                     Ada_Program.Nil_Element, Result,
                                     Requires_Alignment, Static);
                        exit;

                    when Types.A_Derived_Type_Definition =>
                        Element := Types.Last_Constraint
                                      (Types.Derived_From (Element));
                        -- loop on type that was derived

                    when Types.A_Private_Type_Definition ..
                            Types.A_Limited_Private_Type_Definition =>
                        Element := Declarations.Enclosing_Declaration (Element);
                        Element := Ada_Program.Definition (Element);

                    when Types.Not_A_Type_Definition =>
                        Result := 0;
                        Static := False;
                        exit;
                end case;
            else
                Expression_Value (Size_Expression, Result, Static);
                return;
            end if;
        end loop;
    end Size;

    procedure Size (Ref_Id             : Ada_Program.Identifier_Reference :=
                       Ada_Program.Nil_Element;
                    Ignore_Rep_Clauses : Boolean;
                    Original           : Type_Information.Type_Definition;
                    Constraint         : Type_Information.Type_Constraint;
                    Result             : out Long_Natural;
                    Requires_Alignment : in out Boolean;
                    Static             : in out Boolean) is
        Ground : Types.Type_Definition := Types.Ground_Type (Original);
        Range_Constraint, Delta_Constraint : Types.Type_Constraint;
        Lbound, Ubound : Long_Integer;
        L_Bound, U_Bound : Float;
        Digits_Accuracy : Long_Natural;

        Is_Packed : Boolean;
    begin
        Requires_Alignment := False;
        case Types.Kind (Ground) is
            when Types.An_Enumeration_Type_Definition =>
                Bounds_Utilities.Enumeration_Range_Constraint_Bounds
                   (Constraint, Lbound, Ubound, Static);
                if Static then
                    Result := Enumeration_Type_Size (Lbound, Ubound, Is_Packed);
                else
                    Result := 0;               end if;

            when Types.An_Integer_Type_Definition =>
                Bounds_Utilities.Integer_Range_Constraint_Bounds
                   (Constraint, Lbound, Ubound, Static);
                if Static then
                    Result := Integer_Type_Size (Lbound, Ubound, Is_Packed);
                else
                    Result := 0;
                end if;

            when Types.A_Fixed_Type_Definition =>
                Find_Fixed_Constraints (Ref_Id           => Ref_Id,
                                        Root             => Constraint,
                                        First            => Constraint,
                                        Range_Constraint => Range_Constraint,
                                        Delta_Constraint => Delta_Constraint);
                Bounds_Utilities.Fixed_Range_Constraint_Bounds
                   (Delta_Constraint, Range_Constraint, Lbound, Ubound, Static);
                if Static then
                    Result := Integer_Type_Size (Lbound, Ubound, Is_Packed);
                else
                    Result := 0;
                end if;

            when Types.A_Float_Type_Definition =>
                Bounds_Utilities.Float_Range_Constraint_Bounds
                   (Constraint, L_Bound, U_Bound, Static);
                Expression_Value (Types.Digits_Accuracy_Definition (Ground),
                                  Digits_Accuracy, Static);
                if Static then
                    Result := Float_Type_Size
                                 (L_Bound, U_Bound, Digits_Accuracy);
                end if;

            when Types.An_Array_Type_Definition =>
                Array_Size (Ground, Ignore_Rep_Clauses,
                            Types.Discrete_Ranges (Constraint), Result, Static);

            when Types.A_Record_Type_Definition =>
                Record_Size (Ground, Ignore_Rep_Clauses, Constraint,
                             Result, Requires_Alignment, Static);

            when others =>
                -- Can't happen ...
                Result := 0;
                Static := False;
        end case;
    end Size;

    procedure Type_Size (For_Type : Type_Information.Type_Definition;
                         Ignore_Type_Representation_Clauses : Boolean := False;
                         Result : out Long_Natural;
                         Static : in out Boolean) is
        Exact_Size         : Long_Natural;
        Requires_Alignment : Boolean;
    begin
        Size (For_Type, Ignore_Type_Representation_Clauses,
              Exact_Size, Requires_Alignment, Static);
        Result := Exact_Size;
    end Type_Size;

    procedure Object_Size
                 (For_Object : Declarations.Object_Declaration;
                  Ignore_Type_Representation_Clauses : Boolean := False;
                  Result : out Long_Natural;
                  Static : in out Boolean) is
        Exact_Size         : Long_Natural;
        Requires_Alignment : Boolean;

        Number_Of_Id_Decls : Long_Natural;
    begin
        Number_Of_Ids (For_Object, Number_Of_Id_Decls);

        Size (Declarations.Object_Type (For_Object),  
              Ignore_Type_Representation_Clauses,
              Exact_Size, Requires_Alignment, Static);

        if Requires_Alignment then

            Result := Number_Of_Id_Decls *
                         Round_Up_To_Alignment (Exact_Size,
                                                Object_Declaration_Alignment);
        else
            Result := Number_Of_Id_Decls * Exact_Size;
        end if;
    end Object_Size;

    procedure Number_Of_Ids (Object :     Declarations.Object_Declaration;
                             Count  : out Long_Natural) is
        Ids   : Ada_Program.Element_List := Declarations.Identifiers (Object);
        Total : Long_Natural             := 0;
    begin
        while not Ada_Program.Done (Ids) loop
            Total := Total + 1;
            Ada_Program.Next (Ids);
        end loop;
        Count := Total;
    end Number_Of_Ids;
end Size_Utilities;

E3 Meta Data

    nblk1=2e
    nid=0
    hdr6=5c
        [0x00] rec0=20 rec1=00 rec2=01 rec3=030
        [0x01] rec0=17 rec1=00 rec2=02 rec3=020
        [0x02] rec0=1b rec1=00 rec2=03 rec3=096
        [0x03] rec0=1a rec1=00 rec2=04 rec3=00e
        [0x04] rec0=1b rec1=00 rec2=05 rec3=010
        [0x05] rec0=19 rec1=00 rec2=06 rec3=024
        [0x06] rec0=00 rec1=00 rec2=2e rec3=00e
        [0x07] rec0=17 rec1=00 rec2=07 rec3=022
        [0x08] rec0=18 rec1=00 rec2=08 rec3=01a
        [0x09] rec0=00 rec1=00 rec2=2d rec3=016
        [0x0a] rec0=17 rec1=00 rec2=09 rec3=046
        [0x0b] rec0=00 rec1=00 rec2=2c rec3=010
        [0x0c] rec0=17 rec1=00 rec2=0a rec3=050
        [0x0d] rec0=1e rec1=00 rec2=0b rec3=00c
        [0x0e] rec0=00 rec1=00 rec2=2b rec3=01a
        [0x0f] rec0=1a rec1=00 rec2=0c rec3=034
        [0x10] rec0=00 rec1=00 rec2=2a rec3=00e
        [0x11] rec0=15 rec1=00 rec2=0d rec3=06e
        [0x12] rec0=00 rec1=00 rec2=29 rec3=012
        [0x13] rec0=16 rec1=00 rec2=0e rec3=008
        [0x14] rec0=00 rec1=00 rec2=28 rec3=012
        [0x15] rec0=1c rec1=00 rec2=0f rec3=000
        [0x16] rec0=15 rec1=00 rec2=10 rec3=03a
        [0x17] rec0=00 rec1=00 rec2=27 rec3=038
        [0x18] rec0=17 rec1=00 rec2=11 rec3=064
        [0x19] rec0=18 rec1=00 rec2=12 rec3=02c
        [0x1a] rec0=00 rec1=00 rec2=26 rec3=01a
        [0x1b] rec0=1b rec1=00 rec2=13 rec3=036
        [0x1c] rec0=02 rec1=00 rec2=25 rec3=020
        [0x1d] rec0=19 rec1=00 rec2=14 rec3=062
        [0x1e] rec0=1d rec1=00 rec2=15 rec3=050
        [0x1f] rec0=00 rec1=00 rec2=24 rec3=018
        [0x20] rec0=14 rec1=00 rec2=16 rec3=042
        [0x21] rec0=14 rec1=00 rec2=17 rec3=020
        [0x22] rec0=12 rec1=00 rec2=18 rec3=046
        [0x23] rec0=01 rec1=00 rec2=23 rec3=00a
        [0x24] rec0=13 rec1=00 rec2=19 rec3=06a
        [0x25] rec0=15 rec1=00 rec2=1a rec3=046
        [0x26] rec0=17 rec1=00 rec2=1b rec3=08a
        [0x27] rec0=16 rec1=00 rec2=1c rec3=002
        [0x28] rec0=13 rec1=00 rec2=1d rec3=03c
        [0x29] rec0=16 rec1=00 rec2=1e rec3=03a
        [0x2a] rec0=1a rec1=00 rec2=1f rec3=008
        [0x2b] rec0=00 rec1=00 rec2=22 rec3=010
        [0x2c] rec0=1a rec1=00 rec2=20 rec3=03c
        [0x2d] rec0=07 rec1=00 rec2=21 rec3=001
    tail 0x215004478815c6606e31b 0x42a00088462061e03