1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- E L I S T S -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1992-2019, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. -- 17-- -- 18-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 21-- -- 22-- You should have received a copy of the GNU General Public License and -- 23-- a copy of the GCC Runtime Library Exception along with this program; -- 24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 25-- <http://www.gnu.org/licenses/>. -- 26-- -- 27-- GNAT was originally developed by the GNAT team at New York University. -- 28-- Extensive contributions were provided by Ada Core Technologies Inc. -- 29-- -- 30------------------------------------------------------------------------------ 31 32-- This package provides facilities for manipulating lists of nodes (see 33-- package Atree for format and implementation of tree nodes). Separate list 34-- elements are allocated to represent elements of these lists, so it is 35-- possible for a given node to be on more than one element list at a time. 36-- See also package Nlists, which provides another form that is threaded 37-- through the nodes themselves (using the Link field), which is more time 38-- and space efficient, but a node can be only one such list. 39 40with Types; use Types; 41with System; 42 43package Elists is 44 45 -- An element list is represented by a header that is allocated in the 46 -- Elist header table. This header contains pointers to the first and 47 -- last elements in the list, or to No_Elmt if the list is empty. 48 49 -- The elements in the list each contain a pointer to the next element 50 -- and a pointer to the referenced node. Putting a node into an element 51 -- list causes no change at all to the node itself, so a node may be 52 -- included in multiple element lists, and the nodes thus included may 53 -- or may not be elements of node lists (see package Nlists). 54 55 procedure Initialize; 56 -- Initialize allocation of element list tables. Called at the start of 57 -- compiling each new main source file. Note that Initialize must not be 58 -- called if Tree_Read is used. 59 60 procedure Lock; 61 -- Lock tables used for element lists before calling backend 62 63 procedure Unlock; 64 -- Unlock list tables, in cases where the back end needs to modify them 65 66 procedure Tree_Read; 67 -- Initializes internal tables from current tree file using the relevant 68 -- Table.Tree_Read routines. Note that Initialize should not be called if 69 -- Tree_Read is used. Tree_Read includes all necessary initialization. 70 71 procedure Tree_Write; 72 -- Writes out internal tables to current tree file using the relevant 73 -- Table.Tree_Write routines. 74 75 function Last_Elist_Id return Elist_Id; 76 -- Returns Id of last allocated element list header 77 78 function Elists_Address return System.Address; 79 -- Return address of Elists table (used in Back_End for Gigi call) 80 81 function Num_Elists return Nat; 82 -- Number of currently allocated element lists 83 84 function Last_Elmt_Id return Elmt_Id; 85 -- Returns Id of last allocated list element 86 87 function Elmts_Address return System.Address; 88 -- Return address of Elmts table (used in Back_End for Gigi call) 89 90 function Node (Elmt : Elmt_Id) return Node_Or_Entity_Id; 91 pragma Inline (Node); 92 -- Returns the value of a given list element. Returns Empty if Elmt 93 -- is set to No_Elmt. 94 95 function New_Elmt_List return Elist_Id; 96 -- Creates a new empty element list. Typically this is used to initialize 97 -- a field in some other node which points to an element list where the 98 -- list is then subsequently filled in using Append calls. 99 100 function First_Elmt (List : Elist_Id) return Elmt_Id; 101 pragma Inline (First_Elmt); 102 -- Obtains the first element of the given element list or, if the list has 103 -- no items, then No_Elmt is returned. 104 105 function Last_Elmt (List : Elist_Id) return Elmt_Id; 106 pragma Inline (Last_Elmt); 107 -- Obtains the last element of the given element list or, if the list has 108 -- no items, then No_Elmt is returned. 109 110 function List_Length (List : Elist_Id) return Nat; 111 -- Returns number of elements in given List (zero if List = No_Elist) 112 113 function Next_Elmt (Elmt : Elmt_Id) return Elmt_Id; 114 pragma Inline (Next_Elmt); 115 -- This function returns the next element on an element list. The argument 116 -- must be a list element other than No_Elmt. Returns No_Elmt if the given 117 -- element is the last element of the list. 118 119 procedure Next_Elmt (Elmt : in out Elmt_Id); 120 pragma Inline (Next_Elmt); 121 -- Next_Elmt (Elmt) is equivalent to Elmt := Next_Elmt (Elmt) 122 123 function Is_Empty_Elmt_List (List : Elist_Id) return Boolean; 124 pragma Inline (Is_Empty_Elmt_List); 125 -- This function determines if a given tree id references an element list 126 -- that contains no items. 127 128 procedure Append_Elmt (N : Node_Or_Entity_Id; To : Elist_Id); 129 -- Appends N at the end of To, allocating a new element. N must be a 130 -- non-empty node or entity Id, and To must be an Elist (not No_Elist). 131 132 procedure Append_New_Elmt (N : Node_Or_Entity_Id; To : in out Elist_Id); 133 pragma Inline (Append_New_Elmt); 134 -- Like Append_Elmt if Elist_Id is not No_List, but if Elist_Id is No_List, 135 -- then first assigns it an empty element list and then does the append. 136 137 procedure Append_Unique_Elmt (N : Node_Or_Entity_Id; To : Elist_Id); 138 -- Like Append_Elmt, except that a check is made to see if To already 139 -- contains N and if so the call has no effect. 140 141 procedure Prepend_Elmt (N : Node_Or_Entity_Id; To : Elist_Id); 142 -- Appends N at the beginning of To, allocating a new element 143 144 procedure Prepend_Unique_Elmt (N : Node_Or_Entity_Id; To : Elist_Id); 145 -- Like Prepend_Elmt, except that a check is made to see if To already 146 -- contains N and if so the call has no effect. 147 148 procedure Insert_Elmt_After (N : Node_Or_Entity_Id; Elmt : Elmt_Id); 149 -- Add a new element (N) right after the pre-existing element Elmt 150 -- It is invalid to call this subprogram with Elmt = No_Elmt. 151 152 function New_Copy_Elist (List : Elist_Id) return Elist_Id; 153 -- Replicate the contents of a list. Internal list nodes are not shared and 154 -- order of elements is preserved. 155 156 procedure Replace_Elmt (Elmt : Elmt_Id; New_Node : Node_Or_Entity_Id); 157 pragma Inline (Replace_Elmt); 158 -- Causes the given element of the list to refer to New_Node, the node 159 -- which was previously referred to by Elmt is effectively removed from 160 -- the list and replaced by New_Node. 161 162 procedure Remove (List : Elist_Id; N : Node_Or_Entity_Id); 163 -- Remove a node or an entity from a list. If the list does not contain the 164 -- item in question, the routine has no effect. 165 166 procedure Remove_Elmt (List : Elist_Id; Elmt : Elmt_Id); 167 -- Removes Elmt from the given list. The node itself is not affected, 168 -- but the space used by the list element may be (but is not required 169 -- to be) freed for reuse in a subsequent Append_Elmt call. 170 171 procedure Remove_Last_Elmt (List : Elist_Id); 172 -- Removes the last element of the given list. The node itself is not 173 -- affected, but the space used by the list element may be (but is not 174 -- required to be) freed for reuse in a subsequent Append_Elmt call. 175 176 function Contains (List : Elist_Id; N : Node_Or_Entity_Id) return Boolean; 177 -- Perform a sequential search to determine whether the given list contains 178 -- a node or an entity. 179 180 function No (List : Elist_Id) return Boolean; 181 pragma Inline (No); 182 -- Tests given Id for equality with No_Elist. This allows notations like 183 -- "if No (Statements)" as opposed to "if Statements = No_Elist". 184 185 function Present (List : Elist_Id) return Boolean; 186 pragma Inline (Present); 187 -- Tests given Id for inequality with No_Elist. This allows notations like 188 -- "if Present (Statements)" as opposed to "if Statements /= No_Elist". 189 190 function No (Elmt : Elmt_Id) return Boolean; 191 pragma Inline (No); 192 -- Tests given Id for equality with No_Elmt. This allows notations like 193 -- "if No (Operation)" as opposed to "if Operation = No_Elmt". 194 195 function Present (Elmt : Elmt_Id) return Boolean; 196 pragma Inline (Present); 197 -- Tests given Id for inequality with No_Elmt. This allows notations like 198 -- "if Present (Operation)" as opposed to "if Operation /= No_Elmt". 199 200end Elists; 201