annotate gcc/ada/lib-load.adb @ 143:76e1cf5455ef

add cbc_gc test
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 19:24:05 +0900
parents 84e7813d76e9
children 1830386684a0
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 -- L I B . L O A D --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. --
111
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 Debug; use Debug;
kono
parents:
diff changeset
28 with Einfo; use Einfo;
kono
parents:
diff changeset
29 with Errout; use Errout;
kono
parents:
diff changeset
30 with Fname; use Fname;
kono
parents:
diff changeset
31 with Fname.UF; use Fname.UF;
kono
parents:
diff changeset
32 with Nlists; use Nlists;
kono
parents:
diff changeset
33 with Nmake; use Nmake;
kono
parents:
diff changeset
34 with Opt; use Opt;
kono
parents:
diff changeset
35 with Osint; use Osint;
kono
parents:
diff changeset
36 with Osint.C; use Osint.C;
kono
parents:
diff changeset
37 with Output; use Output;
kono
parents:
diff changeset
38 with Par;
kono
parents:
diff changeset
39 with Restrict; use Restrict;
kono
parents:
diff changeset
40 with Scn; use Scn;
kono
parents:
diff changeset
41 with Sinfo; use Sinfo;
kono
parents:
diff changeset
42 with Sinput; use Sinput;
kono
parents:
diff changeset
43 with Sinput.L; use Sinput.L;
kono
parents:
diff changeset
44 with Stand; use Stand;
kono
parents:
diff changeset
45 with Tbuild; use Tbuild;
kono
parents:
diff changeset
46 with Uname; use Uname;
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 package body Lib.Load is
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 -----------------------
kono
parents:
diff changeset
51 -- Local Subprograms --
kono
parents:
diff changeset
52 -----------------------
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 function From_Limited_With_Chain return Boolean;
kono
parents:
diff changeset
55 -- Check whether a possible circular dependence includes units that
kono
parents:
diff changeset
56 -- have been loaded through limited_with clauses, in which case there
kono
parents:
diff changeset
57 -- is no real circularity.
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 function Spec_Is_Irrelevant
kono
parents:
diff changeset
60 (Spec_Unit : Unit_Number_Type;
kono
parents:
diff changeset
61 Body_Unit : Unit_Number_Type) return Boolean;
kono
parents:
diff changeset
62 -- The Spec_Unit and Body_Unit parameters are the unit numbers of the
kono
parents:
diff changeset
63 -- spec file that corresponds to the main unit which is a body. This
kono
parents:
diff changeset
64 -- function determines if the spec file is irrelevant and will be
kono
parents:
diff changeset
65 -- overridden by the body as described in RM 10.1.4(4). See description
kono
parents:
diff changeset
66 -- in "Special Handling of Subprogram Bodies" for further details.
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 procedure Write_Dependency_Chain;
kono
parents:
diff changeset
69 -- This procedure is used to generate error message info lines that
kono
parents:
diff changeset
70 -- trace the current dependency chain when a load error occurs.
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 ------------------------------
kono
parents:
diff changeset
73 -- Change_Main_Unit_To_Spec --
kono
parents:
diff changeset
74 ------------------------------
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 procedure Change_Main_Unit_To_Spec is
kono
parents:
diff changeset
77 U : Unit_Record renames Units.Table (Main_Unit);
kono
parents:
diff changeset
78 N : File_Name_Type;
kono
parents:
diff changeset
79 X : Source_File_Index;
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 begin
kono
parents:
diff changeset
82 -- Get name of unit body
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 Get_Name_String (U.Unit_File_Name);
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 -- Note: for the following we should really generalize and consult the
kono
parents:
diff changeset
87 -- file name pattern data, but for now we just deal with the common
kono
parents:
diff changeset
88 -- naming cases, which is probably good enough in practice ???
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 -- Change .adb to .ads
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 if Name_Len >= 5
kono
parents:
diff changeset
93 and then Name_Buffer (Name_Len - 3 .. Name_Len) = ".adb"
kono
parents:
diff changeset
94 then
kono
parents:
diff changeset
95 Name_Buffer (Name_Len) := 's';
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 -- Change .2.ada to .1.ada (Rational convention)
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 elsif Name_Len >= 7
kono
parents:
diff changeset
100 and then Name_Buffer (Name_Len - 5 .. Name_Len) = ".2.ada"
kono
parents:
diff changeset
101 then
kono
parents:
diff changeset
102 Name_Buffer (Name_Len - 4) := '1';
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 -- Change .ada to _.ada (DEC convention)
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 elsif Name_Len >= 5
kono
parents:
diff changeset
107 and then Name_Buffer (Name_Len - 3 .. Name_Len) = ".ada"
kono
parents:
diff changeset
108 then
kono
parents:
diff changeset
109 Name_Buffer (Name_Len - 3 .. Name_Len + 1) := "_.ada";
kono
parents:
diff changeset
110 Name_Len := Name_Len + 1;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 -- No match, don't make the change
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 else
kono
parents:
diff changeset
115 return;
kono
parents:
diff changeset
116 end if;
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 -- Try loading the spec
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 N := Name_Find;
kono
parents:
diff changeset
121 X := Load_Source_File (N);
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 -- No change if we did not find the spec
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 if X <= No_Source_File then
kono
parents:
diff changeset
126 return;
kono
parents:
diff changeset
127 end if;
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 -- Otherwise modify Main_Unit entry to point to spec
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 U.Unit_File_Name := N;
kono
parents:
diff changeset
132 U.Source_Index := X;
kono
parents:
diff changeset
133 end Change_Main_Unit_To_Spec;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 -------------------------------
kono
parents:
diff changeset
136 -- Create_Dummy_Package_Unit --
kono
parents:
diff changeset
137 -------------------------------
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 function Create_Dummy_Package_Unit
kono
parents:
diff changeset
140 (With_Node : Node_Id;
kono
parents:
diff changeset
141 Spec_Name : Unit_Name_Type) return Unit_Number_Type
kono
parents:
diff changeset
142 is
kono
parents:
diff changeset
143 Unum : Unit_Number_Type;
kono
parents:
diff changeset
144 Cunit_Entity : Entity_Id;
kono
parents:
diff changeset
145 Cunit : Node_Id;
kono
parents:
diff changeset
146 Du_Name : Node_Or_Entity_Id;
kono
parents:
diff changeset
147 End_Lab : Node_Id;
kono
parents:
diff changeset
148 Fname : constant File_Name_Type :=
kono
parents:
diff changeset
149 Get_File_Name (Spec_Name, Subunit => False);
kono
parents:
diff changeset
150 Pre_Name : constant Boolean :=
kono
parents:
diff changeset
151 Is_Predefined_File_Name (Fname, Renamings_Included => False);
kono
parents:
diff changeset
152 Ren_Name : constant Boolean :=
kono
parents:
diff changeset
153 Is_Predefined_Renaming_File_Name (Fname);
kono
parents:
diff changeset
154 GNAT_Name : constant Boolean :=
kono
parents:
diff changeset
155 Is_GNAT_File_Name (Fname);
kono
parents:
diff changeset
156 Save_CS : constant Boolean := Get_Comes_From_Source_Default;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 begin
kono
parents:
diff changeset
159 -- The created dummy package unit does not come from source
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 Set_Comes_From_Source_Default (False);
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 -- Normal package
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 if Nkind (Name (With_Node)) = N_Identifier then
kono
parents:
diff changeset
166 Cunit_Entity :=
kono
parents:
diff changeset
167 Make_Defining_Identifier (No_Location,
kono
parents:
diff changeset
168 Chars => Chars (Name (With_Node)));
kono
parents:
diff changeset
169 Du_Name := Cunit_Entity;
kono
parents:
diff changeset
170 End_Lab := New_Occurrence_Of (Cunit_Entity, No_Location);
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 -- Child package
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 else
kono
parents:
diff changeset
175 Cunit_Entity :=
kono
parents:
diff changeset
176 Make_Defining_Identifier (No_Location,
kono
parents:
diff changeset
177 Chars => Chars (Selector_Name (Name (With_Node))));
kono
parents:
diff changeset
178 Du_Name :=
kono
parents:
diff changeset
179 Make_Defining_Program_Unit_Name (No_Location,
kono
parents:
diff changeset
180 Name => Copy_Separate_Tree (Prefix (Name (With_Node))),
kono
parents:
diff changeset
181 Defining_Identifier => Cunit_Entity);
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 Set_Is_Child_Unit (Cunit_Entity);
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 End_Lab :=
kono
parents:
diff changeset
186 Make_Designator (No_Location,
kono
parents:
diff changeset
187 Name => Copy_Separate_Tree (Prefix (Name (With_Node))),
kono
parents:
diff changeset
188 Identifier => New_Occurrence_Of (Cunit_Entity, No_Location));
kono
parents:
diff changeset
189 end if;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 Set_Scope (Cunit_Entity, Standard_Standard);
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 Cunit :=
kono
parents:
diff changeset
194 Make_Compilation_Unit (No_Location,
kono
parents:
diff changeset
195 Context_Items => Empty_List,
kono
parents:
diff changeset
196 Unit =>
kono
parents:
diff changeset
197 Make_Package_Declaration (No_Location,
kono
parents:
diff changeset
198 Specification =>
kono
parents:
diff changeset
199 Make_Package_Specification (No_Location,
kono
parents:
diff changeset
200 Defining_Unit_Name => Du_Name,
kono
parents:
diff changeset
201 Visible_Declarations => Empty_List,
kono
parents:
diff changeset
202 End_Label => End_Lab)),
kono
parents:
diff changeset
203 Aux_Decls_Node =>
kono
parents:
diff changeset
204 Make_Compilation_Unit_Aux (No_Location));
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 -- Mark the dummy package as analyzed to prevent analysis of this
kono
parents:
diff changeset
207 -- (non-existent) unit in -gnatQ mode because at the moment the
kono
parents:
diff changeset
208 -- structure and attributes of this dummy package does not allow
kono
parents:
diff changeset
209 -- a normal analysis of this unit
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 Set_Analyzed (Cunit);
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 Units.Increment_Last;
kono
parents:
diff changeset
214 Unum := Units.Last;
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 Units.Table (Unum) :=
kono
parents:
diff changeset
217 (Cunit => Cunit,
kono
parents:
diff changeset
218 Cunit_Entity => Cunit_Entity,
kono
parents:
diff changeset
219 Dependency_Num => 0,
kono
parents:
diff changeset
220 Dynamic_Elab => False,
kono
parents:
diff changeset
221 Error_Location => Sloc (With_Node),
kono
parents:
diff changeset
222 Expected_Unit => Spec_Name,
kono
parents:
diff changeset
223 Fatal_Error => Error_Detected,
kono
parents:
diff changeset
224 Generate_Code => False,
kono
parents:
diff changeset
225 Has_RACW => False,
kono
parents:
diff changeset
226 Filler => False,
kono
parents:
diff changeset
227 Ident_String => Empty,
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 Is_Predefined_Renaming => Ren_Name,
kono
parents:
diff changeset
230 Is_Predefined_Unit => Pre_Name or Ren_Name,
kono
parents:
diff changeset
231 Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name,
kono
parents:
diff changeset
232 Filler2 => False,
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 Loading => False,
kono
parents:
diff changeset
235 Main_Priority => Default_Main_Priority,
kono
parents:
diff changeset
236 Main_CPU => Default_Main_CPU,
kono
parents:
diff changeset
237 Primary_Stack_Count => 0,
kono
parents:
diff changeset
238 Sec_Stack_Count => 0,
kono
parents:
diff changeset
239 Munit_Index => 0,
kono
parents:
diff changeset
240 No_Elab_Code_All => False,
kono
parents:
diff changeset
241 Serial_Number => 0,
kono
parents:
diff changeset
242 Source_Index => No_Source_File,
kono
parents:
diff changeset
243 Unit_File_Name => Fname,
kono
parents:
diff changeset
244 Unit_Name => Spec_Name,
kono
parents:
diff changeset
245 Version => 0,
kono
parents:
diff changeset
246 OA_Setting => 'O');
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 Set_Comes_From_Source_Default (Save_CS);
kono
parents:
diff changeset
249 Set_Error_Posted (Cunit_Entity);
kono
parents:
diff changeset
250 Set_Error_Posted (Cunit);
kono
parents:
diff changeset
251 return Unum;
kono
parents:
diff changeset
252 end Create_Dummy_Package_Unit;
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 -----------------------------
kono
parents:
diff changeset
255 -- From_Limited_With_Chain --
kono
parents:
diff changeset
256 -----------------------------
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 function From_Limited_With_Chain return Boolean is
kono
parents:
diff changeset
259 Curr_Num : constant Unit_Number_Type :=
kono
parents:
diff changeset
260 Load_Stack.Table (Load_Stack.Last).Unit_Number;
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 begin
kono
parents:
diff changeset
263 -- True if the current load operation is through a limited_with clause
kono
parents:
diff changeset
264 -- and we are not within a loop of regular with_clauses.
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 for U in reverse Load_Stack.First .. Load_Stack.Last - 1 loop
kono
parents:
diff changeset
267 if Load_Stack.Table (U).Unit_Number = Curr_Num then
kono
parents:
diff changeset
268 return False;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 elsif Present (Load_Stack.Table (U).With_Node)
kono
parents:
diff changeset
271 and then Limited_Present (Load_Stack.Table (U).With_Node)
kono
parents:
diff changeset
272 then
kono
parents:
diff changeset
273 return True;
kono
parents:
diff changeset
274 end if;
kono
parents:
diff changeset
275 end loop;
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 return False;
kono
parents:
diff changeset
278 end From_Limited_With_Chain;
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 ----------------
kono
parents:
diff changeset
281 -- Initialize --
kono
parents:
diff changeset
282 ----------------
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 procedure Initialize is
kono
parents:
diff changeset
285 begin
kono
parents:
diff changeset
286 Units.Init;
kono
parents:
diff changeset
287 Load_Stack.Init;
kono
parents:
diff changeset
288 end Initialize;
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 ------------------------
kono
parents:
diff changeset
291 -- Initialize_Version --
kono
parents:
diff changeset
292 ------------------------
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 procedure Initialize_Version (U : Unit_Number_Type) is
kono
parents:
diff changeset
295 begin
kono
parents:
diff changeset
296 Units.Table (U).Version := Source_Checksum (Source_Index (U));
kono
parents:
diff changeset
297 end Initialize_Version;
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 ----------------------
kono
parents:
diff changeset
300 -- Load_Main_Source --
kono
parents:
diff changeset
301 ----------------------
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 procedure Load_Main_Source is
kono
parents:
diff changeset
304 Fname : constant File_Name_Type := Next_Main_Source;
kono
parents:
diff changeset
305 Pre_Name : constant Boolean :=
kono
parents:
diff changeset
306 Is_Predefined_File_Name (Fname, Renamings_Included => False);
kono
parents:
diff changeset
307 Ren_Name : constant Boolean :=
kono
parents:
diff changeset
308 Is_Predefined_Renaming_File_Name (Fname);
kono
parents:
diff changeset
309 GNAT_Name : constant Boolean :=
kono
parents:
diff changeset
310 Is_GNAT_File_Name (Fname);
kono
parents:
diff changeset
311 Version : Word := 0;
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 begin
kono
parents:
diff changeset
314 Load_Stack.Increment_Last;
kono
parents:
diff changeset
315 Load_Stack.Table (Load_Stack.Last) := (Main_Unit, Empty);
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 -- Initialize unit table entry for Main_Unit. Note that we don't know
kono
parents:
diff changeset
318 -- the unit name yet, that gets filled in when the parser parses the
kono
parents:
diff changeset
319 -- main unit, at which time a check is made that it matches the main
kono
parents:
diff changeset
320 -- file name, and then the Unit_Name field is set. The Cunit and
kono
parents:
diff changeset
321 -- Cunit_Entity fields also get filled in later by the parser.
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 Units.Increment_Last;
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 Units.Table (Main_Unit).Unit_File_Name := Fname;
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 if Fname /= No_File then
kono
parents:
diff changeset
328 Main_Source_File := Load_Source_File (Fname);
kono
parents:
diff changeset
329 Current_Error_Source_File := Main_Source_File;
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 if Main_Source_File > No_Source_File then
kono
parents:
diff changeset
332 Version := Source_Checksum (Main_Source_File);
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 else
kono
parents:
diff changeset
335 -- To avoid emitting a source location (since there is no file),
kono
parents:
diff changeset
336 -- we write a custom error message instead of using the machinery
kono
parents:
diff changeset
337 -- in errout.adb.
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 Set_Standard_Error;
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 if Main_Source_File = No_Access_To_Source_File then
kono
parents:
diff changeset
342 Write_Str
kono
parents:
diff changeset
343 ("no read access for file """ & Get_Name_String (Fname)
kono
parents:
diff changeset
344 & """");
kono
parents:
diff changeset
345 else
kono
parents:
diff changeset
346 Write_Str
kono
parents:
diff changeset
347 ("file """ & Get_Name_String (Fname) & """ not found");
kono
parents:
diff changeset
348 end if;
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 Write_Eol;
kono
parents:
diff changeset
351 Set_Standard_Output;
kono
parents:
diff changeset
352 end if;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 Units.Table (Main_Unit) :=
kono
parents:
diff changeset
355 (Cunit => Empty,
kono
parents:
diff changeset
356 Cunit_Entity => Empty,
kono
parents:
diff changeset
357 Dependency_Num => 0,
kono
parents:
diff changeset
358 Dynamic_Elab => False,
kono
parents:
diff changeset
359 Error_Location => No_Location,
kono
parents:
diff changeset
360 Expected_Unit => No_Unit_Name,
kono
parents:
diff changeset
361 Fatal_Error => None,
kono
parents:
diff changeset
362 Generate_Code => False,
kono
parents:
diff changeset
363 Has_RACW => False,
kono
parents:
diff changeset
364 Filler => False,
kono
parents:
diff changeset
365 Ident_String => Empty,
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 Is_Predefined_Renaming => Ren_Name,
kono
parents:
diff changeset
368 Is_Predefined_Unit => Pre_Name or Ren_Name,
kono
parents:
diff changeset
369 Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name,
kono
parents:
diff changeset
370 Filler2 => False,
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 Loading => True,
kono
parents:
diff changeset
373 Main_Priority => Default_Main_Priority,
kono
parents:
diff changeset
374 Main_CPU => Default_Main_CPU,
kono
parents:
diff changeset
375 Primary_Stack_Count => 0,
kono
parents:
diff changeset
376 Sec_Stack_Count => 0,
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 Munit_Index => 0,
kono
parents:
diff changeset
379 No_Elab_Code_All => False,
kono
parents:
diff changeset
380 Serial_Number => 0,
kono
parents:
diff changeset
381 Source_Index => Main_Source_File,
kono
parents:
diff changeset
382 Unit_File_Name => Fname,
kono
parents:
diff changeset
383 Unit_Name => No_Unit_Name,
kono
parents:
diff changeset
384 Version => Version,
kono
parents:
diff changeset
385 OA_Setting => 'O');
kono
parents:
diff changeset
386 end if;
kono
parents:
diff changeset
387 end Load_Main_Source;
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 ---------------
kono
parents:
diff changeset
390 -- Load_Unit --
kono
parents:
diff changeset
391 ---------------
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 function Load_Unit
kono
parents:
diff changeset
394 (Load_Name : Unit_Name_Type;
kono
parents:
diff changeset
395 Required : Boolean;
kono
parents:
diff changeset
396 Error_Node : Node_Id;
kono
parents:
diff changeset
397 Subunit : Boolean;
kono
parents:
diff changeset
398 Corr_Body : Unit_Number_Type := No_Unit;
kono
parents:
diff changeset
399 Renamings : Boolean := False;
kono
parents:
diff changeset
400 With_Node : Node_Id := Empty;
kono
parents:
diff changeset
401 PMES : Boolean := False) return Unit_Number_Type
kono
parents:
diff changeset
402 is
kono
parents:
diff changeset
403 Calling_Unit : Unit_Number_Type;
kono
parents:
diff changeset
404 Uname_Actual : Unit_Name_Type;
kono
parents:
diff changeset
405 Unum : Unit_Number_Type;
kono
parents:
diff changeset
406 Unump : Unit_Number_Type;
kono
parents:
diff changeset
407 Fname : File_Name_Type;
kono
parents:
diff changeset
408 Pre_Name : Boolean;
kono
parents:
diff changeset
409 Ren_Name : Boolean;
kono
parents:
diff changeset
410 GNAT_Name : Boolean;
kono
parents:
diff changeset
411 Src_Ind : Source_File_Index;
kono
parents:
diff changeset
412 Save_PMES : constant Boolean := Parsing_Main_Extended_Source;
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 Save_Cunit_Restrictions : constant Save_Cunit_Boolean_Restrictions :=
kono
parents:
diff changeset
415 Cunit_Boolean_Restrictions_Save;
kono
parents:
diff changeset
416 -- Save current restrictions for restore at end
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 begin
kono
parents:
diff changeset
419 Parsing_Main_Extended_Source := PMES;
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 -- Initialize restrictions to config restrictions for unit to load if
kono
parents:
diff changeset
422 -- it is part of the main extended source, otherwise reset them.
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 -- Note: it's a bit odd but PMES is False for subunits, which is why
kono
parents:
diff changeset
425 -- we have the OR here. Should be investigated some time???
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 if PMES or Subunit then
kono
parents:
diff changeset
428 Restore_Config_Cunit_Boolean_Restrictions;
kono
parents:
diff changeset
429 else
kono
parents:
diff changeset
430 Reset_Cunit_Boolean_Restrictions;
kono
parents:
diff changeset
431 end if;
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 -- If renamings are allowed and we have a child unit name, then we
kono
parents:
diff changeset
434 -- must first load the parent to deal with finding the real name.
kono
parents:
diff changeset
435 -- Retain the with_clause that names the child, so that if it is
kono
parents:
diff changeset
436 -- limited, the parent is loaded under the same condition.
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 if Renamings and then Is_Child_Name (Load_Name) then
kono
parents:
diff changeset
439 Unump :=
kono
parents:
diff changeset
440 Load_Unit
kono
parents:
diff changeset
441 (Load_Name => Get_Parent_Spec_Name (Load_Name),
kono
parents:
diff changeset
442 Required => Required,
kono
parents:
diff changeset
443 Subunit => False,
kono
parents:
diff changeset
444 Renamings => True,
kono
parents:
diff changeset
445 Error_Node => Error_Node,
kono
parents:
diff changeset
446 With_Node => With_Node);
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 if Unump = No_Unit then
kono
parents:
diff changeset
449 Parsing_Main_Extended_Source := Save_PMES;
kono
parents:
diff changeset
450 return No_Unit;
kono
parents:
diff changeset
451 end if;
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 -- If parent is a renaming, then we use the renamed package as
kono
parents:
diff changeset
454 -- the actual parent for the subsequent load operation.
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 if Nkind (Unit (Cunit (Unump))) = N_Package_Renaming_Declaration then
kono
parents:
diff changeset
457 Uname_Actual :=
kono
parents:
diff changeset
458 New_Child
kono
parents:
diff changeset
459 (Load_Name, Get_Unit_Name (Name (Unit (Cunit (Unump)))));
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 -- If the load is for a with_clause, for visibility purposes both
kono
parents:
diff changeset
462 -- the renamed entity and renaming one must be available in the
kono
parents:
diff changeset
463 -- current unit: the renamed one in order to retrieve the child
kono
parents:
diff changeset
464 -- unit, and the original one because it may be used as a prefix
kono
parents:
diff changeset
465 -- in the body of the current unit. We add an explicit with_clause
kono
parents:
diff changeset
466 -- for the original parent so that the renaming declaration is
kono
parents:
diff changeset
467 -- properly loaded and analyzed.
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 if Present (With_Node) then
kono
parents:
diff changeset
470 Insert_After (With_Node,
kono
parents:
diff changeset
471 Make_With_Clause (Sloc (With_Node),
kono
parents:
diff changeset
472 Name => Copy_Separate_Tree (Prefix (Name (With_Node)))));
kono
parents:
diff changeset
473 end if;
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 -- Save the renaming entity, to establish its visibility when
kono
parents:
diff changeset
476 -- installing the context. The implicit with is on this entity,
kono
parents:
diff changeset
477 -- not on the package it renames. This is somewhat redundant given
kono
parents:
diff changeset
478 -- the with_clause just created, but it simplifies subsequent
kono
parents:
diff changeset
479 -- expansion of the current with_clause. Optimizable ???
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 if Nkind (Error_Node) = N_With_Clause
kono
parents:
diff changeset
482 and then Nkind (Name (Error_Node)) = N_Selected_Component
kono
parents:
diff changeset
483 then
kono
parents:
diff changeset
484 declare
kono
parents:
diff changeset
485 Par : Node_Id := Name (Error_Node);
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 begin
kono
parents:
diff changeset
488 while Nkind (Par) = N_Selected_Component
kono
parents:
diff changeset
489 and then Chars (Selector_Name (Par)) /=
kono
parents:
diff changeset
490 Chars (Cunit_Entity (Unump))
kono
parents:
diff changeset
491 loop
kono
parents:
diff changeset
492 Par := Prefix (Par);
kono
parents:
diff changeset
493 end loop;
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 -- Case of some intermediate parent is a renaming
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 if Nkind (Par) = N_Selected_Component then
kono
parents:
diff changeset
498 Set_Entity (Selector_Name (Par), Cunit_Entity (Unump));
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 -- Case where the ultimate parent is a renaming
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 else
kono
parents:
diff changeset
503 Set_Entity (Par, Cunit_Entity (Unump));
kono
parents:
diff changeset
504 end if;
kono
parents:
diff changeset
505 end;
kono
parents:
diff changeset
506 end if;
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 -- If the parent is not a renaming, then get its name (this may
kono
parents:
diff changeset
509 -- be different from the parent spec name obtained above because
kono
parents:
diff changeset
510 -- of renamings higher up in the hierarchy).
kono
parents:
diff changeset
511
kono
parents:
diff changeset
512 else
kono
parents:
diff changeset
513 Uname_Actual := New_Child (Load_Name, Unit_Name (Unump));
kono
parents:
diff changeset
514 end if;
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 -- Here if unit to be loaded is not a child unit
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518 else
kono
parents:
diff changeset
519 Uname_Actual := Load_Name;
kono
parents:
diff changeset
520 end if;
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 Fname := Get_File_Name (Uname_Actual, Subunit);
kono
parents:
diff changeset
523 Pre_Name :=
kono
parents:
diff changeset
524 Is_Predefined_File_Name (Fname, Renamings_Included => False);
kono
parents:
diff changeset
525 Ren_Name := Is_Predefined_Renaming_File_Name (Fname);
kono
parents:
diff changeset
526 GNAT_Name := Is_GNAT_File_Name (Fname);
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 if Debug_Flag_L then
kono
parents:
diff changeset
529 Write_Eol;
kono
parents:
diff changeset
530 Write_Str ("*** Load request for unit: ");
kono
parents:
diff changeset
531 Write_Unit_Name (Load_Name);
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 if Required then
kono
parents:
diff changeset
534 Write_Str (" (Required = True)");
kono
parents:
diff changeset
535 else
kono
parents:
diff changeset
536 Write_Str (" (Required = False)");
kono
parents:
diff changeset
537 end if;
kono
parents:
diff changeset
538
kono
parents:
diff changeset
539 Write_Eol;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 if Uname_Actual /= Load_Name then
kono
parents:
diff changeset
542 Write_Str ("*** Actual unit loaded: ");
kono
parents:
diff changeset
543 Write_Unit_Name (Uname_Actual);
kono
parents:
diff changeset
544 end if;
kono
parents:
diff changeset
545 end if;
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 -- Capture error location if it is for the main unit. The idea is to
kono
parents:
diff changeset
548 -- post errors on the main unit location, not the most recent unit.
kono
parents:
diff changeset
549 -- Note: Unit_Name (Main_Unit) is not set if we are parsing gnat.adc.
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 if Present (Error_Node)
kono
parents:
diff changeset
552 and then Unit_Name (Main_Unit) /= No_Unit_Name
kono
parents:
diff changeset
553 then
kono
parents:
diff changeset
554 -- It seems like In_Extended_Main_Source_Unit (Error_Node) would
kono
parents:
diff changeset
555 -- do the trick here, but that's wrong, it is much too early to
kono
parents:
diff changeset
556 -- call this routine. We are still in the parser, and the required
kono
parents:
diff changeset
557 -- semantic information is not established yet. So we base the
kono
parents:
diff changeset
558 -- judgment on unit names.
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 Get_External_Unit_Name_String (Unit_Name (Main_Unit));
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 declare
kono
parents:
diff changeset
563 Main_Unit_Name : constant String := Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565 begin
kono
parents:
diff changeset
566 Get_External_Unit_Name_String
kono
parents:
diff changeset
567 (Unit_Name (Get_Source_Unit (Error_Node)));
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 -- If the two names are identical, then for sure we are part
kono
parents:
diff changeset
570 -- of the extended main unit
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 if Main_Unit_Name = Name_Buffer (1 .. Name_Len) then
kono
parents:
diff changeset
573 Load_Msg_Sloc := Sloc (Error_Node);
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 -- If the load is called from a with_type clause, the error
kono
parents:
diff changeset
576 -- node is correct.
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 -- Otherwise, check for the subunit case, and if so, consider
kono
parents:
diff changeset
579 -- we have a match if one name is a prefix of the other name.
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 else
kono
parents:
diff changeset
582 if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit
kono
parents:
diff changeset
583 or else
kono
parents:
diff changeset
584 Nkind (Unit (Cunit (Get_Source_Unit (Error_Node)))) =
kono
parents:
diff changeset
585 N_Subunit
kono
parents:
diff changeset
586 then
kono
parents:
diff changeset
587 Name_Len := Integer'Min (Name_Len, Main_Unit_Name'Length);
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 if Name_Buffer (1 .. Name_Len)
kono
parents:
diff changeset
590 =
kono
parents:
diff changeset
591 Main_Unit_Name (1 .. Name_Len)
kono
parents:
diff changeset
592 then
kono
parents:
diff changeset
593 Load_Msg_Sloc := Sloc (Error_Node);
kono
parents:
diff changeset
594 end if;
kono
parents:
diff changeset
595 end if;
kono
parents:
diff changeset
596 end if;
kono
parents:
diff changeset
597 end;
kono
parents:
diff changeset
598 end if;
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 -- If we are generating error messages, then capture calling unit
kono
parents:
diff changeset
601
kono
parents:
diff changeset
602 if Present (Error_Node) then
kono
parents:
diff changeset
603 Calling_Unit := Get_Source_Unit (Error_Node);
kono
parents:
diff changeset
604 else
kono
parents:
diff changeset
605 Calling_Unit := No_Unit;
kono
parents:
diff changeset
606 end if;
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 -- See if we already have an entry for this unit
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 Unum := Main_Unit;
kono
parents:
diff changeset
611 while Unum <= Units.Last loop
kono
parents:
diff changeset
612 exit when Uname_Actual = Units.Table (Unum).Unit_Name;
kono
parents:
diff changeset
613 Unum := Unum + 1;
kono
parents:
diff changeset
614 end loop;
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 -- Whether or not the entry was found, Unum is now the right value,
kono
parents:
diff changeset
617 -- since it is one more than Units.Last (i.e. the index of the new
kono
parents:
diff changeset
618 -- entry we will create) in the not found case.
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 -- A special check is necessary in the unit not found case. If the unit
kono
parents:
diff changeset
621 -- is not found, but the file in which it lives has already been loaded,
kono
parents:
diff changeset
622 -- then we have the problem that the file does not contain the unit that
kono
parents:
diff changeset
623 -- is needed. We simply treat this as a file not found condition.
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 -- We skip this test in multiple unit per file mode since in this
kono
parents:
diff changeset
626 -- case we can have multiple units from the same source file.
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 if Unum > Units.Last and then Get_Unit_Index (Uname_Actual) = 0 then
kono
parents:
diff changeset
629 for J in Units.First .. Units.Last loop
kono
parents:
diff changeset
630 if Fname = Units.Table (J).Unit_File_Name then
kono
parents:
diff changeset
631 if Debug_Flag_L then
kono
parents:
diff changeset
632 Write_Str (" file does not contain unit, Unit_Number = ");
kono
parents:
diff changeset
633 Write_Int (Int (Unum));
kono
parents:
diff changeset
634 Write_Eol;
kono
parents:
diff changeset
635 Write_Eol;
kono
parents:
diff changeset
636 end if;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 if Present (Error_Node) then
kono
parents:
diff changeset
639 Get_Name_String (Fname);
kono
parents:
diff changeset
640
kono
parents:
diff changeset
641 if Is_Predefined_File_Name (Fname) then
kono
parents:
diff changeset
642 Error_Msg_Unit_1 := Uname_Actual;
kono
parents:
diff changeset
643 Error_Msg
kono
parents:
diff changeset
644 ("$$ is not a language defined unit", Load_Msg_Sloc);
kono
parents:
diff changeset
645 else
kono
parents:
diff changeset
646 Error_Msg_File_1 := Fname;
kono
parents:
diff changeset
647 Error_Msg_Unit_1 := Uname_Actual;
kono
parents:
diff changeset
648 Error_Msg ("File{ does not contain unit$", Load_Msg_Sloc);
kono
parents:
diff changeset
649 end if;
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 Write_Dependency_Chain;
kono
parents:
diff changeset
652 Unum := No_Unit;
kono
parents:
diff changeset
653 goto Done;
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 else
kono
parents:
diff changeset
656 Unum := No_Unit;
kono
parents:
diff changeset
657 goto Done;
kono
parents:
diff changeset
658 end if;
kono
parents:
diff changeset
659 end if;
kono
parents:
diff changeset
660 end loop;
kono
parents:
diff changeset
661 end if;
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 -- If we are proceeding with load, then make load stack entry,
kono
parents:
diff changeset
664 -- and indicate the kind of with_clause responsible for the load.
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 Load_Stack.Increment_Last;
kono
parents:
diff changeset
667 Load_Stack.Table (Load_Stack.Last) := (Unum, With_Node);
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 -- Case of entry already in table
kono
parents:
diff changeset
670
kono
parents:
diff changeset
671 if Unum <= Units.Last then
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 -- Here is where we check for a circular dependency, which is
kono
parents:
diff changeset
674 -- an attempt to load a unit which is currently in the process
kono
parents:
diff changeset
675 -- of being loaded. We do *not* care about a circular chain that
kono
parents:
diff changeset
676 -- leads back to a body, because this kind of circular dependence
kono
parents:
diff changeset
677 -- legitimately occurs (e.g. two package bodies that contain
kono
parents:
diff changeset
678 -- inlined subprogram referenced by the other).
kono
parents:
diff changeset
679
kono
parents:
diff changeset
680 -- Ada 2005 (AI-50217): We also ignore limited_with clauses, because
kono
parents:
diff changeset
681 -- their purpose is precisely to create legal circular structures.
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 if Loading (Unum)
kono
parents:
diff changeset
684 and then (Is_Spec_Name (Units.Table (Unum).Unit_Name)
kono
parents:
diff changeset
685 or else Acts_As_Spec (Units.Table (Unum).Cunit))
kono
parents:
diff changeset
686 and then (Nkind (Error_Node) /= N_With_Clause
kono
parents:
diff changeset
687 or else not Limited_Present (Error_Node))
kono
parents:
diff changeset
688 and then not From_Limited_With_Chain
kono
parents:
diff changeset
689 then
kono
parents:
diff changeset
690 if Debug_Flag_L then
kono
parents:
diff changeset
691 Write_Str (" circular dependency encountered");
kono
parents:
diff changeset
692 Write_Eol;
kono
parents:
diff changeset
693 end if;
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 if Present (Error_Node) then
kono
parents:
diff changeset
696 Error_Msg ("circular unit dependency", Load_Msg_Sloc);
kono
parents:
diff changeset
697 Write_Dependency_Chain;
kono
parents:
diff changeset
698 else
kono
parents:
diff changeset
699 Load_Stack.Decrement_Last;
kono
parents:
diff changeset
700 end if;
kono
parents:
diff changeset
701
kono
parents:
diff changeset
702 Unum := No_Unit;
kono
parents:
diff changeset
703 goto Done;
kono
parents:
diff changeset
704 end if;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 if Debug_Flag_L then
kono
parents:
diff changeset
707 Write_Str (" unit already in file table, Unit_Number = ");
kono
parents:
diff changeset
708 Write_Int (Int (Unum));
kono
parents:
diff changeset
709 Write_Eol;
kono
parents:
diff changeset
710 end if;
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 Load_Stack.Decrement_Last;
kono
parents:
diff changeset
713 goto Done;
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 -- Unit is not already in table, so try to open the file
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 else
kono
parents:
diff changeset
718 if Debug_Flag_L then
kono
parents:
diff changeset
719 Write_Str (" attempt unit load, Unit_Number = ");
kono
parents:
diff changeset
720 Write_Int (Int (Unum));
kono
parents:
diff changeset
721 Write_Eol;
kono
parents:
diff changeset
722 end if;
kono
parents:
diff changeset
723
kono
parents:
diff changeset
724 Src_Ind := Load_Source_File (Fname);
kono
parents:
diff changeset
725
kono
parents:
diff changeset
726 -- Make a partial entry in the file table, used even in the file not
kono
parents:
diff changeset
727 -- found case to print the dependency chain including the last entry
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 Units.Increment_Last;
kono
parents:
diff changeset
730 Units.Table (Unum).Unit_Name := Uname_Actual;
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 -- File was found
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 if Src_Ind > No_Source_File then
kono
parents:
diff changeset
735 Units.Table (Unum) :=
kono
parents:
diff changeset
736 (Cunit => Empty,
kono
parents:
diff changeset
737 Cunit_Entity => Empty,
kono
parents:
diff changeset
738 Dependency_Num => 0,
kono
parents:
diff changeset
739 Dynamic_Elab => False,
kono
parents:
diff changeset
740 Error_Location => Sloc (Error_Node),
kono
parents:
diff changeset
741 Expected_Unit => Uname_Actual,
kono
parents:
diff changeset
742 Fatal_Error => None,
kono
parents:
diff changeset
743 Generate_Code => False,
kono
parents:
diff changeset
744 Has_RACW => False,
kono
parents:
diff changeset
745 Filler => False,
kono
parents:
diff changeset
746 Ident_String => Empty,
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 Is_Predefined_Renaming => Ren_Name,
kono
parents:
diff changeset
749 Is_Predefined_Unit => Pre_Name or Ren_Name,
kono
parents:
diff changeset
750 Is_Internal_Unit => Pre_Name or Ren_Name or GNAT_Name,
kono
parents:
diff changeset
751 Filler2 => False,
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753 Loading => True,
kono
parents:
diff changeset
754 Main_Priority => Default_Main_Priority,
kono
parents:
diff changeset
755 Main_CPU => Default_Main_CPU,
kono
parents:
diff changeset
756 Primary_Stack_Count => 0,
kono
parents:
diff changeset
757 Sec_Stack_Count => 0,
kono
parents:
diff changeset
758 Munit_Index => 0,
kono
parents:
diff changeset
759 No_Elab_Code_All => False,
kono
parents:
diff changeset
760 Serial_Number => 0,
kono
parents:
diff changeset
761 Source_Index => Src_Ind,
kono
parents:
diff changeset
762 Unit_File_Name => Fname,
kono
parents:
diff changeset
763 Unit_Name => Uname_Actual,
kono
parents:
diff changeset
764 Version => Source_Checksum (Src_Ind),
kono
parents:
diff changeset
765 OA_Setting => 'O');
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 -- Parse the new unit
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 declare
kono
parents:
diff changeset
770 Save_Index : constant Nat := Multiple_Unit_Index;
kono
parents:
diff changeset
771 Save_PMES : constant Boolean := Parsing_Main_Extended_Source;
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 begin
kono
parents:
diff changeset
774 Multiple_Unit_Index := Get_Unit_Index (Uname_Actual);
kono
parents:
diff changeset
775 Units.Table (Unum).Munit_Index := Multiple_Unit_Index;
kono
parents:
diff changeset
776 Initialize_Scanner (Unum, Source_Index (Unum));
kono
parents:
diff changeset
777
kono
parents:
diff changeset
778 if Calling_Unit = Main_Unit and then Subunit then
kono
parents:
diff changeset
779 Parsing_Main_Extended_Source := True;
kono
parents:
diff changeset
780 end if;
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782 Discard_List (Par (Configuration_Pragmas => False));
kono
parents:
diff changeset
783
kono
parents:
diff changeset
784 Parsing_Main_Extended_Source := Save_PMES;
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 Multiple_Unit_Index := Save_Index;
kono
parents:
diff changeset
787 Set_Loading (Unum, False);
kono
parents:
diff changeset
788 end;
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 -- If spec is irrelevant, then post errors and quit
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 if Corr_Body /= No_Unit
kono
parents:
diff changeset
793 and then Spec_Is_Irrelevant (Unum, Corr_Body)
kono
parents:
diff changeset
794 then
kono
parents:
diff changeset
795 Error_Msg_File_1 := Unit_File_Name (Corr_Body);
kono
parents:
diff changeset
796 Error_Msg
kono
parents:
diff changeset
797 ("cannot compile subprogram in file {!", Load_Msg_Sloc);
kono
parents:
diff changeset
798 Error_Msg_File_1 := Unit_File_Name (Unum);
kono
parents:
diff changeset
799 Error_Msg
kono
parents:
diff changeset
800 ("\incorrect spec in file { must be removed first!",
kono
parents:
diff changeset
801 Load_Msg_Sloc);
kono
parents:
diff changeset
802 Unum := No_Unit;
kono
parents:
diff changeset
803 goto Done;
kono
parents:
diff changeset
804 end if;
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 -- If loaded unit had an error, then caller inherits setting
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 if Present (Error_Node) then
kono
parents:
diff changeset
809 case Units.Table (Unum).Fatal_Error is
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 -- Nothing to do if with'ed unit had no error
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 when None =>
kono
parents:
diff changeset
814 null;
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 -- If with'ed unit had a detected fatal error, propagate it
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 when Error_Detected =>
kono
parents:
diff changeset
819 Units.Table (Calling_Unit).Fatal_Error := Error_Detected;
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 -- If with'ed unit had an ignored error, then propagate it
kono
parents:
diff changeset
822 -- but do not overide an existring setting.
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 when Error_Ignored =>
kono
parents:
diff changeset
825 if Units.Table (Calling_Unit).Fatal_Error = None then
kono
parents:
diff changeset
826 Units.Table (Calling_Unit).Fatal_Error :=
kono
parents:
diff changeset
827 Error_Ignored;
kono
parents:
diff changeset
828 end if;
kono
parents:
diff changeset
829 end case;
kono
parents:
diff changeset
830 end if;
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 -- Remove load stack entry and return the entry in the file table
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 Load_Stack.Decrement_Last;
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 -- All done, return unit number
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 goto Done;
kono
parents:
diff changeset
839
kono
parents:
diff changeset
840 -- Case of file not found
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 else
kono
parents:
diff changeset
843 if Debug_Flag_L then
kono
parents:
diff changeset
844 if Src_Ind = No_Access_To_Source_File then
kono
parents:
diff changeset
845 Write_Str (" no read access to file, load failed");
kono
parents:
diff changeset
846 else
kono
parents:
diff changeset
847 Write_Str (" file was not found, load failed");
kono
parents:
diff changeset
848 end if;
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 Write_Eol;
kono
parents:
diff changeset
851 end if;
kono
parents:
diff changeset
852
kono
parents:
diff changeset
853 -- Generate message if unit required
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 if Required then
kono
parents:
diff changeset
856 Get_Name_String (Fname);
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 if Is_Predefined_File_Name (Fname) then
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 -- This is a predefined library unit which is not present
kono
parents:
diff changeset
861 -- in the run time. If a predefined unit is not available
kono
parents:
diff changeset
862 -- it may very likely be the case that there is also pragma
kono
parents:
diff changeset
863 -- Restriction forbidding its usage. This is typically the
kono
parents:
diff changeset
864 -- case when building a configurable run time, where the
kono
parents:
diff changeset
865 -- usage of certain run-time units is restricted by means
kono
parents:
diff changeset
866 -- of both the corresponding pragma Restriction (such as
kono
parents:
diff changeset
867 -- No_Calendar), and by not including the unit. Hence, we
kono
parents:
diff changeset
868 -- check whether this predefined unit is forbidden, so that
kono
parents:
diff changeset
869 -- the message about the restriction violation is generated,
kono
parents:
diff changeset
870 -- if needed.
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 if Present (Error_Node) then
kono
parents:
diff changeset
873 Check_Restricted_Unit (Load_Name, Error_Node);
kono
parents:
diff changeset
874 end if;
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 Error_Msg_Unit_1 := Uname_Actual;
kono
parents:
diff changeset
877 Error_Msg -- CODEFIX
kono
parents:
diff changeset
878 ("$$ is not a predefined library unit", Load_Msg_Sloc);
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 else
kono
parents:
diff changeset
881 Error_Msg_File_1 := Fname;
kono
parents:
diff changeset
882
kono
parents:
diff changeset
883 if Src_Ind = No_Access_To_Source_File then
kono
parents:
diff changeset
884 Error_Msg ("no read access to file{", Load_Msg_Sloc);
kono
parents:
diff changeset
885 else
kono
parents:
diff changeset
886 Error_Msg ("file{ not found", Load_Msg_Sloc);
kono
parents:
diff changeset
887 end if;
kono
parents:
diff changeset
888 end if;
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 Write_Dependency_Chain;
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 -- Remove unit from stack, to avoid cascaded errors on
kono
parents:
diff changeset
893 -- subsequent missing files.
kono
parents:
diff changeset
894
kono
parents:
diff changeset
895 Load_Stack.Decrement_Last;
kono
parents:
diff changeset
896 Units.Decrement_Last;
kono
parents:
diff changeset
897
kono
parents:
diff changeset
898 -- If unit not required, remove load stack entry and the junk
kono
parents:
diff changeset
899 -- file table entry, and return No_Unit to indicate not found,
kono
parents:
diff changeset
900
kono
parents:
diff changeset
901 else
kono
parents:
diff changeset
902 Load_Stack.Decrement_Last;
kono
parents:
diff changeset
903 Units.Decrement_Last;
kono
parents:
diff changeset
904 end if;
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 Unum := No_Unit;
kono
parents:
diff changeset
907 goto Done;
kono
parents:
diff changeset
908 end if;
kono
parents:
diff changeset
909 end if;
kono
parents:
diff changeset
910
kono
parents:
diff changeset
911 -- Here to exit, with result in Unum
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 <<Done>>
kono
parents:
diff changeset
914 Parsing_Main_Extended_Source := Save_PMES;
kono
parents:
diff changeset
915 Cunit_Boolean_Restrictions_Restore (Save_Cunit_Restrictions);
kono
parents:
diff changeset
916 return Unum;
kono
parents:
diff changeset
917 end Load_Unit;
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 --------------------------
kono
parents:
diff changeset
920 -- Make_Child_Decl_Unit --
kono
parents:
diff changeset
921 --------------------------
kono
parents:
diff changeset
922
kono
parents:
diff changeset
923 procedure Make_Child_Decl_Unit (N : Node_Id) is
kono
parents:
diff changeset
924 Unit_Decl : constant Node_Id := Library_Unit (N);
kono
parents:
diff changeset
925
kono
parents:
diff changeset
926 begin
kono
parents:
diff changeset
927 Units.Increment_Last;
kono
parents:
diff changeset
928 Units.Table (Units.Last) := Units.Table (Get_Cunit_Unit_Number (N));
kono
parents:
diff changeset
929 Units.Table (Units.Last).Unit_Name :=
kono
parents:
diff changeset
930 Get_Spec_Name (Unit_Name (Get_Cunit_Unit_Number (N)));
kono
parents:
diff changeset
931 Units.Table (Units.Last).Cunit := Unit_Decl;
kono
parents:
diff changeset
932 Units.Table (Units.Last).Cunit_Entity :=
kono
parents:
diff changeset
933 Defining_Identifier
kono
parents:
diff changeset
934 (Defining_Unit_Name (Specification (Unit (Unit_Decl))));
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 -- The library unit created for of a child subprogram unit plays no
kono
parents:
diff changeset
937 -- role in code generation and binding, so label it accordingly.
kono
parents:
diff changeset
938
kono
parents:
diff changeset
939 Units.Table (Units.Last).Generate_Code := False;
kono
parents:
diff changeset
940 Set_Has_No_Elaboration_Code (Unit_Decl);
kono
parents:
diff changeset
941 end Make_Child_Decl_Unit;
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 ------------------------
kono
parents:
diff changeset
944 -- Make_Instance_Unit --
kono
parents:
diff changeset
945 ------------------------
kono
parents:
diff changeset
946
kono
parents:
diff changeset
947 -- If the unit is an instance, it appears as a package declaration, but
kono
parents:
diff changeset
948 -- contains both declaration and body of the instance. The body becomes
kono
parents:
diff changeset
949 -- the main unit of the compilation, and the declaration is inserted
kono
parents:
diff changeset
950 -- at the end of the unit table. The main unit now has the name of a
kono
parents:
diff changeset
951 -- body, which is constructed from the name of the original spec,
kono
parents:
diff changeset
952 -- and is attached to the compilation node of the original unit. The
kono
parents:
diff changeset
953 -- declaration has been attached to a new compilation unit node, and
kono
parents:
diff changeset
954 -- code will have to be generated for it.
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 procedure Make_Instance_Unit (N : Node_Id; In_Main : Boolean) is
kono
parents:
diff changeset
957 Sind : constant Source_File_Index := Source_Index (Main_Unit);
kono
parents:
diff changeset
958
kono
parents:
diff changeset
959 begin
kono
parents:
diff changeset
960 Units.Increment_Last;
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 if In_Main then
kono
parents:
diff changeset
963 Units.Table (Units.Last) := Units.Table (Main_Unit);
kono
parents:
diff changeset
964 Units.Table (Units.Last).Cunit := Library_Unit (N);
kono
parents:
diff changeset
965 Units.Table (Units.Last).Generate_Code := True;
kono
parents:
diff changeset
966 Units.Table (Main_Unit).Cunit := N;
kono
parents:
diff changeset
967 Units.Table (Main_Unit).Unit_Name :=
kono
parents:
diff changeset
968 Get_Body_Name
kono
parents:
diff changeset
969 (Unit_Name (Get_Cunit_Unit_Number (Library_Unit (N))));
kono
parents:
diff changeset
970 Units.Table (Main_Unit).Version := Source_Checksum (Sind);
kono
parents:
diff changeset
971
kono
parents:
diff changeset
972 else
kono
parents:
diff changeset
973 -- Duplicate information from instance unit, for the body. The unit
kono
parents:
diff changeset
974 -- node N has been rewritten as a body, but it was placed in the
kono
parents:
diff changeset
975 -- units table when first loaded as a declaration.
kono
parents:
diff changeset
976
kono
parents:
diff changeset
977 Units.Table (Units.Last) := Units.Table (Get_Cunit_Unit_Number (N));
kono
parents:
diff changeset
978 Units.Table (Units.Last).Cunit := Library_Unit (N);
kono
parents:
diff changeset
979 end if;
kono
parents:
diff changeset
980 end Make_Instance_Unit;
kono
parents:
diff changeset
981
kono
parents:
diff changeset
982 ------------------------
kono
parents:
diff changeset
983 -- Spec_Is_Irrelevant --
kono
parents:
diff changeset
984 ------------------------
kono
parents:
diff changeset
985
kono
parents:
diff changeset
986 function Spec_Is_Irrelevant
kono
parents:
diff changeset
987 (Spec_Unit : Unit_Number_Type;
kono
parents:
diff changeset
988 Body_Unit : Unit_Number_Type) return Boolean
kono
parents:
diff changeset
989 is
kono
parents:
diff changeset
990 Sunit : constant Node_Id := Cunit (Spec_Unit);
kono
parents:
diff changeset
991 Bunit : constant Node_Id := Cunit (Body_Unit);
kono
parents:
diff changeset
992
kono
parents:
diff changeset
993 begin
kono
parents:
diff changeset
994 -- The spec is irrelevant if the body is a subprogram body, and the spec
kono
parents:
diff changeset
995 -- is other than a subprogram spec or generic subprogram spec. Note that
kono
parents:
diff changeset
996 -- the names must be the same, we don't need to check that, because we
kono
parents:
diff changeset
997 -- already know that from the fact that the file names are the same.
kono
parents:
diff changeset
998
kono
parents:
diff changeset
999 return
kono
parents:
diff changeset
1000 Nkind (Unit (Bunit)) = N_Subprogram_Body
kono
parents:
diff changeset
1001 and then Nkind (Unit (Sunit)) /= N_Subprogram_Declaration
kono
parents:
diff changeset
1002 and then Nkind (Unit (Sunit)) /= N_Generic_Subprogram_Declaration;
kono
parents:
diff changeset
1003 end Spec_Is_Irrelevant;
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 --------------------
kono
parents:
diff changeset
1006 -- Version_Update --
kono
parents:
diff changeset
1007 --------------------
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 procedure Version_Update (U : Node_Id; From : Node_Id) is
kono
parents:
diff changeset
1010 Unum : constant Unit_Number_Type := Get_Cunit_Unit_Number (U);
kono
parents:
diff changeset
1011 Fnum : constant Unit_Number_Type := Get_Cunit_Unit_Number (From);
kono
parents:
diff changeset
1012 begin
kono
parents:
diff changeset
1013 if Source_Index (Fnum) > No_Source_File then
kono
parents:
diff changeset
1014 Units.Table (Unum).Version :=
kono
parents:
diff changeset
1015 Units.Table (Unum).Version
kono
parents:
diff changeset
1016 xor
kono
parents:
diff changeset
1017 Source_Checksum (Source_Index (Fnum));
kono
parents:
diff changeset
1018 end if;
kono
parents:
diff changeset
1019 end Version_Update;
kono
parents:
diff changeset
1020
kono
parents:
diff changeset
1021 ----------------------------
kono
parents:
diff changeset
1022 -- Write_Dependency_Chain --
kono
parents:
diff changeset
1023 ----------------------------
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 procedure Write_Dependency_Chain is
kono
parents:
diff changeset
1026 begin
kono
parents:
diff changeset
1027 -- The dependency chain is only written if it is at least two entries
kono
parents:
diff changeset
1028 -- deep, otherwise it is trivial (the main unit depending on a unit
kono
parents:
diff changeset
1029 -- that it obviously directly depends on).
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 if Load_Stack.Last - 1 > Load_Stack.First then
kono
parents:
diff changeset
1032 for U in Load_Stack.First .. Load_Stack.Last - 1 loop
kono
parents:
diff changeset
1033 Error_Msg_Unit_1 :=
kono
parents:
diff changeset
1034 Unit_Name (Load_Stack.Table (U).Unit_Number);
kono
parents:
diff changeset
1035 Error_Msg_Unit_2 :=
kono
parents:
diff changeset
1036 Unit_Name (Load_Stack.Table (U + 1).Unit_Number);
kono
parents:
diff changeset
1037 Error_Msg ("$ depends on $!", Load_Msg_Sloc);
kono
parents:
diff changeset
1038 end loop;
kono
parents:
diff changeset
1039 end if;
kono
parents:
diff changeset
1040 end Write_Dependency_Chain;
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 end Lib.Load;