-------------------------------------- ------------------------------------------ -- -- -- OCARINA COMPONENTS -- -- -- -- OCARINA.GENERATORS.PO_HI_ADA.DEPLOYMENT -- -- -- -- B o d y -- -- -- -- Copyright (C) 2006-2007, GET-Telecom Paris. -- -- -- -- Ocarina 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 2, or (at your option) any -- -- later version. Ocarina 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 Ocarina; see file COPYING. -- -- If not, write to the Free Software Foundation, 51 Franklin Street, Fifth -- -- Floor, Boston, MA 02111-1301, USA. -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- -- -- -- Ocarina is maintained by the Ocarina team -- -- (ocarina-users@listes.enst.fr) -- -- -- ------------------------------------------------------------------------------ with Namet; with Ocarina.Nodes; with Ocarina.Nutils; with Ocarina.Entities.Components; with Ocarina.Generators.Utils; with Ocarina.Generators.Ada_Values; with Ocarina.Generators.Ada_Tree.Nutils; with Ocarina.Generators.Ada_Tree.Nodes; with Ocarina.Generators.PO_HI_Ada.Mapping; package body Ocarina.Generators.PO_HI_Ada.Deployment is use Namet; use Ocarina.Nodes; use Ocarina.Entities.Components; use Ocarina.Generators.Utils; use Ocarina.Generators.Ada_Values; use Ocarina.Generators.Ada_Tree.Nutils; use Ocarina.Generators.PO_HI_Ada.Mapping; package AAU renames Ocarina.Nutils; package ADN renames Ocarina.Generators.Ada_Tree.Nodes; ------------------ -- Package_Spec -- ------------------ package body Package_Spec is procedure Visit_Architecture_Instance (E : Node_Id); procedure Visit_Component_Instance (E : Node_Id); procedure Visit_System_Instance (E : Node_Id); procedure Visit_Process_Instance (E : Node_Id); procedure Visit_Thread_Instance (E : Node_Id); Last_Node_Enum_Pos : Nat := 1; Last_Thread_Enum_Pos : Nat := 1; Last_Port_Enum_Pos : Nat := 1; -- Global variables for the representation clauses of the -- generated enumerator types. They point to the next free -- position in the corresponding enumeration type. We start by -- 1 because 0 is the value to indicate that no position has -- been assigned to the enumerator yet. function Get_Node_Enum_Pos (Name : Name_Id) return Nat; function Get_Thread_Enum_Pos (Name : Name_Id) return Nat; function Get_Port_Enum_Pos (Name : Name_Id) return Nat; -- Return the position corresponding to the enumerator. If no -- position has been computed for the given enumerator, compute -- a new one. function Added_Internal_Name (P : Node_Id; E : Node_Id) return Name_Id; function Is_Added (P : Node_Id; E : Node_Id) return Boolean; procedure Set_Added (P : Node_Id; E : Node_Id); -- Used to ensure that the enumerator for Process P and all the -- enumerator corresponding to its threads are added only once -- to the deployment package of node E. type Get_Enum_Pos_Access is access function (Name : Name_Id) return Nat; procedure Insert_Node_In_List (N : Node_Id; L : List_Id; Get_Enum_Pos : Get_Enum_Pos_Access); -- Insert the node N into list L. N is assumed to be an -- enumerator or an element association relative to an -- enumerator. The insertion is done so that the positions of -- all the enumerators in the list are ordered -- incresingly. This is necessary in Ada since the enumerator -- position order must respect their declaration order. ------------------ -- Global Lists -- ------------------ -- The lists below are global and initialized at the beginning -- of visit of each process instance. This does not cause a -- consistency nor a concurrency proble since the visits of -- processes are done sequentially and the visit of one process -- is performed entirely before beginning the visit of another -- one. Node_Enumerator_List : List_Id; -- Global list for all the distributed application nodes -- enumeration type. Node_Enumerator_Pos_List : List_Id; -- Global list to store the representation clause of the node -- enumeration type. Thread_Enumerator_List : List_Id; -- Global list for all the distributed application threads -- enumeration types. Thread_Enumerator_Pos_List : List_Id; -- Global list to store the representation clause of the thread -- enumeration type. Entity_Table_List : List_Id; -- Global list that associates each thread of the distributed -- application to its containing process. Concretly, this is a -- list of associations that contain for each enumerator of the -- Entity_Type type the corresponding enumerator of the -- Node_Type type. Port_Enumerator_List : List_Id; -- Global list for all the distributed application thread port -- enumeration types. Port_Enumerator_Pos_List : List_Id; -- Global list to store the representation clause of the thread -- port enumeration type. Port_Table_List : List_Id; -- Global list that associates each port of the distributed -- application to its containing thread. Concretly, this is a -- list of associations that contain for each enumerator of the -- Port_Type type the corresponding enumerator of the -- Entity_Type type. ----------------------- -- Get_Node_Enum_Pos -- ----------------------- function Get_Node_Enum_Pos (Name : Name_Id) return Nat is I_Name : Name_Id; Position : Nat; begin Set_Str_To_Name_Buffer ("%node_enum_pos%"); Get_Name_String (Name); I_Name := Name_Find; -- Check whether a value has been computed for the current -- enumerator. Otherwise, compute a new one. Position := Get_Name_Table_Info (I_Name); if Position = 0 then -- Get the next free position Position := Last_Node_Enum_Pos; -- Link it to the enumerator for future use Set_Name_Table_Info (I_Name, Position); -- Increment the next free position Last_Node_Enum_Pos := Last_Node_Enum_Pos + 1; end if; return Position; end Get_Node_Enum_Pos; ------------------------- -- Get_Thread_Enum_Pos -- ------------------------- function Get_Thread_Enum_Pos (Name : Name_Id) return Nat is I_Name : Name_Id; Position : Nat; begin Set_Str_To_Name_Buffer ("%thread_enum_pos%"); Get_Name_String (Name); I_Name := Name_Find; -- Check whether a value has been computed for the current -- enumerator. Otherwise, compute a new one. Position := Get_Name_Table_Info (I_Name); if Position = 0 then -- Get the next free position Position := Last_Thread_Enum_Pos; -- Link it to the enumerator for future use Set_Name_Table_Info (I_Name, Position); -- Increment the next free position Last_Thread_Enum_Pos := Last_Thread_Enum_Pos + 1; end if; return Position; end Get_Thread_Enum_Pos; ----------------------- -- Get_Port_Enum_Pos -- ----------------------- function Get_Port_Enum_Pos (Name : Name_Id) return Nat is I_Name : Name_Id; Position : Nat; begin Set_Str_To_Name_Buffer ("%port_enum_pos%"); Get_Name_String (Name); I_Name := Name_Find; -- Check whether a value has been computed for the current -- enumerator. Otherwise, compute a new one. Position := Get_Name_Table_Info (I_Name); if Position = 0 then -- Get the next free position Position := Last_Port_Enum_Pos; -- Link it to the enumerator for future use Set_Name_Table_Info (I_Name, Position); -- Increment the next free position Last_Port_Enum_Pos := Last_Port_Enum_Pos + 1; end if; return Position; end Get_Port_Enum_Pos; ------------------------- -- Added_Internal_Name -- ------------------------- function Added_Internal_Name (P : Node_Id; E : Node_Id) return Name_Id is begin Set_Str_To_Name_Buffer ("%add%enumerator%"); Add_Nat_To_Name_Buffer (Nat (P)); Add_Char_To_Name_Buffer ('%'); Add_Nat_To_Name_Buffer (Nat (E)); return Name_Find; end Added_Internal_Name; -------------- -- Is_Added -- -------------- function Is_Added (P : Node_Id; E : Node_Id) return Boolean is I_Name : constant Name_Id := Added_Internal_Name (P, E); begin return Get_Name_Table_Byte (I_Name) = 1; end Is_Added; --------------- -- Set_Added -- --------------- procedure Set_Added (P : Node_Id; E : Node_Id) is I_Name : constant Name_Id := Added_Internal_Name (P, E); begin Set_Name_Table_Byte (I_Name, 1); end Set_Added; ------------------------- -- Insert_Node_In_List -- ------------------------- procedure Insert_Node_In_List (N : Node_Id; L : List_Id; Get_Enum_Pos : Get_Enum_Pos_Access) is use ADN; M : Node_Id; Position_N : Nat; Position_M : Nat; begin pragma Assert (Kind (N) = K_Defining_Identifier or else Kind (N) = K_Element_Association); case ADN.Kind (N) is when ADN.K_Defining_Identifier => Position_N := Get_Enum_Pos (ADN.Name (N)); when ADN.K_Element_Association => Position_N := Get_Enum_Pos (ADN.Name (Index (N))); when others => raise Program_Error with "Inconsistency in Insert_Node_In_List"; end case; if Is_Empty (L) then Append_Node_To_List (N, L); else M := ADN.First_Node (L); while Present (M) loop case ADN.Kind (M) is when ADN.K_Defining_Identifier => Position_M := Get_Enum_Pos (ADN.Name (M)); when ADN.K_Element_Association => Position_M := Get_Enum_Pos (ADN.Name (Index (M))); when others => raise Program_Error with "Inconsistency in Insert_Node_In_List"; end case; if Position_N < Position_M then Insert_Before_Node (N, M, L); return; -- IMPORTANT end if; M := ADN.Next_Node (M); end loop; Append_Node_To_List (N, L); end if; end Insert_Node_In_List; ----------- -- Visit -- ----------- procedure Visit (E : Node_Id) is begin case Kind (E) is when K_Architecture_Instance => Visit_Architecture_Instance (E); when K_Component_Instance => Visit_Component_Instance (E); when others => null; end case; end Visit; --------------------------------- -- Visit_Architecture_Instance -- --------------------------------- procedure Visit_Architecture_Instance (E : Node_Id) is begin Visit (Root_System (E)); end Visit_Architecture_Instance; ------------------------------ -- Visit_Component_Instance -- ------------------------------ procedure Visit_Component_Instance (E : Node_Id) is Cathegory : constant Component_Category := Get_Category_Of_Component (E); begin case Cathegory is when CC_System => Visit_System_Instance (E); when CC_Process => Visit_Process_Instance (E); when CC_Thread => Visit_Thread_Instance (E); when others => null; end case; end Visit_Component_Instance; ---------------------------- -- Visit_Process_Instance -- ---------------------------- procedure Visit_Process_Instance (E : Node_Id) is U : constant Node_Id := ADN.Distributed_Application_Unit (ADN.Naming_Node (Backend_Node (Identifier (E)))); P : constant Node_Id := ADN.Entity (U); S : constant Node_Id := Parent_Subcomponent (E); N : Node_Id; C : Node_Id; F : Node_Id; Src : Node_Id; Dst : Node_Id; Parent : Node_Id; S_Parent : Node_Id; begin Push_Entity (P); Push_Entity (U); Set_Deployment_Spec; -- Create the lists Node_Enumerator_List := New_List (ADN.K_Enumeration_Literals); Node_Enumerator_Pos_List := New_List (ADN.K_Element_List); Thread_Enumerator_List := New_List (ADN.K_Enumeration_Literals); Thread_Enumerator_Pos_List := New_List (ADN.K_Element_List); Entity_Table_List := New_List (ADN.K_Element_List); Port_Enumerator_List := New_List (ADN.K_Enumeration_Literals); Port_Enumerator_Pos_List := New_List (ADN.K_Element_List); Port_Table_List := New_List (ADN.K_Element_List); -- The Deployment package must be preelaborated N := Make_Pragma_Statement (Pragma_Preelaborate, No_List); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Build the enumerator corresponding to the distributed -- application node. The enumerator name is mapped from the -- process *sub*component instance. N := Make_Defining_Identifier (Map_Ada_Enumerator_Name (S)); Append_Node_To_List (N, Node_Enumerator_List); Bind_AADL_To_Enumerator (Identifier (S), N); -- Build the representation clause of the enumerator N := Make_Element_Association (Make_Defining_Identifier (Map_Ada_Enumerator_Name (S)), Make_Literal (New_Integer_Value (Unsigned_Long_Long (Get_Node_Enum_Pos (Map_Ada_Enumerator_Name (S))), 1, 10))); Insert_Node_In_List (N, Node_Enumerator_Pos_List, Get_Node_Enum_Pos'Access); -- Visit all the subcomponents of the process if not AAU.Is_Empty (Subcomponents (E)) then C := First_Node (Subcomponents (E)); while Present (C) loop Visit (Corresponding_Instance (C)); C := Next_Node (C); end loop; end if; -- For each of the processes P connected to E, (1) we add an -- enumerator corresponding to P and (2) for each one of the -- threads of P, we add an enumerator. if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop -- The sources of F if not AAU.Is_Empty (Sources (F)) then Src := First_Node (Sources (F)); while Present (Src) loop Parent := Parent_Component (Item (Src)); if Is_Process (Parent) and then Parent /= E and then not Is_Added (Parent, E) then -- Add the process to the deployment -- enumerators of E. S_Parent := Parent_Subcomponent (Parent); N := Make_Defining_Identifier (Map_Ada_Enumerator_Name (S_Parent)); Insert_Node_In_List (N, Node_Enumerator_List, Get_Node_Enum_Pos'Access); -- Add a representation clause for the -- enumerator corresponding to Parent. N := Make_Element_Association (Make_Defining_Identifier (Map_Ada_Enumerator_Name (S_Parent)), Make_Literal (New_Integer_Value (Unsigned_Long_Long (Get_Node_Enum_Pos ( Map_Ada_Enumerator_Name (S_Parent))), 1, 10))); Insert_Node_In_List (N, Node_Enumerator_Pos_List, Get_Node_Enum_Pos'Access); -- Traverse all the subcomponents of Parent if not AAU.Is_Empty (Subcomponents (Parent)) then C := First_Node (Subcomponents (Parent)); while Present (C) loop Visit (Corresponding_Instance (C)); C := Next_Node (C); end loop; end if; -- Mark P as being Added Set_Added (Parent, E); end if; Src := Next_Node (Src); end loop; end if; -- The destinations of F if not AAU.Is_Empty (Destinations (F)) then Dst := First_Node (Destinations (F)); while Present (Dst) loop Parent := Parent_Component (Item (Dst)); if Is_Process (Parent) and then Parent /= E and then not Is_Added (Parent, E) then -- Add the process to the deployment -- enumerators of E. S_Parent := Parent_Subcomponent (Parent); N := Make_Defining_Identifier (Map_Ada_Enumerator_Name (S_Parent)); Insert_Node_In_List (N, Node_Enumerator_List, Get_Node_Enum_Pos'Access); -- Add a representation clause for the -- enumerator corresponding to P. N := Make_Element_Association (Make_Defining_Identifier (Map_Ada_Enumerator_Name (S_Parent)), Make_Literal (New_Integer_Value (Unsigned_Long_Long (Get_Node_Enum_Pos ( Map_Ada_Enumerator_Name (S_Parent))), 1, 10))); Insert_Node_In_List (N, Node_Enumerator_Pos_List, Get_Node_Enum_Pos'Access); -- Traverse all the subcomponensts of P if not AAU.Is_Empty (Subcomponents (Parent)) then C := First_Node (Subcomponents (Parent)); while Present (C) loop Visit (Corresponding_Instance (C)); C := Next_Node (C); end loop; end if; -- Mark P as being Added Set_Added (Parent, E); end if; Dst := Next_Node (Dst); end loop; end if; F := Next_Node (F); end loop; end if; -- Create the node enumeration type declaration. Note that -- the type creation is possible even the enumeration list -- is incomplete. We can do this in the first traversal -- since we are sure that the enumerator list is not empty. N := Message_Comment ("For each node in the distributed" & " application add an enumerator"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Full_Type_Declaration (Defining_Identifier => Make_Defining_Identifier (TN (T_Node_Type)), Type_Definition => Make_Enumeration_Type_Definition (Node_Enumerator_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Create the enumeration representation clause so that all -- the enumerators in all the generated deployment packages -- have coherent position. N := Message_Comment ("Representation clause to have consistent" & " positions for enumarators"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Enumeration_Representation_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Node_Type)), Array_Aggregate => Make_Array_Aggregate (Node_Enumerator_Pos_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Fix the size of type Node_Type to 8 bit because the -- message stream allocates one byte for it for now. This -- implies a maximum value of 256 nodes per application. N := Message_Comment ("Size of Node_Type fixed to 8 bits"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Attribute_Definition_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Node_Type)), Attribute_Designator => A_Size, Expression => Make_Literal (New_Integer_Value (8, 1, 10))); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Declare the constant that represent the current node N := Make_Object_Declaration (Defining_Identifier => Make_Defining_Identifier (PN (P_My_Node)), Constant_Present => True, Object_Definition => Make_Designator (TN (T_Node_Type)), Expression => Make_Defining_Identifier (Map_Ada_Enumerator_Name (S))); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Create the thread enumeration type declaration. Note that -- the type creation is possible even the enumeration list -- is incomplete. if not Is_Empty (Thread_Enumerator_List) then N := Message_Comment ("For each thread in the distributed" & " application nodes, add an" & " enumerator"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Full_Type_Declaration (Defining_Identifier => Make_Defining_Identifier (TN (T_Entity_Type)), Type_Definition => Make_Enumeration_Type_Definition (Thread_Enumerator_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Create the enumeration representation clause so that -- all the enumerators in all the generated deployment -- packages have coherent position. N := Message_Comment ("Representation clause to have consistent" & " positions for enumarators"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Enumeration_Representation_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Entity_Type)), Array_Aggregate => Make_Array_Aggregate (Thread_Enumerator_Pos_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Fix the size of type Entity_Type to 8 bit because the -- message stream allocates one byte for it for now. This -- implies a maximum value of 256 nodes per application. N := Message_Comment ("Size of Entity_Type fixed to 8 bits"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Attribute_Definition_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Entity_Type)), Attribute_Designator => A_Size, Expression => Make_Literal (New_Integer_Value (8, 1, 10))); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); end if; -- Declare the Entity Table when necessary if not Is_Empty (Entity_Table_List) then N := Message_Comment ("Entity Table"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Array_Type_Definition (Range_Constraints => Make_List_Id (Make_Range_Constraint (No_Node, No_Node, Make_Attribute_Designator (Make_Designator (TN (T_Entity_Type)), A_Range))), Component_Definition => Make_Defining_Identifier (TN (T_Node_Type))); N := Make_Object_Declaration (Defining_Identifier => Make_Defining_Identifier (PN (P_Entity_Table)), Constant_Present => True, Object_Definition => N, Expression => Make_Array_Aggregate (Entity_Table_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); end if; -- Create the port enumeration type declaration. Note that -- the type creation is possible even the enumeration list -- is incomplete. if not Is_Empty (Port_Enumerator_List) then N := Message_Comment ("For each thread port in the distributed" & " application nodes, add an" & " enumerator"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Full_Type_Declaration (Defining_Identifier => Make_Defining_Identifier (TN (T_Port_Type)), Type_Definition => Make_Enumeration_Type_Definition (Port_Enumerator_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Create the enumeration representation clause so that -- all the enumerators in all the generated deployment -- packages have coherent position. N := Message_Comment ("Representation clause to have consistent" & " positions for enumarators"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Enumeration_Representation_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Port_Type)), Array_Aggregate => Make_Array_Aggregate (Port_Enumerator_Pos_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); -- Fix the size of type Port_Type to 16 bits to be able -- to instanciate a Marshallers_G for it. N := Message_Comment ("Size of Port_Type fixed to 16 bits"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Attribute_Definition_Clause (Defining_Identifier => Make_Defining_Identifier (TN (T_Port_Type)), Attribute_Designator => A_Size, Expression => Make_Literal (New_Integer_Value (16, 1, 10))); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); end if; -- Declare the Port Table when necessary if not Is_Empty (Port_Table_List) then N := Message_Comment ("Port Table"); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); N := Make_Array_Type_Definition (Range_Constraints => Make_List_Id (Make_Range_Constraint (No_Node, No_Node, Make_Attribute_Designator (Make_Designator (TN (T_Port_Type)), A_Range))), Component_Definition => Make_Defining_Identifier (TN (T_Entity_Type))); N := Make_Object_Declaration (Defining_Identifier => Make_Defining_Identifier (PN (P_Port_Table)), Constant_Present => True, Object_Definition => N, Expression => Make_Array_Aggregate (Port_Table_List)); Append_Node_To_List (N, ADN.Visible_Part (Current_Package)); end if; Pop_Entity; -- U Pop_Entity; -- P end Visit_Process_Instance; --------------------------- -- Visit_System_Instance -- --------------------------- procedure Visit_System_Instance (E : Node_Id) is S : Node_Id; begin Push_Entity (HI_Distributed_Application_Root); -- Visit all the subcomponents of the system if not AAU.Is_Empty (Subcomponents (E)) then S := First_Node (Subcomponents (E)); while Present (S) loop -- Visit the component instance corresponding to the -- subcomponent S. Visit (Corresponding_Instance (S)); S := Next_Node (S); end loop; end if; Pop_Entity; -- HI_Distributed_Application_Root end Visit_System_Instance; --------------------------- -- Visit_Thread_Instance -- --------------------------- procedure Visit_Thread_Instance (E : Node_Id) is N : Node_Id; P : Node_Id; F : Node_Id; S : constant Node_Id := Parent_Subcomponent (E); begin -- Build the enumerator corresponding to the thread. The -- enumerator name is mapped from the the thread name and -- its containing process name. N := Make_Defining_Identifier (Map_Ada_Enumerator_Name (S)); Insert_Node_In_List (N, Thread_Enumerator_List, Get_Thread_Enum_Pos'Access); Bind_AADL_To_Enumerator (Identifier (S), N); -- Build the representation clause for the enumerator N := Make_Element_Association (Make_Defining_Identifier (Map_Ada_Enumerator_Name (S)), Make_Literal (New_Integer_Value (Unsigned_Long_Long (Get_Thread_Enum_Pos (Map_Ada_Enumerator_Name (S))), 1, 10))); Insert_Node_In_List (N, Thread_Enumerator_Pos_List, Get_Thread_Enum_Pos'Access); -- For each thread, build the corresponding element -- association and append it to the entity list. -- Get the Process parent of the thread P := Parent_Component (S); pragma Assert (Is_Process (P)); N := Make_Element_Association (Make_Defining_Identifier (Map_Ada_Enumerator_Name (S)), Make_Defining_Identifier (Map_Ada_Enumerator_Name (Parent_Subcomponent (P)))); Insert_Node_In_List (N, Entity_Table_List, Get_Thread_Enum_Pos'Access); -- For each one of the thread ports, create its -- correspodning enumerator, representation clause and -- association. if not AAU.Is_Empty (Features (E)) then F := First_Node (Features (E)); while Present (F) loop if Kind (F) = K_Port_Spec_Instance then declare Enum_Name : constant Name_Id := Map_Ada_Full_Feature_Name (F, 'K'); begin -- Create the enumerator corresponding to the -- port. N := Make_Defining_Identifier (Enum_Name); Insert_Node_In_List (N, Port_Enumerator_List, Get_Port_Enum_Pos'Access); -- Build the representation clause for the -- enumerator. N := Make_Element_Association (Make_Defining_Identifier (Enum_Name), Make_Literal (New_Integer_Value (Unsigned_Long_Long (Get_Port_Enum_Pos (Enum_Name)), 1, 10))); Insert_Node_In_List (N, Port_Enumerator_Pos_List, Get_Port_Enum_Pos'Access); -- For each port, build the corresponding -- element association and append it to the -- association list. N := Make_Element_Association (Make_Defining_Identifier (Enum_Name), Make_Defining_Identifier (Map_Ada_Enumerator_Name (S))); Insert_Node_In_List (N, Port_Table_List, Get_Port_Enum_Pos'Access); end; end if; F := Next_Node (F); end loop; end if; end Visit_Thread_Instance; end Package_Spec; end Ocarina.Generators.PO_HI_Ada.Deployment;