]>
Commit | Line | Data |
---|---|---|
996ae0b0 RK |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- S E M _ M A P S -- | |
6 | -- -- | |
7 | -- S p e c -- | |
8 | -- -- | |
9de61fcb | 9 | -- Copyright (C) 1996-2005, Free Software Foundation, Inc. -- |
996ae0b0 RK |
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 2, 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. See the GNU General Public License -- | |
17 | -- for more details. You should have received a copy of the GNU General -- | |
18 | -- Public License distributed with GNAT; see file COPYING. If not, write -- | |
cb5fee25 KC |
19 | -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- |
20 | -- Boston, MA 02110-1301, USA. -- | |
996ae0b0 RK |
21 | -- -- |
22 | -- GNAT was originally developed by the GNAT team at New York University. -- | |
71ff80dc | 23 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
996ae0b0 RK |
24 | -- -- |
25 | ------------------------------------------------------------------------------ | |
26 | ||
27 | -- This package contains the operations on the renaming maps used for | |
28 | -- generic analysis and instantiation. Renaming maps are created when | |
29 | -- a generic unit is analyzed, in order to capture all references to | |
30 | -- global variables within the unit. The renaming map of a generic unit | |
31 | -- copied prior to each instantiation, and then updated by mapping the | |
32 | -- formals into the actuals and the local entities into entities local to | |
33 | -- the instance. When the generic tree is copied to produce the instance, | |
34 | -- all references are updated by means of the renaming map. | |
35 | ||
36 | -- Map composition of renaming maps takes place for nested instantiations, | |
37 | -- for generic child units, and for formal packages. | |
38 | ||
9de61fcb | 39 | -- For additional details, see the documentation in sem_ch12 |
996ae0b0 RK |
40 | |
41 | with Table; | |
42 | with Types; use Types; | |
43 | ||
44 | package Sem_Maps is | |
45 | ||
46 | type Map is new Int; | |
47 | ||
48 | type Assoc is private; | |
49 | ||
50 | type Scope_Kind is (S_Global, S_Formal, S_Local); | |
51 | ||
52 | function New_Map (Num_Assoc : Int) return Map; | |
53 | -- Build empty map with the given number of associations, and a | |
54 | -- headers table of the appropriate size. | |
55 | ||
56 | function Compose (Orig_Map : Map; New_Map : Map) return Map; | |
57 | -- Update the associations in Orig_Map, so that if Orig_Map (e1) = e2 | |
58 | -- and New_Map (e2) = e3, then the image of e1 under the result is e3. | |
59 | ||
60 | function Copy (M : Map) return Map; | |
9de61fcb | 61 | -- Full copy of contents and headers |
996ae0b0 RK |
62 | |
63 | function Lookup (M : Map; E : Entity_Id) return Entity_Id; | |
9de61fcb | 64 | -- Retrieve image of E under M, Empty if undefined |
996ae0b0 RK |
65 | |
66 | procedure Add_Association | |
67 | (M : in out Map; | |
68 | O_Id : Entity_Id; | |
69 | N_Id : Entity_Id; | |
70 | Kind : Scope_Kind := S_Local); | |
9de61fcb | 71 | -- Update M in place. On entry M (O_Id) must not be defined |
996ae0b0 RK |
72 | |
73 | procedure Update_Association | |
74 | (M : in out Map; | |
75 | O_Id : Entity_Id; | |
76 | N_Id : Entity_Id; | |
77 | Kind : Scope_Kind := S_Local); | |
9de61fcb | 78 | -- Update the entry in M for O_Id |
996ae0b0 RK |
79 | |
80 | function Build_Instance_Map (M : Map) return Map; | |
81 | -- Copy renaming map of generic, and create new entities for all the | |
82 | -- local entities within. | |
83 | ||
84 | private | |
85 | ||
86 | -- New maps are created when a generic is analyzed, and for each of | |
87 | -- its instantiations. Maps are also updated for nested generics, for | |
88 | -- child units, and for formal packages. As a result we need to allocate | |
89 | -- maps dynamically. | |
90 | ||
91 | -- When analyzing a generic, we do not know how many references are | |
92 | -- in it. We build an initial map after generic analysis, using a static | |
93 | -- structure that relies on the compiler's extensible table mechanism. | |
94 | -- After constructing this initial map, all subsequent uses and updates | |
95 | -- of this map do not modify its domain, so that dynamically allocated | |
96 | -- maps have a fixed size and never need to be reallocated. Furthermore, | |
97 | -- the headers of the hash table of a dynamically allocated map can be | |
98 | -- chosen according to the total number of entries in the map, to | |
638e383e | 99 | -- accommodate efficiently generic units of different sizes (Unchecked_ |
996ae0b0 RK |
100 | -- Conversion vs. Generic_Elementary_Functions, for example). So in |
101 | -- fact both components of a map have fixed size, and can be allocated | |
102 | -- using the standard table mechanism. A Maps_Table holds records that | |
103 | -- contain indices into the global Headers table and the Associations | |
104 | -- table, and a Map is an index into the Maps_Table. | |
105 | -- | |
106 | -- Maps_Table Headers_Table Associations_Table | |
107 | -- | |
108 | -- |_____| |___________ | | |
109 | -- |_____| | | | | | |
110 | -- ------>|Map |------------------------------>|Associations| | |
111 | -- |Info |------------->| |=========>| for one | | |
112 | -- |_____| | |====| | unit | | |
113 | -- | | | | |====>| | | |
114 | -- |_____| |____________| | |
115 | -- | | | | | |
116 | type Header_Index is new Int; | |
117 | type Assoc_Index is new Int; | |
118 | No_Assoc : constant Assoc_Index := -1; | |
119 | ||
120 | type Map_Info is record | |
121 | Header_Offset : Header_Index; | |
122 | Header_Num : Header_Index; | |
123 | Assoc_Offset : Assoc_Index; | |
124 | Assoc_Num : Assoc_Index; | |
125 | Assoc_Next : Assoc_Index; | |
126 | end record; | |
127 | ||
128 | type Assoc is record | |
129 | Old_Id : Entity_Id := Empty; | |
130 | New_Id : Entity_Id := Empty; | |
131 | Kind : Scope_Kind := S_Local; | |
132 | Next : Assoc_Index := No_Assoc; | |
133 | end record; | |
134 | ||
135 | -- All maps are accessed through the following table. The map attribute | |
136 | -- of a generic unit or an instance is an index into this table. | |
137 | ||
138 | package Maps_Table is new Table.Table ( | |
139 | Table_Component_Type => Map_Info, | |
140 | Table_Index_Type => Map, | |
141 | Table_Low_Bound => 0, | |
142 | Table_Initial => 100, | |
143 | Table_Increment => 10, | |
144 | Table_Name => "Maps_Table"); | |
145 | ||
146 | -- All headers for hash tables are allocated in one global table. Each | |
147 | -- map stores the offset into this table at which its own headers start. | |
148 | ||
149 | package Headers_Table is new Table.Table ( | |
150 | Table_Component_Type => Assoc_Index, | |
151 | Table_Index_Type => Header_Index, | |
152 | Table_Low_Bound => 0, | |
153 | Table_Initial => 1000, | |
154 | Table_Increment => 10, | |
155 | Table_Name => "Headers_Table"); | |
156 | ||
157 | -- All associations are allocated in one global table. Each map stores | |
158 | -- the offset into this table at which its own associations start. | |
159 | ||
160 | package Associations_Table is new Table.Table ( | |
161 | Table_Component_Type => Assoc, | |
162 | Table_Index_Type => Assoc_Index, | |
163 | Table_Low_Bound => 1, | |
164 | Table_Initial => 1000, | |
165 | Table_Increment => 10, | |
166 | Table_Name => "Associations_Table"); | |
167 | ||
168 | end Sem_Maps; |