annotate gcc/ada/sem_elim.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- S E M _ E L I M --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 1997-2017, Free Software Foundation, Inc. --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Atree; use Atree;
kono
parents:
diff changeset
27 with Einfo; use Einfo;
kono
parents:
diff changeset
28 with Errout; use Errout;
kono
parents:
diff changeset
29 with Lib; use Lib;
kono
parents:
diff changeset
30 with Namet; use Namet;
kono
parents:
diff changeset
31 with Nlists; use Nlists;
kono
parents:
diff changeset
32 with Opt; use Opt;
kono
parents:
diff changeset
33 with Sem; use Sem;
kono
parents:
diff changeset
34 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
35 with Sem_Prag; use Sem_Prag;
kono
parents:
diff changeset
36 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
37 with Sinput; use Sinput;
kono
parents:
diff changeset
38 with Sinfo; use Sinfo;
kono
parents:
diff changeset
39 with Snames; use Snames;
kono
parents:
diff changeset
40 with Stand; use Stand;
kono
parents:
diff changeset
41 with Stringt; use Stringt;
kono
parents:
diff changeset
42 with Table;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 with GNAT.HTable; use GNAT.HTable;
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 package body Sem_Elim is
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 No_Elimination : Boolean;
kono
parents:
diff changeset
49 -- Set True if no Eliminate pragmas active
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 ---------------------
kono
parents:
diff changeset
52 -- Data Structures --
kono
parents:
diff changeset
53 ---------------------
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 -- A single pragma Eliminate is represented by the following record
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 type Elim_Data;
kono
parents:
diff changeset
58 type Access_Elim_Data is access Elim_Data;
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 type Names is array (Nat range <>) of Name_Id;
kono
parents:
diff changeset
61 -- Type used to represent set of names. Used for names in Unit_Name
kono
parents:
diff changeset
62 -- and also the set of names in Argument_Types.
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 type Access_Names is access Names;
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 type Elim_Data is record
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 Unit_Name : Access_Names;
kono
parents:
diff changeset
69 -- Unit name, broken down into a set of names (e.g. A.B.C is
kono
parents:
diff changeset
70 -- represented as Name_Id values for A, B, C in sequence).
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 Entity_Name : Name_Id;
kono
parents:
diff changeset
73 -- Entity name if Entity parameter if present. If no Entity parameter
kono
parents:
diff changeset
74 -- was supplied, then Entity_Node is set to Empty, and the Entity_Name
kono
parents:
diff changeset
75 -- field contains the last identifier name in the Unit_Name.
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 Entity_Scope : Access_Names;
kono
parents:
diff changeset
78 -- Static scope of the entity within the compilation unit represented by
kono
parents:
diff changeset
79 -- Unit_Name.
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 Entity_Node : Node_Id;
kono
parents:
diff changeset
82 -- Save node of entity argument, for posting error messages. Set
kono
parents:
diff changeset
83 -- to Empty if there is no entity argument.
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 Parameter_Types : Access_Names;
kono
parents:
diff changeset
86 -- Set to set of names given for parameter types. If no parameter
kono
parents:
diff changeset
87 -- types argument is present, this argument is set to null.
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 Result_Type : Name_Id;
kono
parents:
diff changeset
90 -- Result type name if Result_Types parameter present, No_Name if not
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 Source_Location : Name_Id;
kono
parents:
diff changeset
93 -- String describing the source location of subprogram defining name if
kono
parents:
diff changeset
94 -- Source_Location parameter present, No_Name if not
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 Hash_Link : Access_Elim_Data;
kono
parents:
diff changeset
97 -- Link for hash table use
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 Homonym : Access_Elim_Data;
kono
parents:
diff changeset
100 -- Pointer to next entry with same key
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 Prag : Node_Id;
kono
parents:
diff changeset
103 -- Node_Id for Eliminate pragma
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 end record;
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 ----------------
kono
parents:
diff changeset
108 -- Hash_Table --
kono
parents:
diff changeset
109 ----------------
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 -- Setup hash table using the Entity_Name field as the hash key
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 subtype Element is Elim_Data;
kono
parents:
diff changeset
114 subtype Elmt_Ptr is Access_Elim_Data;
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 subtype Key is Name_Id;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 type Header_Num is range 0 .. 1023;
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 Null_Ptr : constant Elmt_Ptr := null;
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 ----------------------
kono
parents:
diff changeset
123 -- Hash_Subprograms --
kono
parents:
diff changeset
124 ----------------------
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 package Hash_Subprograms is
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 function Equal (F1, F2 : Key) return Boolean;
kono
parents:
diff changeset
129 pragma Inline (Equal);
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 function Get_Key (E : Elmt_Ptr) return Key;
kono
parents:
diff changeset
132 pragma Inline (Get_Key);
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 function Hash (F : Key) return Header_Num;
kono
parents:
diff changeset
135 pragma Inline (Hash);
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 function Next (E : Elmt_Ptr) return Elmt_Ptr;
kono
parents:
diff changeset
138 pragma Inline (Next);
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 procedure Set_Next (E : Elmt_Ptr; Next : Elmt_Ptr);
kono
parents:
diff changeset
141 pragma Inline (Set_Next);
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 end Hash_Subprograms;
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 package body Hash_Subprograms is
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 -----------
kono
parents:
diff changeset
148 -- Equal --
kono
parents:
diff changeset
149 -----------
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 function Equal (F1, F2 : Key) return Boolean is
kono
parents:
diff changeset
152 begin
kono
parents:
diff changeset
153 return F1 = F2;
kono
parents:
diff changeset
154 end Equal;
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 -------------
kono
parents:
diff changeset
157 -- Get_Key --
kono
parents:
diff changeset
158 -------------
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 function Get_Key (E : Elmt_Ptr) return Key is
kono
parents:
diff changeset
161 begin
kono
parents:
diff changeset
162 return E.Entity_Name;
kono
parents:
diff changeset
163 end Get_Key;
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 ----------
kono
parents:
diff changeset
166 -- Hash --
kono
parents:
diff changeset
167 ----------
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 function Hash (F : Key) return Header_Num is
kono
parents:
diff changeset
170 begin
kono
parents:
diff changeset
171 return Header_Num (Int (F) mod 1024);
kono
parents:
diff changeset
172 end Hash;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 ----------
kono
parents:
diff changeset
175 -- Next --
kono
parents:
diff changeset
176 ----------
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 function Next (E : Elmt_Ptr) return Elmt_Ptr is
kono
parents:
diff changeset
179 begin
kono
parents:
diff changeset
180 return E.Hash_Link;
kono
parents:
diff changeset
181 end Next;
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 --------------
kono
parents:
diff changeset
184 -- Set_Next --
kono
parents:
diff changeset
185 --------------
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 procedure Set_Next (E : Elmt_Ptr; Next : Elmt_Ptr) is
kono
parents:
diff changeset
188 begin
kono
parents:
diff changeset
189 E.Hash_Link := Next;
kono
parents:
diff changeset
190 end Set_Next;
kono
parents:
diff changeset
191 end Hash_Subprograms;
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 ------------
kono
parents:
diff changeset
194 -- Tables --
kono
parents:
diff changeset
195 ------------
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 -- The following table records the data for each pragma, using the
kono
parents:
diff changeset
198 -- entity name as the hash key for retrieval. Entries in this table
kono
parents:
diff changeset
199 -- are set by Process_Eliminate_Pragma and read by Check_Eliminated.
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 package Elim_Hash_Table is new Static_HTable (
kono
parents:
diff changeset
202 Header_Num => Header_Num,
kono
parents:
diff changeset
203 Element => Element,
kono
parents:
diff changeset
204 Elmt_Ptr => Elmt_Ptr,
kono
parents:
diff changeset
205 Null_Ptr => Null_Ptr,
kono
parents:
diff changeset
206 Set_Next => Hash_Subprograms.Set_Next,
kono
parents:
diff changeset
207 Next => Hash_Subprograms.Next,
kono
parents:
diff changeset
208 Key => Key,
kono
parents:
diff changeset
209 Get_Key => Hash_Subprograms.Get_Key,
kono
parents:
diff changeset
210 Hash => Hash_Subprograms.Hash,
kono
parents:
diff changeset
211 Equal => Hash_Subprograms.Equal);
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 -- The following table records entities for subprograms that are
kono
parents:
diff changeset
214 -- eliminated, and corresponding eliminate pragmas that caused the
kono
parents:
diff changeset
215 -- elimination. Entries in this table are set by Check_Eliminated
kono
parents:
diff changeset
216 -- and read by Eliminate_Error_Msg.
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 type Elim_Entity_Entry is record
kono
parents:
diff changeset
219 Prag : Node_Id;
kono
parents:
diff changeset
220 Subp : Entity_Id;
kono
parents:
diff changeset
221 end record;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 package Elim_Entities is new Table.Table (
kono
parents:
diff changeset
224 Table_Component_Type => Elim_Entity_Entry,
kono
parents:
diff changeset
225 Table_Index_Type => Name_Id'Base,
kono
parents:
diff changeset
226 Table_Low_Bound => First_Name_Id,
kono
parents:
diff changeset
227 Table_Initial => 50,
kono
parents:
diff changeset
228 Table_Increment => 200,
kono
parents:
diff changeset
229 Table_Name => "Elim_Entries");
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 ----------------------
kono
parents:
diff changeset
232 -- Check_Eliminated --
kono
parents:
diff changeset
233 ----------------------
kono
parents:
diff changeset
234
kono
parents:
diff changeset
235 procedure Check_Eliminated (E : Entity_Id) is
kono
parents:
diff changeset
236 Elmt : Access_Elim_Data;
kono
parents:
diff changeset
237 Scop : Entity_Id;
kono
parents:
diff changeset
238 Form : Entity_Id;
kono
parents:
diff changeset
239 Up : Nat;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 begin
kono
parents:
diff changeset
242 if No_Elimination then
kono
parents:
diff changeset
243 return;
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 -- Elimination of objects and types is not implemented yet
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 elsif Ekind (E) not in Subprogram_Kind then
kono
parents:
diff changeset
248 return;
kono
parents:
diff changeset
249 end if;
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 -- Loop through homonyms for this key
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 Elmt := Elim_Hash_Table.Get (Chars (E));
kono
parents:
diff changeset
254 while Elmt /= null loop
kono
parents:
diff changeset
255 Check_Homonyms : declare
kono
parents:
diff changeset
256 procedure Set_Eliminated;
kono
parents:
diff changeset
257 -- Set current subprogram entity as eliminated
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 --------------------
kono
parents:
diff changeset
260 -- Set_Eliminated --
kono
parents:
diff changeset
261 --------------------
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 procedure Set_Eliminated is
kono
parents:
diff changeset
264 Overridden : Entity_Id;
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 begin
kono
parents:
diff changeset
267 if Is_Dispatching_Operation (E) then
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 -- If an overriding dispatching primitive is eliminated then
kono
parents:
diff changeset
270 -- its parent must have been eliminated. If the parent is an
kono
parents:
diff changeset
271 -- inherited operation, check the operation that it renames,
kono
parents:
diff changeset
272 -- because flag Eliminated is only set on source operations.
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 Overridden := Overridden_Operation (E);
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 if Present (Overridden)
kono
parents:
diff changeset
277 and then not Comes_From_Source (Overridden)
kono
parents:
diff changeset
278 and then Present (Alias (Overridden))
kono
parents:
diff changeset
279 then
kono
parents:
diff changeset
280 Overridden := Alias (Overridden);
kono
parents:
diff changeset
281 end if;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 if Present (Overridden)
kono
parents:
diff changeset
284 and then not Is_Eliminated (Overridden)
kono
parents:
diff changeset
285 and then not Is_Abstract_Subprogram (Overridden)
kono
parents:
diff changeset
286 then
kono
parents:
diff changeset
287 Error_Msg_Name_1 := Chars (E);
kono
parents:
diff changeset
288 Error_Msg_N ("cannot eliminate subprogram %", E);
kono
parents:
diff changeset
289 return;
kono
parents:
diff changeset
290 end if;
kono
parents:
diff changeset
291 end if;
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 Set_Is_Eliminated (E);
kono
parents:
diff changeset
294 Elim_Entities.Append ((Prag => Elmt.Prag, Subp => E));
kono
parents:
diff changeset
295 end Set_Eliminated;
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 -- Start of processing for Check_Homonyms
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 begin
kono
parents:
diff changeset
300 -- First we check that the name of the entity matches
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 if Elmt.Entity_Name /= Chars (E) then
kono
parents:
diff changeset
303 goto Continue;
kono
parents:
diff changeset
304 end if;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 -- Find enclosing unit, and verify that its name and those of its
kono
parents:
diff changeset
307 -- parents match.
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 Scop := Cunit_Entity (Current_Sem_Unit);
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 -- Now see if compilation unit matches
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 Up := Elmt.Unit_Name'Last;
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 -- If we are within a subunit, the name in the pragma has been
kono
parents:
diff changeset
316 -- parsed as a child unit, but the current compilation unit is in
kono
parents:
diff changeset
317 -- fact the parent in which the subunit is embedded. We must skip
kono
parents:
diff changeset
318 -- the first name which is that of the subunit to match the pragma
kono
parents:
diff changeset
319 -- specification. Body may be that of a package or subprogram.
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 declare
kono
parents:
diff changeset
322 Par : Node_Id;
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 begin
kono
parents:
diff changeset
325 Par := Parent (E);
kono
parents:
diff changeset
326 while Present (Par) loop
kono
parents:
diff changeset
327 if Nkind (Par) = N_Subunit then
kono
parents:
diff changeset
328 if Chars (Defining_Entity (Proper_Body (Par))) =
kono
parents:
diff changeset
329 Elmt.Unit_Name (Up)
kono
parents:
diff changeset
330 then
kono
parents:
diff changeset
331 Up := Up - 1;
kono
parents:
diff changeset
332 exit;
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 else
kono
parents:
diff changeset
335 goto Continue;
kono
parents:
diff changeset
336 end if;
kono
parents:
diff changeset
337 end if;
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 Par := Parent (Par);
kono
parents:
diff changeset
340 end loop;
kono
parents:
diff changeset
341 end;
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 for J in reverse Elmt.Unit_Name'First .. Up loop
kono
parents:
diff changeset
344 if Elmt.Unit_Name (J) /= Chars (Scop) then
kono
parents:
diff changeset
345 goto Continue;
kono
parents:
diff changeset
346 end if;
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 Scop := Scope (Scop);
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 if Scop /= Standard_Standard and then J = 1 then
kono
parents:
diff changeset
351 goto Continue;
kono
parents:
diff changeset
352 end if;
kono
parents:
diff changeset
353 end loop;
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 if Scop /= Standard_Standard then
kono
parents:
diff changeset
356 goto Continue;
kono
parents:
diff changeset
357 end if;
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 if Present (Elmt.Entity_Node)
kono
parents:
diff changeset
360 and then Elmt.Entity_Scope /= null
kono
parents:
diff changeset
361 then
kono
parents:
diff changeset
362 -- Check that names of enclosing scopes match. Skip blocks and
kono
parents:
diff changeset
363 -- wrapper package of subprogram instances, which do not appear
kono
parents:
diff changeset
364 -- in the pragma.
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 Scop := Scope (E);
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 for J in reverse Elmt.Entity_Scope'Range loop
kono
parents:
diff changeset
369 while Ekind (Scop) = E_Block
kono
parents:
diff changeset
370 or else
kono
parents:
diff changeset
371 (Ekind (Scop) = E_Package
kono
parents:
diff changeset
372 and then Is_Wrapper_Package (Scop))
kono
parents:
diff changeset
373 loop
kono
parents:
diff changeset
374 Scop := Scope (Scop);
kono
parents:
diff changeset
375 end loop;
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 if Elmt.Entity_Scope (J) /= Chars (Scop) then
kono
parents:
diff changeset
378 if Ekind (Scop) /= E_Protected_Type
kono
parents:
diff changeset
379 or else Comes_From_Source (Scop)
kono
parents:
diff changeset
380 then
kono
parents:
diff changeset
381 goto Continue;
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 -- For simple protected declarations, retrieve the source
kono
parents:
diff changeset
384 -- name of the object, which appeared in the Eliminate
kono
parents:
diff changeset
385 -- pragma.
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 else
kono
parents:
diff changeset
388 declare
kono
parents:
diff changeset
389 Decl : constant Node_Id :=
kono
parents:
diff changeset
390 Original_Node (Parent (Scop));
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 begin
kono
parents:
diff changeset
393 if Elmt.Entity_Scope (J) /=
kono
parents:
diff changeset
394 Chars (Defining_Identifier (Decl))
kono
parents:
diff changeset
395 then
kono
parents:
diff changeset
396 if J > 0 then
kono
parents:
diff changeset
397 null;
kono
parents:
diff changeset
398 end if;
kono
parents:
diff changeset
399 goto Continue;
kono
parents:
diff changeset
400 end if;
kono
parents:
diff changeset
401 end;
kono
parents:
diff changeset
402 end if;
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 end if;
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 Scop := Scope (Scop);
kono
parents:
diff changeset
407 end loop;
kono
parents:
diff changeset
408 end if;
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 -- If given entity is a library level subprogram and pragma had a
kono
parents:
diff changeset
411 -- single parameter, a match.
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 if Is_Compilation_Unit (E)
kono
parents:
diff changeset
414 and then Is_Subprogram (E)
kono
parents:
diff changeset
415 and then No (Elmt.Entity_Node)
kono
parents:
diff changeset
416 then
kono
parents:
diff changeset
417 Set_Eliminated;
kono
parents:
diff changeset
418 return;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 -- Check for case of type or object with two parameter case
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 elsif (Is_Type (E) or else Is_Object (E))
kono
parents:
diff changeset
423 and then Elmt.Result_Type = No_Name
kono
parents:
diff changeset
424 and then Elmt.Parameter_Types = null
kono
parents:
diff changeset
425 then
kono
parents:
diff changeset
426 Set_Eliminated;
kono
parents:
diff changeset
427 return;
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 -- Check for case of subprogram
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 elsif Ekind_In (E, E_Function, E_Procedure) then
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 -- If Source_Location present, then see if it matches
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 if Elmt.Source_Location /= No_Name then
kono
parents:
diff changeset
436 Get_Name_String (Elmt.Source_Location);
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 declare
kono
parents:
diff changeset
439 Sloc_Trace : constant String :=
kono
parents:
diff changeset
440 Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 Idx : Natural := Sloc_Trace'First;
kono
parents:
diff changeset
443 -- Index in Sloc_Trace, if equals to 0, then we have
kono
parents:
diff changeset
444 -- completely traversed Sloc_Trace
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 Last : constant Natural := Sloc_Trace'Last;
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 P : Source_Ptr;
kono
parents:
diff changeset
449 Sindex : Source_File_Index;
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 function File_Name_Match return Boolean;
kono
parents:
diff changeset
452 -- This function is supposed to be called when Idx points
kono
parents:
diff changeset
453 -- to the beginning of the new file name, and Name_Buffer
kono
parents:
diff changeset
454 -- is set to contain the name of the proper source file
kono
parents:
diff changeset
455 -- from the chain corresponding to the Sloc of E. First
kono
parents:
diff changeset
456 -- it checks that these two files have the same name. If
kono
parents:
diff changeset
457 -- this check is successful, moves Idx to point to the
kono
parents:
diff changeset
458 -- beginning of the column number.
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 function Line_Num_Match return Boolean;
kono
parents:
diff changeset
461 -- This function is supposed to be called when Idx points
kono
parents:
diff changeset
462 -- to the beginning of the column number, and P is
kono
parents:
diff changeset
463 -- set to point to the proper Sloc the chain
kono
parents:
diff changeset
464 -- corresponding to the Sloc of E. First it checks that
kono
parents:
diff changeset
465 -- the line number Idx points on and the line number
kono
parents:
diff changeset
466 -- corresponding to P are the same. If this check is
kono
parents:
diff changeset
467 -- successful, moves Idx to point to the beginning of
kono
parents:
diff changeset
468 -- the next file name in Sloc_Trace. If there is no file
kono
parents:
diff changeset
469 -- name any more, Idx is set to 0.
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 function Different_Trace_Lengths return Boolean;
kono
parents:
diff changeset
472 -- From Idx and P, defines if there are in both traces
kono
parents:
diff changeset
473 -- more element(s) in the instantiation chains. Returns
kono
parents:
diff changeset
474 -- False if one trace contains more element(s), but
kono
parents:
diff changeset
475 -- another does not. If both traces contains more
kono
parents:
diff changeset
476 -- elements (that is, the function returns False), moves
kono
parents:
diff changeset
477 -- P ahead in the chain corresponding to E, recomputes
kono
parents:
diff changeset
478 -- Sindex and sets the name of the corresponding file in
kono
parents:
diff changeset
479 -- Name_Buffer
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 function Skip_Spaces return Natural;
kono
parents:
diff changeset
482 -- If Sloc_Trace (Idx) is not space character, returns
kono
parents:
diff changeset
483 -- Idx. Otherwise returns the index of the nearest
kono
parents:
diff changeset
484 -- non-space character in Sloc_Trace to the right of Idx.
kono
parents:
diff changeset
485 -- Returns 0 if there is no such character.
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 -----------------------------
kono
parents:
diff changeset
488 -- Different_Trace_Lengths --
kono
parents:
diff changeset
489 -----------------------------
kono
parents:
diff changeset
490
kono
parents:
diff changeset
491 function Different_Trace_Lengths return Boolean is
kono
parents:
diff changeset
492 begin
kono
parents:
diff changeset
493 P := Instantiation (Sindex);
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 if (P = No_Location and then Idx /= 0)
kono
parents:
diff changeset
496 or else
kono
parents:
diff changeset
497 (P /= No_Location and then Idx = 0)
kono
parents:
diff changeset
498 then
kono
parents:
diff changeset
499 return True;
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 else
kono
parents:
diff changeset
502 if P /= No_Location then
kono
parents:
diff changeset
503 Sindex := Get_Source_File_Index (P);
kono
parents:
diff changeset
504 Get_Name_String (File_Name (Sindex));
kono
parents:
diff changeset
505 end if;
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 return False;
kono
parents:
diff changeset
508 end if;
kono
parents:
diff changeset
509 end Different_Trace_Lengths;
kono
parents:
diff changeset
510
kono
parents:
diff changeset
511 ---------------------
kono
parents:
diff changeset
512 -- File_Name_Match --
kono
parents:
diff changeset
513 ---------------------
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 function File_Name_Match return Boolean is
kono
parents:
diff changeset
516 Tmp_Idx : Natural;
kono
parents:
diff changeset
517 End_Idx : Natural;
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 begin
kono
parents:
diff changeset
520 if Idx = 0 then
kono
parents:
diff changeset
521 return False;
kono
parents:
diff changeset
522 end if;
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 -- Find first colon. If no colon, then return False.
kono
parents:
diff changeset
525 -- If there is a colon, Tmp_Idx is set to point just
kono
parents:
diff changeset
526 -- before the colon.
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 Tmp_Idx := Idx - 1;
kono
parents:
diff changeset
529 loop
kono
parents:
diff changeset
530 if Tmp_Idx >= Last then
kono
parents:
diff changeset
531 return False;
kono
parents:
diff changeset
532 elsif Sloc_Trace (Tmp_Idx + 1) = ':' then
kono
parents:
diff changeset
533 exit;
kono
parents:
diff changeset
534 else
kono
parents:
diff changeset
535 Tmp_Idx := Tmp_Idx + 1;
kono
parents:
diff changeset
536 end if;
kono
parents:
diff changeset
537 end loop;
kono
parents:
diff changeset
538
kono
parents:
diff changeset
539 -- Find last non-space before this colon. If there is
kono
parents:
diff changeset
540 -- no space character before this colon, then return
kono
parents:
diff changeset
541 -- False. Otherwise, End_Idx is set to point to this
kono
parents:
diff changeset
542 -- non-space character.
kono
parents:
diff changeset
543
kono
parents:
diff changeset
544 End_Idx := Tmp_Idx;
kono
parents:
diff changeset
545 loop
kono
parents:
diff changeset
546 if End_Idx < Idx then
kono
parents:
diff changeset
547 return False;
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 elsif Sloc_Trace (End_Idx) /= ' ' then
kono
parents:
diff changeset
550 exit;
kono
parents:
diff changeset
551
kono
parents:
diff changeset
552 else
kono
parents:
diff changeset
553 End_Idx := End_Idx - 1;
kono
parents:
diff changeset
554 end if;
kono
parents:
diff changeset
555 end loop;
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 -- Now see if file name matches what is in Name_Buffer
kono
parents:
diff changeset
558 -- and if so, step Idx past it and return True. If the
kono
parents:
diff changeset
559 -- name does not match, return False.
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 if Sloc_Trace (Idx .. End_Idx) =
kono
parents:
diff changeset
562 Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
563 then
kono
parents:
diff changeset
564 Idx := Tmp_Idx + 2;
kono
parents:
diff changeset
565 Idx := Skip_Spaces;
kono
parents:
diff changeset
566 return True;
kono
parents:
diff changeset
567 else
kono
parents:
diff changeset
568 return False;
kono
parents:
diff changeset
569 end if;
kono
parents:
diff changeset
570 end File_Name_Match;
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 --------------------
kono
parents:
diff changeset
573 -- Line_Num_Match --
kono
parents:
diff changeset
574 --------------------
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 function Line_Num_Match return Boolean is
kono
parents:
diff changeset
577 N : Nat := 0;
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 begin
kono
parents:
diff changeset
580 if Idx = 0 then
kono
parents:
diff changeset
581 return False;
kono
parents:
diff changeset
582 end if;
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 while Idx <= Last
kono
parents:
diff changeset
585 and then Sloc_Trace (Idx) in '0' .. '9'
kono
parents:
diff changeset
586 loop
kono
parents:
diff changeset
587 N := N * 10 +
kono
parents:
diff changeset
588 (Character'Pos (Sloc_Trace (Idx)) -
kono
parents:
diff changeset
589 Character'Pos ('0'));
kono
parents:
diff changeset
590 Idx := Idx + 1;
kono
parents:
diff changeset
591 end loop;
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 if Get_Physical_Line_Number (P) =
kono
parents:
diff changeset
594 Physical_Line_Number (N)
kono
parents:
diff changeset
595 then
kono
parents:
diff changeset
596 while Idx <= Last and then
kono
parents:
diff changeset
597 Sloc_Trace (Idx) /= '['
kono
parents:
diff changeset
598 loop
kono
parents:
diff changeset
599 Idx := Idx + 1;
kono
parents:
diff changeset
600 end loop;
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 if Idx <= Last then
kono
parents:
diff changeset
603 pragma Assert (Sloc_Trace (Idx) = '[');
kono
parents:
diff changeset
604 Idx := Idx + 1;
kono
parents:
diff changeset
605 Idx := Skip_Spaces;
kono
parents:
diff changeset
606 else
kono
parents:
diff changeset
607 Idx := 0;
kono
parents:
diff changeset
608 end if;
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 return True;
kono
parents:
diff changeset
611
kono
parents:
diff changeset
612 else
kono
parents:
diff changeset
613 return False;
kono
parents:
diff changeset
614 end if;
kono
parents:
diff changeset
615 end Line_Num_Match;
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 -----------------
kono
parents:
diff changeset
618 -- Skip_Spaces --
kono
parents:
diff changeset
619 -----------------
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 function Skip_Spaces return Natural is
kono
parents:
diff changeset
622 Res : Natural;
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 begin
kono
parents:
diff changeset
625 Res := Idx;
kono
parents:
diff changeset
626 while Sloc_Trace (Res) = ' ' loop
kono
parents:
diff changeset
627 Res := Res + 1;
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 if Res > Last then
kono
parents:
diff changeset
630 Res := 0;
kono
parents:
diff changeset
631 exit;
kono
parents:
diff changeset
632 end if;
kono
parents:
diff changeset
633 end loop;
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 return Res;
kono
parents:
diff changeset
636 end Skip_Spaces;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 begin
kono
parents:
diff changeset
639 P := Sloc (E);
kono
parents:
diff changeset
640 Sindex := Get_Source_File_Index (P);
kono
parents:
diff changeset
641 Get_Name_String (File_Name (Sindex));
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 Idx := Skip_Spaces;
kono
parents:
diff changeset
644 while Idx > 0 loop
kono
parents:
diff changeset
645 if not File_Name_Match then
kono
parents:
diff changeset
646 goto Continue;
kono
parents:
diff changeset
647 elsif not Line_Num_Match then
kono
parents:
diff changeset
648 goto Continue;
kono
parents:
diff changeset
649 end if;
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 if Different_Trace_Lengths then
kono
parents:
diff changeset
652 goto Continue;
kono
parents:
diff changeset
653 end if;
kono
parents:
diff changeset
654 end loop;
kono
parents:
diff changeset
655 end;
kono
parents:
diff changeset
656 end if;
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 -- If we have a Result_Type, then we must have a function with
kono
parents:
diff changeset
659 -- the proper result type.
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 if Elmt.Result_Type /= No_Name then
kono
parents:
diff changeset
662 if Ekind (E) /= E_Function
kono
parents:
diff changeset
663 or else Chars (Etype (E)) /= Elmt.Result_Type
kono
parents:
diff changeset
664 then
kono
parents:
diff changeset
665 goto Continue;
kono
parents:
diff changeset
666 end if;
kono
parents:
diff changeset
667 end if;
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 -- If we have Parameter_Types, they must match
kono
parents:
diff changeset
670
kono
parents:
diff changeset
671 if Elmt.Parameter_Types /= null then
kono
parents:
diff changeset
672 Form := First_Formal (E);
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 if No (Form)
kono
parents:
diff changeset
675 and then Elmt.Parameter_Types'Length = 1
kono
parents:
diff changeset
676 and then Elmt.Parameter_Types (1) = No_Name
kono
parents:
diff changeset
677 then
kono
parents:
diff changeset
678 -- Parameterless procedure matches
kono
parents:
diff changeset
679
kono
parents:
diff changeset
680 null;
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 elsif Elmt.Parameter_Types = null then
kono
parents:
diff changeset
683 goto Continue;
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 else
kono
parents:
diff changeset
686 for J in Elmt.Parameter_Types'Range loop
kono
parents:
diff changeset
687 if No (Form)
kono
parents:
diff changeset
688 or else
kono
parents:
diff changeset
689 Chars (Etype (Form)) /= Elmt.Parameter_Types (J)
kono
parents:
diff changeset
690 then
kono
parents:
diff changeset
691 goto Continue;
kono
parents:
diff changeset
692 else
kono
parents:
diff changeset
693 Next_Formal (Form);
kono
parents:
diff changeset
694 end if;
kono
parents:
diff changeset
695 end loop;
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 if Present (Form) then
kono
parents:
diff changeset
698 goto Continue;
kono
parents:
diff changeset
699 end if;
kono
parents:
diff changeset
700 end if;
kono
parents:
diff changeset
701 end if;
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 -- If we fall through, this is match
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 Set_Eliminated;
kono
parents:
diff changeset
706 return;
kono
parents:
diff changeset
707 end if;
kono
parents:
diff changeset
708 end Check_Homonyms;
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 <<Continue>>
kono
parents:
diff changeset
711 Elmt := Elmt.Homonym;
kono
parents:
diff changeset
712 end loop;
kono
parents:
diff changeset
713
kono
parents:
diff changeset
714 return;
kono
parents:
diff changeset
715 end Check_Eliminated;
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 -------------------------------------
kono
parents:
diff changeset
718 -- Check_For_Eliminated_Subprogram --
kono
parents:
diff changeset
719 -------------------------------------
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 procedure Check_For_Eliminated_Subprogram (N : Node_Id; S : Entity_Id) is
kono
parents:
diff changeset
722 Ultimate_Subp : constant Entity_Id := Ultimate_Alias (S);
kono
parents:
diff changeset
723 Enclosing_Subp : Entity_Id;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 begin
kono
parents:
diff changeset
726 -- No check needed within a default expression for a formal, since this
kono
parents:
diff changeset
727 -- is not really a use, and the expression (a call or attribute) may
kono
parents:
diff changeset
728 -- never be used if the enclosing subprogram is itself eliminated.
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 if In_Spec_Expression then
kono
parents:
diff changeset
731 return;
kono
parents:
diff changeset
732 end if;
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 if Is_Eliminated (Ultimate_Subp)
kono
parents:
diff changeset
735 and then not Inside_A_Generic
kono
parents:
diff changeset
736 and then not Is_Generic_Unit (Cunit_Entity (Current_Sem_Unit))
kono
parents:
diff changeset
737 then
kono
parents:
diff changeset
738 Enclosing_Subp := Current_Subprogram;
kono
parents:
diff changeset
739 while Present (Enclosing_Subp) loop
kono
parents:
diff changeset
740 if Is_Eliminated (Enclosing_Subp) then
kono
parents:
diff changeset
741 return;
kono
parents:
diff changeset
742 end if;
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 Enclosing_Subp := Enclosing_Subprogram (Enclosing_Subp);
kono
parents:
diff changeset
745 end loop;
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 -- Emit error, unless we are within an instance body and the expander
kono
parents:
diff changeset
748 -- is disabled, indicating an instance within an enclosing generic.
kono
parents:
diff changeset
749 -- In an instance, the ultimate alias is an internal entity, so place
kono
parents:
diff changeset
750 -- the message on the original subprogram.
kono
parents:
diff changeset
751
kono
parents:
diff changeset
752 if In_Instance_Body and then not Expander_Active then
kono
parents:
diff changeset
753 null;
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 elsif Comes_From_Source (Ultimate_Subp) then
kono
parents:
diff changeset
756 Eliminate_Error_Msg (N, Ultimate_Subp);
kono
parents:
diff changeset
757
kono
parents:
diff changeset
758 else
kono
parents:
diff changeset
759 Eliminate_Error_Msg (N, S);
kono
parents:
diff changeset
760 end if;
kono
parents:
diff changeset
761 end if;
kono
parents:
diff changeset
762 end Check_For_Eliminated_Subprogram;
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 -------------------------
kono
parents:
diff changeset
765 -- Eliminate_Error_Msg --
kono
parents:
diff changeset
766 -------------------------
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 procedure Eliminate_Error_Msg (N : Node_Id; E : Entity_Id) is
kono
parents:
diff changeset
769 begin
kono
parents:
diff changeset
770 for J in Elim_Entities.First .. Elim_Entities.Last loop
kono
parents:
diff changeset
771 if E = Elim_Entities.Table (J).Subp then
kono
parents:
diff changeset
772 Error_Msg_Sloc := Sloc (Elim_Entities.Table (J).Prag);
kono
parents:
diff changeset
773 Error_Msg_NE ("cannot reference subprogram & eliminated #", N, E);
kono
parents:
diff changeset
774 return;
kono
parents:
diff changeset
775 end if;
kono
parents:
diff changeset
776 end loop;
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 -- If this is an internal operation generated for a protected operation,
kono
parents:
diff changeset
779 -- its name does not match the source name, so just report the error.
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 if not Comes_From_Source (E)
kono
parents:
diff changeset
782 and then Present (First_Entity (E))
kono
parents:
diff changeset
783 and then Is_Concurrent_Record_Type (Etype (First_Entity (E)))
kono
parents:
diff changeset
784 then
kono
parents:
diff changeset
785 Error_Msg_NE
kono
parents:
diff changeset
786 ("cannot reference eliminated protected subprogram", N, E);
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 -- Otherwise should not fall through, entry should be in table
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 else
kono
parents:
diff changeset
791 Error_Msg_NE
kono
parents:
diff changeset
792 ("subprogram& is called but its alias is eliminated", N, E);
kono
parents:
diff changeset
793 -- raise Program_Error;
kono
parents:
diff changeset
794 end if;
kono
parents:
diff changeset
795 end Eliminate_Error_Msg;
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 ----------------
kono
parents:
diff changeset
798 -- Initialize --
kono
parents:
diff changeset
799 ----------------
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 procedure Initialize is
kono
parents:
diff changeset
802 begin
kono
parents:
diff changeset
803 Elim_Hash_Table.Reset;
kono
parents:
diff changeset
804 Elim_Entities.Init;
kono
parents:
diff changeset
805 No_Elimination := True;
kono
parents:
diff changeset
806 end Initialize;
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 ------------------------------
kono
parents:
diff changeset
809 -- Process_Eliminate_Pragma --
kono
parents:
diff changeset
810 ------------------------------
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 procedure Process_Eliminate_Pragma
kono
parents:
diff changeset
813 (Pragma_Node : Node_Id;
kono
parents:
diff changeset
814 Arg_Unit_Name : Node_Id;
kono
parents:
diff changeset
815 Arg_Entity : Node_Id;
kono
parents:
diff changeset
816 Arg_Parameter_Types : Node_Id;
kono
parents:
diff changeset
817 Arg_Result_Type : Node_Id;
kono
parents:
diff changeset
818 Arg_Source_Location : Node_Id)
kono
parents:
diff changeset
819 is
kono
parents:
diff changeset
820 Data : constant Access_Elim_Data := new Elim_Data;
kono
parents:
diff changeset
821 -- Build result data here
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 Elmt : Access_Elim_Data;
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 Num_Names : Nat := 0;
kono
parents:
diff changeset
826 -- Number of names in unit name
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 Lit : Node_Id;
kono
parents:
diff changeset
829 Arg_Ent : Entity_Id;
kono
parents:
diff changeset
830 Arg_Uname : Node_Id;
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 function OK_Selected_Component (N : Node_Id) return Boolean;
kono
parents:
diff changeset
833 -- Test if N is a selected component with all identifiers, or a selected
kono
parents:
diff changeset
834 -- component whose selector is an operator symbol. As a side effect
kono
parents:
diff changeset
835 -- if result is True, sets Num_Names to the number of names present
kono
parents:
diff changeset
836 -- (identifiers, and operator if any).
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 ---------------------------
kono
parents:
diff changeset
839 -- OK_Selected_Component --
kono
parents:
diff changeset
840 ---------------------------
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 function OK_Selected_Component (N : Node_Id) return Boolean is
kono
parents:
diff changeset
843 begin
kono
parents:
diff changeset
844 if Nkind (N) = N_Identifier
kono
parents:
diff changeset
845 or else Nkind (N) = N_Operator_Symbol
kono
parents:
diff changeset
846 then
kono
parents:
diff changeset
847 Num_Names := Num_Names + 1;
kono
parents:
diff changeset
848 return True;
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 elsif Nkind (N) = N_Selected_Component then
kono
parents:
diff changeset
851 return OK_Selected_Component (Prefix (N))
kono
parents:
diff changeset
852 and then OK_Selected_Component (Selector_Name (N));
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 else
kono
parents:
diff changeset
855 return False;
kono
parents:
diff changeset
856 end if;
kono
parents:
diff changeset
857 end OK_Selected_Component;
kono
parents:
diff changeset
858
kono
parents:
diff changeset
859 -- Start of processing for Process_Eliminate_Pragma
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 begin
kono
parents:
diff changeset
862 Data.Prag := Pragma_Node;
kono
parents:
diff changeset
863 Error_Msg_Name_1 := Name_Eliminate;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 -- Process Unit_Name argument
kono
parents:
diff changeset
866
kono
parents:
diff changeset
867 if Nkind (Arg_Unit_Name) = N_Identifier then
kono
parents:
diff changeset
868 Data.Unit_Name := new Names'(1 => Chars (Arg_Unit_Name));
kono
parents:
diff changeset
869 Num_Names := 1;
kono
parents:
diff changeset
870
kono
parents:
diff changeset
871 elsif OK_Selected_Component (Arg_Unit_Name) then
kono
parents:
diff changeset
872 Data.Unit_Name := new Names (1 .. Num_Names);
kono
parents:
diff changeset
873
kono
parents:
diff changeset
874 Arg_Uname := Arg_Unit_Name;
kono
parents:
diff changeset
875 for J in reverse 2 .. Num_Names loop
kono
parents:
diff changeset
876 Data.Unit_Name (J) := Chars (Selector_Name (Arg_Uname));
kono
parents:
diff changeset
877 Arg_Uname := Prefix (Arg_Uname);
kono
parents:
diff changeset
878 end loop;
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 Data.Unit_Name (1) := Chars (Arg_Uname);
kono
parents:
diff changeset
881
kono
parents:
diff changeset
882 else
kono
parents:
diff changeset
883 Error_Msg_N
kono
parents:
diff changeset
884 ("wrong form for Unit_Name parameter of pragma%", Arg_Unit_Name);
kono
parents:
diff changeset
885 return;
kono
parents:
diff changeset
886 end if;
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 -- Process Entity argument
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 if Present (Arg_Entity) then
kono
parents:
diff changeset
891 Num_Names := 0;
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 if Nkind (Arg_Entity) = N_Identifier
kono
parents:
diff changeset
894 or else Nkind (Arg_Entity) = N_Operator_Symbol
kono
parents:
diff changeset
895 then
kono
parents:
diff changeset
896 Data.Entity_Name := Chars (Arg_Entity);
kono
parents:
diff changeset
897 Data.Entity_Node := Arg_Entity;
kono
parents:
diff changeset
898 Data.Entity_Scope := null;
kono
parents:
diff changeset
899
kono
parents:
diff changeset
900 elsif OK_Selected_Component (Arg_Entity) then
kono
parents:
diff changeset
901 Data.Entity_Scope := new Names (1 .. Num_Names - 1);
kono
parents:
diff changeset
902 Data.Entity_Name := Chars (Selector_Name (Arg_Entity));
kono
parents:
diff changeset
903 Data.Entity_Node := Arg_Entity;
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 Arg_Ent := Prefix (Arg_Entity);
kono
parents:
diff changeset
906 for J in reverse 2 .. Num_Names - 1 loop
kono
parents:
diff changeset
907 Data.Entity_Scope (J) := Chars (Selector_Name (Arg_Ent));
kono
parents:
diff changeset
908 Arg_Ent := Prefix (Arg_Ent);
kono
parents:
diff changeset
909 end loop;
kono
parents:
diff changeset
910
kono
parents:
diff changeset
911 Data.Entity_Scope (1) := Chars (Arg_Ent);
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 elsif Is_Config_Static_String (Arg_Entity) then
kono
parents:
diff changeset
914 Data.Entity_Name := Name_Find;
kono
parents:
diff changeset
915 Data.Entity_Node := Arg_Entity;
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 else
kono
parents:
diff changeset
918 return;
kono
parents:
diff changeset
919 end if;
kono
parents:
diff changeset
920 else
kono
parents:
diff changeset
921 Data.Entity_Node := Empty;
kono
parents:
diff changeset
922 Data.Entity_Name := Data.Unit_Name (Num_Names);
kono
parents:
diff changeset
923 end if;
kono
parents:
diff changeset
924
kono
parents:
diff changeset
925 -- Process Parameter_Types argument
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 if Present (Arg_Parameter_Types) then
kono
parents:
diff changeset
928
kono
parents:
diff changeset
929 -- Here for aggregate case
kono
parents:
diff changeset
930
kono
parents:
diff changeset
931 if Nkind (Arg_Parameter_Types) = N_Aggregate then
kono
parents:
diff changeset
932 Data.Parameter_Types :=
kono
parents:
diff changeset
933 new Names
kono
parents:
diff changeset
934 (1 .. List_Length (Expressions (Arg_Parameter_Types)));
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 Lit := First (Expressions (Arg_Parameter_Types));
kono
parents:
diff changeset
937 for J in Data.Parameter_Types'Range loop
kono
parents:
diff changeset
938 if Is_Config_Static_String (Lit) then
kono
parents:
diff changeset
939 Data.Parameter_Types (J) := Name_Find;
kono
parents:
diff changeset
940 Next (Lit);
kono
parents:
diff changeset
941 else
kono
parents:
diff changeset
942 return;
kono
parents:
diff changeset
943 end if;
kono
parents:
diff changeset
944 end loop;
kono
parents:
diff changeset
945
kono
parents:
diff changeset
946 -- Otherwise we must have case of one name, which looks like a
kono
parents:
diff changeset
947 -- parenthesized literal rather than an aggregate.
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 elsif Paren_Count (Arg_Parameter_Types) /= 1 then
kono
parents:
diff changeset
950 Error_Msg_N
kono
parents:
diff changeset
951 ("wrong form for argument of pragma Eliminate",
kono
parents:
diff changeset
952 Arg_Parameter_Types);
kono
parents:
diff changeset
953 return;
kono
parents:
diff changeset
954
kono
parents:
diff changeset
955 elsif Is_Config_Static_String (Arg_Parameter_Types) then
kono
parents:
diff changeset
956 String_To_Name_Buffer (Strval (Arg_Parameter_Types));
kono
parents:
diff changeset
957
kono
parents:
diff changeset
958 if Name_Len = 0 then
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 -- Parameterless procedure
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 Data.Parameter_Types := new Names'(1 => No_Name);
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 else
kono
parents:
diff changeset
965 Data.Parameter_Types := new Names'(1 => Name_Find);
kono
parents:
diff changeset
966 end if;
kono
parents:
diff changeset
967
kono
parents:
diff changeset
968 else
kono
parents:
diff changeset
969 return;
kono
parents:
diff changeset
970 end if;
kono
parents:
diff changeset
971 end if;
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973 -- Process Result_Types argument
kono
parents:
diff changeset
974
kono
parents:
diff changeset
975 if Present (Arg_Result_Type) then
kono
parents:
diff changeset
976 if Is_Config_Static_String (Arg_Result_Type) then
kono
parents:
diff changeset
977 Data.Result_Type := Name_Find;
kono
parents:
diff changeset
978 else
kono
parents:
diff changeset
979 return;
kono
parents:
diff changeset
980 end if;
kono
parents:
diff changeset
981
kono
parents:
diff changeset
982 -- Here if no Result_Types argument
kono
parents:
diff changeset
983
kono
parents:
diff changeset
984 else
kono
parents:
diff changeset
985 Data.Result_Type := No_Name;
kono
parents:
diff changeset
986 end if;
kono
parents:
diff changeset
987
kono
parents:
diff changeset
988 -- Process Source_Location argument
kono
parents:
diff changeset
989
kono
parents:
diff changeset
990 if Present (Arg_Source_Location) then
kono
parents:
diff changeset
991 if Is_Config_Static_String (Arg_Source_Location) then
kono
parents:
diff changeset
992 Data.Source_Location := Name_Find;
kono
parents:
diff changeset
993 else
kono
parents:
diff changeset
994 return;
kono
parents:
diff changeset
995 end if;
kono
parents:
diff changeset
996 else
kono
parents:
diff changeset
997 Data.Source_Location := No_Name;
kono
parents:
diff changeset
998 end if;
kono
parents:
diff changeset
999
kono
parents:
diff changeset
1000 Elmt := Elim_Hash_Table.Get (Hash_Subprograms.Get_Key (Data));
kono
parents:
diff changeset
1001
kono
parents:
diff changeset
1002 -- If we already have an entry with this same key, then link
kono
parents:
diff changeset
1003 -- it into the chain of entries for this key.
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 if Elmt /= null then
kono
parents:
diff changeset
1006 Data.Homonym := Elmt.Homonym;
kono
parents:
diff changeset
1007 Elmt.Homonym := Data;
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 -- Otherwise create a new entry
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 else
kono
parents:
diff changeset
1012 Elim_Hash_Table.Set (Data);
kono
parents:
diff changeset
1013 end if;
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 No_Elimination := False;
kono
parents:
diff changeset
1016 end Process_Eliminate_Pragma;
kono
parents:
diff changeset
1017
kono
parents:
diff changeset
1018 end Sem_Elim;