-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (Sem)
procedure Add_Record_Sub_Components
  (Record_Var_Sym  : in     Dictionary.Symbol;
   Record_Type_Sym : in     Dictionary.Symbol;
   Component_Data  : in out ComponentManager.ComponentData;
   The_Heap        : in out Heap.HeapRecord)
is
   Type_Component                    : Dictionary.Symbol;
   Var_Component                     : Dictionary.Symbol;
   Prefix_Component_Node             : ComponentManager.Component;
   Current_Record_Var                : Dictionary.Symbol;
   Current_Record_Type               : Dictionary.Symbol;
   Number_Of_Non_Extended_Components : Natural;
begin
   Current_Record_Var  := Record_Var_Sym;
   Current_Record_Type := Record_Type_Sym;
   if Dictionary.IsSubtype (Current_Record_Type) then
      Current_Record_Type := Dictionary.GetRootType (Current_Record_Type);
   end if;

   Prefix_Component_Node := ComponentManager.GetComponentNode (Component_Data, Current_Record_Var);
   -- for non tagged records the outer loop only runs once.  For extended tagged
   -- records we loop through all the inherited fields and add them too

   -- A private extended tagged type where the private part is hidden
   -- might result in Prefix_Component_Node being Null here, in which
   -- case nothing can be done.
   Number_Of_Non_Extended_Components := Dictionary.GetNumberOfNonExtendedComponents (Current_Record_Type);
   loop
      for I in Natural range 1 .. Number_Of_Non_Extended_Components loop
         Type_Component := Dictionary.GetNonExtendedRecordComponent (Current_Record_Type, I);
         Dictionary.AddRecordSubcomponent
           (Prefix       => Current_Record_Var,
            Component    => Type_Component,
            Comp_Unit    => ContextManager.Ops.Current_Unit,
            Subcomponent => Var_Component);
         Prefix_Component_Node := ComponentManager.GetComponentNode (Component_Data, Current_Record_Var);
         ComponentManager.AddNextChild (Component_Data, The_Heap, Prefix_Component_Node, Var_Component);
      end loop;
      Current_Record_Type := Dictionary.GetRootOfExtendedType (Current_Record_Type);
      -- stop when there are no more inherited fields
      exit when Dictionary.Is_Null_Symbol (Current_Record_Type);
      -- if the record has no components (perhaps it is a private type and the private
      -- part is hidden) then we cannot add any subcomponents
      Number_Of_Non_Extended_Components := Dictionary.GetNumberOfNonExtendedComponents (Current_Record_Type);
      exit when Number_Of_Non_Extended_Components = 0;

      -- Simillarly, if the Prefix_Component_Node is null, then we
      -- can't find its FirstChild, so we must be done.
      exit when ComponentManager.IsNullComponent (Prefix_Component_Node);
      Current_Record_Var :=
        ComponentManager.GetName (Component_Data, ComponentManager.GetFirstChild (Component_Data, Prefix_Component_Node));
   end loop;

   ComponentManager.Dump_All_Component_Trees (Data => Component_Data);
end Add_Record_Sub_Components;
