OSDN Git Service

* gcc-interface/Makefile.in (gnatlib-shared-default): Append
[pf3gnuchains/gcc-fork.git] / gcc / ada / rtsfind.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              R T S F I N D                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 with Atree;    use Atree;
27 with Casing;   use Casing;
28 with Csets;    use Csets;
29 with Debug;    use Debug;
30 with Einfo;    use Einfo;
31 with Elists;   use Elists;
32 with Errout;   use Errout;
33 with Exp_Dist; use Exp_Dist;
34 with Fname;    use Fname;
35 with Fname.UF; use Fname.UF;
36 with Lib;      use Lib;
37 with Lib.Load; use Lib.Load;
38 with Namet;    use Namet;
39 with Nlists;   use Nlists;
40 with Nmake;    use Nmake;
41 with Output;   use Output;
42 with Opt;      use Opt;
43 with Restrict; use Restrict;
44 with Sem;      use Sem;
45 with Sem_Aux;  use Sem_Aux;
46 with Sem_Ch7;  use Sem_Ch7;
47 with Sem_Dist; use Sem_Dist;
48 with Sem_Util; use Sem_Util;
49 with Sinfo;    use Sinfo;
50 with Stand;    use Stand;
51 with Snames;   use Snames;
52 with Tbuild;   use Tbuild;
53 with Uname;    use Uname;
54
55 package body Rtsfind is
56
57    RTE_Available_Call : Boolean := False;
58    --  Set True during call to RTE from RTE_Available (or from call to
59    --  RTE_Record_Component from RTE_Record_Component_Available). Tells
60    --  the called subprogram to set RTE_Is_Available to False rather than
61    --  generating an error message.
62
63    RTE_Is_Available : Boolean;
64    --  Set True by RTE_Available on entry. When RTE_Available_Call is set
65    --  True, set False if RTE would otherwise generate an error message.
66
67    ----------------
68    -- Unit table --
69    ----------------
70
71    --  The unit table has one entry for each unit included in the definition
72    --  of the type RTU_Id in the spec. The table entries are initialized in
73    --  Initialize to set the Entity field to Empty, indicating that the
74    --  corresponding unit has not yet been loaded. The fields are set when
75    --  a unit is loaded to contain the defining entity for the unit, the
76    --  unit name, and the unit number.
77
78    --  Note that a unit can be loaded either by a call to find an entity
79    --  within the unit (e.g. RTE), or by an explicit with of the unit. In
80    --  the latter case it is critical to make a call to Set_RTU_Loaded to
81    --  ensure that the entry in this table reflects the load.
82
83    --  A unit retrieved through rtsfind  may end up in the context of several
84    --  other units, in addition to the main unit. These additional with_clauses
85    --  are needed to generate a proper traversal order for Inspector. To
86    --  minimize somewhat the redundancy created by numerous calls to rtsfind
87    --  from different units, we keep track of the list of implicit with_clauses
88    --  already created for the current loaded unit.
89
90    type RT_Unit_Table_Record is record
91       Entity               : Entity_Id;
92       Uname                : Unit_Name_Type;
93       First_Implicit_With  : Node_Id;
94       Unum                 : Unit_Number_Type;
95    end record;
96
97    RT_Unit_Table : array (RTU_Id) of RT_Unit_Table_Record;
98
99    --------------------------
100    -- Runtime Entity Table --
101    --------------------------
102
103    --  There is one entry in the runtime entity table for each entity that is
104    --  included in the definition of the RE_Id type in the spec. The entries
105    --  are set by Initialize_Rtsfind to contain Empty, indicating that the
106    --  entity has not yet been located. Once the entity is located for the
107    --  first time, its ID is stored in this array, so that subsequent calls
108    --  for the same entity can be satisfied immediately.
109
110    --  NOTE: In order to avoid conflicts between record components and subprgs
111    --        that have the same name (i.e. subprogram External_Tag and
112    --        component External_Tag of package Ada.Tags) this table is not used
113    --        with Record_Components.
114
115    RE_Table : array (RE_Id) of Entity_Id;
116
117    --------------------------------
118    -- Generation of with_clauses --
119    --------------------------------
120
121    --  When a unit is implicitly loaded as a result of a call to RTE, it is
122    --  necessary to create one or two implicit with_clauses. We add such
123    --  with_clauses to the extended main unit if needed, and also to whatever
124    --  unit needs them, which is not necessarily the main unit. The former
125    --  ensures that the object is correctly loaded by the binder. The latter
126    --  is necessary for SofCheck Inspector.
127
128    --  The field First_Implicit_With in the unit table record are used to
129    --  avoid creating duplicate with_clauses.
130
131    -----------------------
132    -- Local Subprograms --
133    -----------------------
134
135    function Check_CRT (E : RE_Id; Eid : Entity_Id) return Entity_Id;
136    --  Check entity Eid to ensure that configurable run-time restrictions are
137    --  met. May generate an error message (if RTE_Available_Call is false) and
138    --  raise RE_Not_Available if entity E does not exist (e.g. Eid is Empty).
139    --  Also check that entity is not overloaded.
140
141    procedure Entity_Not_Defined (Id : RE_Id);
142    --  Outputs error messages for an entity that is not defined in the run-time
143    --  library (the form of the error message is tailored for no run time or
144    --  configurable run time mode as required).
145
146    function Get_Unit_Name (U_Id : RTU_Id) return Unit_Name_Type;
147    --  Retrieves the Unit Name given a unit id represented by its enumeration
148    --  value in RTU_Id.
149
150    procedure Load_Fail (S : String; U_Id : RTU_Id; Id : RE_Id);
151    --  Internal procedure called if we can't successfully locate or process a
152    --  run-time unit. The parameters give information about the error message
153    --  to be given. S is a reason for failing to compile the file and U_Id is
154    --  the unit id. RE_Id is the RE_Id originally passed to RTE. The message in
155    --  S is one of the following:
156    --
157    --     "not found"
158    --     "had parser errors"
159    --     "had semantic errors"
160    --
161    --  The "not found" case is treated specially in that it is considered
162    --  a normal situation in configurable run-time mode, and generates
163    --  a warning, but is otherwise ignored.
164
165    procedure Load_RTU
166      (U_Id        : RTU_Id;
167       Id          : RE_Id   := RE_Null;
168       Use_Setting : Boolean := False);
169    --  Load the unit whose Id is given if not already loaded. The unit is
170    --  loaded and analyzed, and the entry in RT_Unit_Table is updated to
171    --  reflect the load. Use_Setting is used to indicate the initial setting
172    --  for the Is_Potentially_Use_Visible flag of the entity for the loaded
173    --  unit (if it is indeed loaded). A value of False means nothing special
174    --  need be done. A value of True indicates that this flag must be set to
175    --  True. It is needed only in the Text_IO_Kludge procedure, which may
176    --  materialize an entity of Text_IO (or [Wide_]Wide_Text_IO) that was
177    --  previously unknown. Id is the RE_Id value of the entity which was
178    --  originally requested. Id is used only for error message detail, and if
179    --  it is RE_Null, then the attempt to output the entity name is ignored.
180
181    function Make_Unit_Name
182      (U : RT_Unit_Table_Record;
183       N : Node_Id) return Node_Id;
184    --  If the unit is a child unit, build fully qualified name for use in
185    --  With_Clause.
186
187    procedure Maybe_Add_With (U : in out RT_Unit_Table_Record);
188    --  If necessary, add an implicit with_clause from the current unit to the
189    --  one represented by U.
190
191    procedure Output_Entity_Name (Id : RE_Id; Msg : String);
192    --  Output continuation error message giving qualified name of entity
193    --  corresponding to Id, appending the string given by Msg. This call
194    --  is only effective in All_Errors mode.
195
196    function RE_Chars (E : RE_Id) return Name_Id;
197    --  Given a RE_Id value returns the Chars of the corresponding entity
198
199    procedure RTE_Error_Msg (Msg : String);
200    --  Generates a message by calling Error_Msg_N specifying Current_Error_Node
201    --  as the node location using the given Msg text. Special processing in the
202    --  case where RTE_Available_Call is set. In this case, no message is output
203    --  and instead RTE_Is_Available is set to False. Note that this can only be
204    --  used if you are sure that the message comes directly or indirectly from
205    --  a call to the RTE function.
206
207    ---------------
208    -- Check_CRT --
209    ---------------
210
211    function Check_CRT (E : RE_Id; Eid : Entity_Id) return Entity_Id is
212       U_Id : constant RTU_Id := RE_Unit_Table (E);
213
214    begin
215       if No (Eid) then
216          if RTE_Available_Call then
217             RTE_Is_Available := False;
218          else
219             Entity_Not_Defined (E);
220          end if;
221
222          raise RE_Not_Available;
223
224       --  Entity is available
225
226       else
227          --  If in No_Run_Time mode and entity is not in one of the
228          --  specially permitted units, raise the exception.
229
230          if No_Run_Time_Mode
231            and then not OK_No_Run_Time_Unit (U_Id)
232          then
233             Entity_Not_Defined (E);
234             raise RE_Not_Available;
235          end if;
236
237          --  Check entity is not overloaded, checking for special exceptions
238
239          if Has_Homonym (Eid)
240            and then E /= RE_Save_Occurrence
241          then
242             Set_Standard_Error;
243             Write_Str ("Run-time configuration error (");
244             Write_Str ("rtsfind entity """);
245             Get_Decoded_Name_String (Chars (Eid));
246             Set_Casing (Mixed_Case);
247             Write_Str (Name_Buffer (1 .. Name_Len));
248             Write_Str (""" is overloaded)");
249             Write_Eol;
250             raise Unrecoverable_Error;
251          end if;
252
253          --  Otherwise entity is accessible
254
255          return Eid;
256       end if;
257    end Check_CRT;
258
259    ------------------------
260    -- Entity_Not_Defined --
261    ------------------------
262
263    procedure Entity_Not_Defined (Id : RE_Id) is
264    begin
265       if No_Run_Time_Mode then
266
267          --  If the error occurs when compiling the body of a predefined
268          --  unit for inlining purposes, the body must be illegal in this
269          --  mode, and there is no point in continuing.
270
271          if Is_Predefined_File_Name
272            (Unit_File_Name (Get_Source_Unit (Sloc (Current_Error_Node))))
273          then
274             Error_Msg_N
275               ("construct not allowed in no run time mode!",
276                  Current_Error_Node);
277             raise Unrecoverable_Error;
278
279          else
280             RTE_Error_Msg ("|construct not allowed in no run time mode");
281          end if;
282
283       elsif Configurable_Run_Time_Mode then
284          RTE_Error_Msg ("|construct not allowed in this configuration>");
285       else
286          RTE_Error_Msg ("run-time configuration error");
287       end if;
288
289       Output_Entity_Name (Id, "not defined");
290    end Entity_Not_Defined;
291
292    -------------------
293    -- Get_Unit_Name --
294    -------------------
295
296    function Get_Unit_Name (U_Id : RTU_Id) return Unit_Name_Type is
297       Uname_Chars : constant String := RTU_Id'Image (U_Id);
298
299    begin
300       Name_Len := Uname_Chars'Length;
301       Name_Buffer (1 .. Name_Len) := Uname_Chars;
302       Set_Casing (All_Lower_Case);
303
304       if U_Id in Ada_Child then
305          Name_Buffer (4) := '.';
306
307          if U_Id in Ada_Calendar_Child then
308             Name_Buffer (13) := '.';
309
310          elsif U_Id in Ada_Dispatching_Child then
311             Name_Buffer (16) := '.';
312
313          elsif U_Id in Ada_Interrupts_Child then
314             Name_Buffer (15) := '.';
315
316          elsif U_Id in Ada_Numerics_Child then
317             Name_Buffer (13) := '.';
318
319          elsif U_Id in Ada_Real_Time_Child then
320             Name_Buffer (14) := '.';
321
322          elsif U_Id in Ada_Streams_Child then
323             Name_Buffer (12) := '.';
324
325          elsif U_Id in Ada_Strings_Child then
326             Name_Buffer (12) := '.';
327
328          elsif U_Id in Ada_Text_IO_Child then
329             Name_Buffer (12) := '.';
330
331          elsif U_Id in Ada_Wide_Text_IO_Child then
332             Name_Buffer (17) := '.';
333
334          elsif U_Id in Ada_Wide_Wide_Text_IO_Child then
335             Name_Buffer (22) := '.';
336          end if;
337
338       elsif U_Id in Interfaces_Child then
339          Name_Buffer (11) := '.';
340
341       elsif U_Id in System_Child then
342          Name_Buffer (7) := '.';
343
344          if U_Id in System_Dim_Child then
345             Name_Buffer (11) := '.';
346          end if;
347
348          if U_Id in System_Multiprocessors_Child then
349             Name_Buffer (23) := '.';
350          end if;
351
352          if U_Id in System_Storage_Pools_Child then
353             Name_Buffer (21) := '.';
354          end if;
355
356          if U_Id in System_Strings_Child then
357             Name_Buffer (15) := '.';
358          end if;
359
360          if U_Id in System_Tasking_Child then
361             Name_Buffer (15) := '.';
362          end if;
363
364          if U_Id in System_Tasking_Restricted_Child then
365             Name_Buffer (26) := '.';
366          end if;
367
368          if U_Id in System_Tasking_Protected_Objects_Child then
369             Name_Buffer (33) := '.';
370          end if;
371
372          if U_Id in System_Tasking_Async_Delays_Child then
373             Name_Buffer (28) := '.';
374          end if;
375       end if;
376
377       --  Add %s at end for spec
378
379       Name_Buffer (Name_Len + 1) := '%';
380       Name_Buffer (Name_Len + 2) := 's';
381       Name_Len := Name_Len + 2;
382
383       return Name_Find;
384    end Get_Unit_Name;
385
386    ----------------
387    -- Initialize --
388    ----------------
389
390    procedure Initialize is
391    begin
392       --  Initialize the unit table
393
394       for J in RTU_Id loop
395          RT_Unit_Table (J).Entity := Empty;
396       end loop;
397
398       for J in RE_Id loop
399          RE_Table (J) := Empty;
400       end loop;
401
402       RTE_Is_Available := False;
403    end Initialize;
404
405    ------------
406    -- Is_RTE --
407    ------------
408
409    function Is_RTE (Ent : Entity_Id; E : RE_Id) return Boolean is
410       E_Unit_Name   : Unit_Name_Type;
411       Ent_Unit_Name : Unit_Name_Type;
412
413       S  : Entity_Id;
414       E1 : Entity_Id;
415       E2 : Entity_Id;
416
417    begin
418       if No (Ent) then
419          return False;
420
421       --  If E has already a corresponding entity, check it directly,
422       --  going to full views if they exist to deal with the incomplete
423       --  and private type cases properly.
424
425       elsif Present (RE_Table (E)) then
426          E1 := Ent;
427
428          if Is_Type (E1) and then Present (Full_View (E1)) then
429             E1 := Full_View (E1);
430          end if;
431
432          E2 := RE_Table (E);
433
434          if Is_Type (E2) and then Present (Full_View (E2)) then
435             E2 := Full_View (E2);
436          end if;
437
438          return E1 = E2;
439       end if;
440
441       --  If the unit containing E is not loaded, we already know that the
442       --  entity we have cannot have come from this unit.
443
444       E_Unit_Name := Get_Unit_Name (RE_Unit_Table (E));
445
446       if not Is_Loaded (E_Unit_Name) then
447          return False;
448       end if;
449
450       --  Here the unit containing the entity is loaded. We have not made
451       --  an explicit call to RTE to get the entity in question, but we may
452       --  have obtained a reference to it indirectly from some other entity
453       --  in the same unit, or some other unit that references it.
454
455       --  Get the defining unit of the entity
456
457       S := Scope (Ent);
458
459       if Ekind (S) /= E_Package then
460          return False;
461       end if;
462
463       Ent_Unit_Name := Get_Unit_Name (Unit_Declaration_Node (S));
464
465       --  If the defining unit of the entity we are testing is not the
466       --  unit containing E, then they cannot possibly match.
467
468       if Ent_Unit_Name /= E_Unit_Name then
469          return False;
470       end if;
471
472       --  If the units match, then compare the names (remember that no
473       --  overloading is permitted in entities fetched using Rtsfind).
474
475       if RE_Chars (E) = Chars (Ent) then
476          RE_Table (E) := Ent;
477
478          --  If front-end inlining is enabled, we may be within a body that
479          --  contains inlined functions, which has not been retrieved through
480          --  rtsfind, and therefore is not yet recorded in the RT_Unit_Table.
481          --  Add the unit information now, it must be fully available.
482
483          declare
484             U : RT_Unit_Table_Record
485                   renames  RT_Unit_Table (RE_Unit_Table (E));
486          begin
487             if No (U.Entity) then
488                U.Entity := S;
489                U.Uname  := E_Unit_Name;
490                U.Unum   := Get_Source_Unit (S);
491             end if;
492          end;
493
494          return True;
495       else
496          return False;
497       end if;
498    end Is_RTE;
499
500    ------------
501    -- Is_RTU --
502    ------------
503
504    function Is_RTU (Ent : Entity_Id;  U : RTU_Id) return Boolean is
505       E : constant Entity_Id := RT_Unit_Table (U).Entity;
506    begin
507       return Present (E) and then E = Ent;
508    end Is_RTU;
509
510    ----------------------------
511    -- Is_Text_IO_Kludge_Unit --
512    ----------------------------
513
514    function Is_Text_IO_Kludge_Unit (Nam : Node_Id) return Boolean is
515       Prf : Node_Id;
516       Sel : Node_Id;
517
518    begin
519       if Nkind (Nam) /= N_Expanded_Name then
520          return False;
521       end if;
522
523       Prf := Prefix (Nam);
524       Sel := Selector_Name (Nam);
525
526       if Nkind (Sel) /= N_Expanded_Name
527         or else Nkind (Prf) /= N_Identifier
528         or else Chars (Prf) /= Name_Ada
529       then
530          return False;
531       end if;
532
533       Prf := Prefix (Sel);
534       Sel := Selector_Name (Sel);
535
536       return
537         Nkind (Prf) = N_Identifier
538           and then
539            (Chars (Prf) = Name_Text_IO
540               or else
541             Chars (Prf) = Name_Wide_Text_IO
542               or else
543             Chars (Prf) = Name_Wide_Wide_Text_IO)
544           and then
545         Nkind (Sel) = N_Identifier
546           and then
547         Chars (Sel) in Text_IO_Package_Name;
548    end Is_Text_IO_Kludge_Unit;
549
550    ---------------
551    -- Load_Fail --
552    ---------------
553
554    procedure Load_Fail (S : String; U_Id : RTU_Id; Id : RE_Id) is
555       M : String (1 .. 100);
556       P : Natural := 0;
557
558    begin
559       --  Output header message
560
561       if Configurable_Run_Time_Mode then
562          RTE_Error_Msg ("construct not allowed in configurable run-time mode");
563       else
564          RTE_Error_Msg ("run-time library configuration error");
565       end if;
566
567       --  Output file name and reason string
568
569       M (1 .. 6) := "\file ";
570       P := 6;
571
572       Get_Name_String
573         (Get_File_Name (RT_Unit_Table (U_Id).Uname, Subunit => False));
574       M (P + 1 .. P + Name_Len) := Name_Buffer (1 .. Name_Len);
575       P := P + Name_Len;
576
577       M (P + 1) := ' ';
578       P := P + 1;
579
580       M (P + 1 .. P + S'Length) := S;
581       P := P + S'Length;
582
583       RTE_Error_Msg (M (1 .. P));
584
585       --  Output entity name
586
587       Output_Entity_Name (Id, "not available");
588
589       --  In configurable run time mode, we raise RE_Not_Available, and the
590       --  caller is expected to deal gracefully with this. In the case of a
591       --  call to RTE_Available, this exception will be caught in Rtsfind,
592       --  and result in a returned value of False for the call.
593
594       if Configurable_Run_Time_Mode then
595          raise RE_Not_Available;
596
597       --  Here we have a load failure in normal full run time mode. See if we
598       --  are in the context of an RTE_Available call. If so, we just raise
599       --  RE_Not_Available. This can happen if a unit is unavailable, which
600       --  happens for example in the VM case, where the run-time is not
601       --  complete, but we do not regard it as a configurable run-time.
602       --  If the caller has done an explicit call to RTE_Available, then
603       --  clearly the caller is prepared to deal with a result of False.
604
605       elsif RTE_Available_Call then
606          RTE_Is_Available := False;
607          raise RE_Not_Available;
608
609       --  If we are not in the context of an RTE_Available call, we are really
610       --  trying to load an entity that is not there, and that should never
611       --  happen, so in this case we signal a fatal error.
612
613       else
614          raise Unrecoverable_Error;
615       end if;
616    end Load_Fail;
617
618    --------------
619    -- Load_RTU --
620    --------------
621
622    procedure Load_RTU
623      (U_Id        : RTU_Id;
624       Id          : RE_Id   := RE_Null;
625       Use_Setting : Boolean := False)
626    is
627       U        : RT_Unit_Table_Record renames RT_Unit_Table (U_Id);
628       Priv_Par : constant Elist_Id := New_Elmt_List;
629       Lib_Unit : Node_Id;
630
631       procedure Save_Private_Visibility;
632       --  If the current unit is the body of child unit or the spec of a
633       --  private child unit, the private declarations of the parent(s) are
634       --  visible. If the unit to be loaded is another public sibling, its
635       --  compilation will affect the visibility of the common ancestors.
636       --  Indicate those that must be restored.
637
638       procedure Restore_Private_Visibility;
639       --  Restore the visibility of ancestors after compiling RTU
640
641       --------------------------------
642       -- Restore_Private_Visibility --
643       --------------------------------
644
645       procedure Restore_Private_Visibility is
646          E_Par : Elmt_Id;
647
648       begin
649          E_Par := First_Elmt (Priv_Par);
650          while Present (E_Par) loop
651             if not In_Private_Part (Node (E_Par)) then
652                Install_Private_Declarations (Node (E_Par));
653             end if;
654
655             Next_Elmt (E_Par);
656          end loop;
657       end Restore_Private_Visibility;
658
659       -----------------------------
660       -- Save_Private_Visibility --
661       -----------------------------
662
663       procedure Save_Private_Visibility is
664          Par : Entity_Id;
665
666       begin
667          Par := Scope (Current_Scope);
668          while Present (Par)
669            and then Par /= Standard_Standard
670          loop
671             if Ekind (Par) = E_Package
672               and then Is_Compilation_Unit (Par)
673               and then In_Private_Part (Par)
674             then
675                Append_Elmt (Par, Priv_Par);
676             end if;
677
678             Par := Scope (Par);
679          end loop;
680       end Save_Private_Visibility;
681
682    --  Start of processing for Load_RTU
683
684    begin
685       --  Nothing to do if unit is already loaded
686
687       if Present (U.Entity) then
688          return;
689       end if;
690
691       --  Note if secondary stack is used
692
693       if U_Id = System_Secondary_Stack then
694          Opt.Sec_Stack_Used := True;
695       end if;
696
697       --  Otherwise we need to load the unit, First build unit name
698       --  from the enumeration literal name in type RTU_Id.
699
700       U.Uname                := Get_Unit_Name (U_Id);
701       U. First_Implicit_With := Empty;
702
703       --  Now do the load call, note that setting Error_Node to Empty is
704       --  a signal to Load_Unit that we will regard a failure to find the
705       --  file as a fatal error, and that it should not output any kind
706       --  of diagnostics, since we will take care of it here.
707
708       --  We save style checking switches and turn off style checking for
709       --  loading the unit, since we don't want any style checking!
710
711       declare
712          Save_Style_Check : constant Boolean := Style_Check;
713       begin
714          Style_Check := False;
715          U.Unum :=
716            Load_Unit
717              (Load_Name  => U.Uname,
718               Required   => False,
719               Subunit    => False,
720               Error_Node => Empty);
721          Style_Check := Save_Style_Check;
722       end;
723
724       --  Check for bad unit load
725
726       if U.Unum = No_Unit then
727          Load_Fail ("not found", U_Id, Id);
728       elsif Fatal_Error (U.Unum) then
729          Load_Fail ("had parser errors", U_Id, Id);
730       end if;
731
732       --  Make sure that the unit is analyzed
733
734       declare
735          Was_Analyzed : constant Boolean :=
736                           Analyzed (Cunit (Current_Sem_Unit));
737
738       begin
739          --  Pretend that the current unit is analyzed, in case it is System
740          --  or some such. This allows us to put some declarations, such as
741          --  exceptions and packed arrays of Boolean, into System even though
742          --  expanding them requires System...
743
744          --  This is a bit odd but works fine. If the RTS unit does not depend
745          --  in any way on the current unit, then it never gets back into the
746          --  current unit's tree, and the change we make to the current unit
747          --  tree is never noticed by anyone (it is undone in a moment). That
748          --  is the normal situation.
749
750          --  If the RTS Unit *does* depend on the current unit, for instance,
751          --  when you are compiling System, then you had better have finished
752          --  analyzing the part of System that is depended on before you try to
753          --  load the RTS Unit. This means having the code in System ordered in
754          --  an appropriate manner.
755
756          Set_Analyzed (Cunit (Current_Sem_Unit), True);
757
758          if not Analyzed (Cunit (U.Unum)) then
759
760             --  If the unit is already loaded through a limited_with_clause,
761             --  the relevant entities must already be available. We do not
762             --  want to load and analyze the unit because this would create
763             --  a real semantic dependence when the purpose of the limited_with
764             --  is precisely to avoid such.
765
766             if From_With_Type (Cunit_Entity (U.Unum)) then
767                null;
768
769             else
770                Save_Private_Visibility;
771                Semantics (Cunit (U.Unum));
772                Restore_Private_Visibility;
773
774                if Fatal_Error (U.Unum) then
775                   Load_Fail ("had semantic errors", U_Id, Id);
776                end if;
777             end if;
778          end if;
779
780          --  Undo the pretence
781
782          Set_Analyzed (Cunit (Current_Sem_Unit), Was_Analyzed);
783       end;
784
785       Lib_Unit := Unit (Cunit (U.Unum));
786       U.Entity := Defining_Entity (Lib_Unit);
787
788       if Use_Setting then
789          Set_Is_Potentially_Use_Visible (U.Entity, True);
790       end if;
791    end Load_RTU;
792
793    --------------------
794    -- Make_Unit_Name --
795    --------------------
796
797    function Make_Unit_Name
798      (U : RT_Unit_Table_Record;
799       N : Node_Id) return Node_Id is
800
801       Nam  : Node_Id;
802       Scop : Entity_Id;
803
804    begin
805       Nam  := New_Reference_To (U.Entity, Standard_Location);
806       Scop := Scope (U.Entity);
807
808       if Nkind (N) = N_Defining_Program_Unit_Name then
809          while Scop /= Standard_Standard loop
810             Nam :=
811               Make_Expanded_Name (Standard_Location,
812                 Chars  => Chars (U.Entity),
813                 Prefix => New_Reference_To (Scop, Standard_Location),
814                 Selector_Name => Nam);
815             Set_Entity (Nam, U.Entity);
816
817             Scop := Scope (Scop);
818          end loop;
819       end if;
820
821       return Nam;
822    end Make_Unit_Name;
823
824    --------------------
825    -- Maybe_Add_With --
826    --------------------
827
828    procedure Maybe_Add_With (U : in out RT_Unit_Table_Record) is
829    begin
830       --  We do not need to generate a with_clause for a call issued from
831       --  RTE_Component_Available. However, for CodePeer, we need these
832       --  additional with's, because for a sequence like "if RTE_Available (X)
833       --  then ... RTE (X)" the RTE call fails to create some necessary
834       --  with's.
835
836       if RTE_Available_Call and then not Generate_SCIL then
837          return;
838       end if;
839
840       --  Avoid creating directly self-referential with clauses
841
842       if Current_Sem_Unit = U.Unum then
843          return;
844       end if;
845
846       --  Add the with_clause, if not already in the context of the
847       --  current compilation unit.
848
849       declare
850          LibUnit : constant Node_Id := Unit (Cunit (U.Unum));
851          Clause  : Node_Id;
852          Withn   : Node_Id;
853
854       begin
855          Clause := U.First_Implicit_With;
856          while Present (Clause) loop
857             if Parent (Clause) =  Cunit (Current_Sem_Unit) then
858                return;
859             end if;
860
861             Clause := Next_Implicit_With (Clause);
862          end loop;
863
864          Withn :=
865             Make_With_Clause (Standard_Location,
866               Name =>
867                 Make_Unit_Name
868                   (U, Defining_Unit_Name (Specification (LibUnit))));
869
870          Set_Library_Unit        (Withn, Cunit (U.Unum));
871          Set_Corresponding_Spec  (Withn, U.Entity);
872          Set_First_Name          (Withn, True);
873          Set_Implicit_With       (Withn, True);
874          Set_Next_Implicit_With  (Withn, U.First_Implicit_With);
875
876          U.First_Implicit_With := Withn;
877
878          Mark_Rewrite_Insertion (Withn);
879          Append (Withn, Context_Items (Cunit (Current_Sem_Unit)));
880          Check_Restriction_No_Dependence (Name (Withn), Current_Error_Node);
881       end;
882    end Maybe_Add_With;
883
884    ------------------------
885    -- Output_Entity_Name --
886    ------------------------
887
888    procedure Output_Entity_Name (Id : RE_Id; Msg : String) is
889       M : String (1 .. 2048);
890       P : Natural := 0;
891       --  M (1 .. P) is current message to be output
892
893       RE_Image : constant String := RE_Id'Image (Id);
894
895    begin
896       if Id = RE_Null then
897          return;
898       end if;
899
900       M (1 .. 9) := "\entity """;
901       P := 9;
902
903       --  Add unit name to message, excluding %s or %b at end
904
905       Get_Name_String (Get_Unit_Name (RE_Unit_Table (Id)));
906       Name_Len := Name_Len - 2;
907       Set_Casing (Mixed_Case);
908       M (P + 1 .. P + Name_Len) := Name_Buffer (1 .. Name_Len);
909       P := P + Name_Len;
910
911       --  Add a qualifying period
912
913       M (P + 1) := '.';
914       P := P + 1;
915
916       --  Add entity name and closing quote to message
917
918       Name_Len := RE_Image'Length - 3;
919       Name_Buffer (1 .. Name_Len) := RE_Image (4 .. RE_Image'Length);
920       Set_Casing (Mixed_Case);
921       M (P + 1 .. P + Name_Len) := Name_Buffer (1 .. Name_Len);
922       P := P + Name_Len;
923       M (P + 1) := '"';
924       P := P + 1;
925
926       --  Add message
927
928       M (P + 1) := ' ';
929       P := P + 1;
930       M (P + 1 .. P + Msg'Length) := Msg;
931       P := P + Msg'Length;
932
933       --  Output message at current error node location
934
935       RTE_Error_Msg (M (1 .. P));
936    end Output_Entity_Name;
937
938    --------------
939    -- RE_Chars --
940    --------------
941
942    function RE_Chars (E : RE_Id) return Name_Id is
943       RE_Name_Chars : constant String := RE_Id'Image (E);
944
945    begin
946       --  Copy name skipping initial RE_ or RO_XX characters
947
948       if RE_Name_Chars (1 .. 2) = "RE" then
949          for J in 4 .. RE_Name_Chars'Last loop
950             Name_Buffer (J - 3) := Fold_Lower (RE_Name_Chars (J));
951          end loop;
952
953          Name_Len := RE_Name_Chars'Length - 3;
954
955       else
956          for J in 7 .. RE_Name_Chars'Last loop
957             Name_Buffer (J - 6) := Fold_Lower (RE_Name_Chars (J));
958          end loop;
959
960          Name_Len := RE_Name_Chars'Length - 6;
961       end if;
962
963       return Name_Find;
964    end RE_Chars;
965
966    ---------
967    -- RTE --
968    ---------
969
970    function RTE (E : RE_Id) return Entity_Id is
971       U_Id : constant RTU_Id := RE_Unit_Table (E);
972       U    : RT_Unit_Table_Record renames RT_Unit_Table (U_Id);
973
974       Lib_Unit : Node_Id;
975       Pkg_Ent  : Entity_Id;
976       Ename    : Name_Id;
977
978       --  The following flag is used to disable front-end inlining when RTE
979       --  is invoked. This prevents the analysis of other runtime bodies when
980       --  a particular spec is loaded through Rtsfind. This is both efficient,
981       --  and it prevents spurious visibility conflicts between use-visible
982       --  user entities, and entities in run-time packages.
983
984       Save_Front_End_Inlining : Boolean;
985
986       procedure Check_RPC;
987       --  Reject programs that make use of distribution features not supported
988       --  on the current target. Also check that the PCS is compatible with
989       --  the code generator version. On such targets (VMS, Vxworks, others?)
990       --  we provide a minimal body for System.Rpc that only supplies an
991       --  implementation of Partition_Id.
992
993       function Find_Local_Entity (E : RE_Id) return Entity_Id;
994       --  This function is used when entity E is in this compilation's main
995       --  unit. It gets the value from the already compiled declaration.
996
997       ---------------
998       -- Check_RPC --
999       ---------------
1000
1001       procedure Check_RPC is
1002       begin
1003          --  Bypass this check if debug flag -gnatdR set
1004
1005          if Debug_Flag_RR then
1006             return;
1007          end if;
1008
1009          --  Otherwise we need the check if we are going after one of the
1010          --  critical entities in System.RPC / System.Partition_Interface.
1011
1012          if E = RE_Do_Rpc
1013               or else
1014             E = RE_Do_Apc
1015               or else
1016             E = RE_Params_Stream_Type
1017               or else
1018             E = RE_Request_Access
1019          then
1020             --  If generating RCI stubs, check that we have a real PCS
1021
1022             if (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
1023                   or else
1024                 Distribution_Stub_Mode = Generate_Caller_Stub_Body)
1025               and then Get_PCS_Name = Name_No_DSA
1026             then
1027                Set_Standard_Error;
1028                Write_Str ("distribution feature not supported");
1029                Write_Eol;
1030                raise Unrecoverable_Error;
1031
1032             --  In all cases, check Exp_Dist and System.Partition_Interface
1033             --  consistency.
1034
1035             elsif Get_PCS_Version /=
1036                     Exp_Dist.PCS_Version_Number (Get_PCS_Name)
1037             then
1038                Set_Standard_Error;
1039                Write_Str ("PCS version mismatch: expander ");
1040                Write_Int (Exp_Dist.PCS_Version_Number (Get_PCS_Name));
1041                Write_Str (", PCS (");
1042                Write_Name (Get_PCS_Name);
1043                Write_Str (") ");
1044                Write_Int (Get_PCS_Version);
1045                Write_Eol;
1046                raise Unrecoverable_Error;
1047             end if;
1048          end if;
1049       end Check_RPC;
1050
1051       -----------------------
1052       -- Find_Local_Entity --
1053       -----------------------
1054
1055       function Find_Local_Entity (E : RE_Id) return Entity_Id is
1056          RE_Str : constant String := RE_Id'Image (E);
1057          Nam    : Name_Id;
1058          Ent    : Entity_Id;
1059
1060          Save_Nam : constant String := Name_Buffer (1 .. Name_Len);
1061          --  Save name buffer and length over call
1062
1063       begin
1064          Name_Len := Natural'Max (0, RE_Str'Length - 3);
1065          Name_Buffer (1 .. Name_Len) :=
1066            RE_Str (RE_Str'First + 3 .. RE_Str'Last);
1067
1068          Nam := Name_Find;
1069          Ent := Entity_Id (Get_Name_Table_Info (Nam));
1070
1071          Name_Len := Save_Nam'Length;
1072          Name_Buffer (1 .. Name_Len) := Save_Nam;
1073
1074          return Ent;
1075       end Find_Local_Entity;
1076
1077    --  Start of processing for RTE
1078
1079    begin
1080       --  Doing a rtsfind in system.ads is special, as we cannot do this
1081       --  when compiling System itself. So if we are compiling system then
1082       --  we should already have acquired and processed the declaration
1083       --  of the entity. The test is to see if this compilation's main unit
1084       --  is System. If so, return the value from the already compiled
1085       --  declaration and otherwise do a regular find.
1086
1087       --  Not pleasant, but these kinds of annoying recursion when
1088       --  writing an Ada compiler in Ada have to be broken somewhere!
1089
1090       if Present (Main_Unit_Entity)
1091         and then Chars (Main_Unit_Entity) = Name_System
1092         and then Analyzed (Main_Unit_Entity)
1093         and then not Is_Child_Unit (Main_Unit_Entity)
1094       then
1095          return Check_CRT (E, Find_Local_Entity (E));
1096       end if;
1097
1098       Save_Front_End_Inlining := Front_End_Inlining;
1099       Front_End_Inlining := False;
1100
1101       --  Load unit if unit not previously loaded
1102
1103       if No (RE_Table (E)) then
1104          Load_RTU (U_Id, Id => E);
1105          Lib_Unit := Unit (Cunit (U.Unum));
1106
1107          --  In the subprogram case, we are all done, the entity we want
1108          --  is the entity for the subprogram itself. Note that we do not
1109          --  bother to check that it is the entity that was requested.
1110          --  the only way that could fail to be the case is if runtime is
1111          --  hopelessly misconfigured, and it isn't worth testing for this.
1112
1113          if Nkind (Lib_Unit) = N_Subprogram_Declaration then
1114             RE_Table (E) := U.Entity;
1115
1116          --  Otherwise we must have the package case. First check package
1117          --  entity itself (e.g. RTE_Name for System.Interrupts.Name)
1118
1119          else
1120             pragma Assert (Nkind (Lib_Unit) = N_Package_Declaration);
1121             Ename := RE_Chars (E);
1122
1123             --  First we search the package entity chain. If the package
1124             --  only has a limited view, scan the corresponding list of
1125             --  incomplete types.
1126
1127             if From_With_Type (U.Entity) then
1128                Pkg_Ent := First_Entity (Limited_View (U.Entity));
1129             else
1130                Pkg_Ent := First_Entity (U.Entity);
1131             end if;
1132
1133             while Present (Pkg_Ent) loop
1134                if Ename = Chars (Pkg_Ent) then
1135                   RE_Table (E) := Pkg_Ent;
1136                   Check_RPC;
1137                   goto Found;
1138                end if;
1139
1140                Next_Entity (Pkg_Ent);
1141             end loop;
1142
1143             --  If we did not find the entity in the package entity chain,
1144             --  then check if the package entity itself matches. Note that
1145             --  we do this check after searching the entity chain, since
1146             --  the rule is that in case of ambiguity, we prefer the entity
1147             --  defined within the package, rather than the package itself.
1148
1149             if Ename = Chars (U.Entity) then
1150                RE_Table (E) := U.Entity;
1151             end if;
1152
1153             --  If we didn't find the entity we want, something is wrong.
1154             --  We just leave RE_Table (E) set to Empty and the appropriate
1155             --  action will be taken by Check_CRT when we exit.
1156
1157          end if;
1158       end if;
1159
1160    <<Found>>
1161       Maybe_Add_With (U);
1162
1163       Front_End_Inlining := Save_Front_End_Inlining;
1164       return Check_CRT (E, RE_Table (E));
1165    end RTE;
1166
1167    -------------------
1168    -- RTE_Available --
1169    -------------------
1170
1171    function RTE_Available (E : RE_Id) return Boolean is
1172       Dummy : Entity_Id;
1173       pragma Warnings (Off, Dummy);
1174
1175       Result : Boolean;
1176
1177       Save_RTE_Available_Call : constant Boolean := RTE_Available_Call;
1178       Save_RTE_Is_Available   : constant Boolean := RTE_Is_Available;
1179       --  These are saved recursively because the call to load a unit
1180       --  caused by an upper level call may perform a recursive call
1181       --  to this routine during analysis of the corresponding unit.
1182
1183    begin
1184       RTE_Available_Call := True;
1185       RTE_Is_Available := True;
1186       Dummy := RTE (E);
1187       Result := RTE_Is_Available;
1188       RTE_Available_Call := Save_RTE_Available_Call;
1189       RTE_Is_Available   := Save_RTE_Is_Available;
1190       return Result;
1191
1192    exception
1193       when RE_Not_Available =>
1194          RTE_Available_Call := Save_RTE_Available_Call;
1195          RTE_Is_Available   := Save_RTE_Is_Available;
1196          return False;
1197    end RTE_Available;
1198
1199    --------------------------
1200    -- RTE_Record_Component --
1201    --------------------------
1202
1203    function RTE_Record_Component (E : RE_Id) return Entity_Id is
1204       U_Id     : constant RTU_Id := RE_Unit_Table (E);
1205       U        : RT_Unit_Table_Record renames RT_Unit_Table (U_Id);
1206       E1       : Entity_Id;
1207       Ename    : Name_Id;
1208       Found_E  : Entity_Id;
1209       Lib_Unit : Node_Id;
1210       Pkg_Ent  : Entity_Id;
1211
1212       --  The following flag is used to disable front-end inlining when
1213       --  RTE_Record_Component is invoked. This prevents the analysis of other
1214       --  runtime bodies when a particular spec is loaded through Rtsfind. This
1215       --  is both efficient, and it prevents spurious visibility conflicts
1216       --  between use-visible user entities, and entities in run-time packages.
1217
1218       Save_Front_End_Inlining : Boolean;
1219
1220    begin
1221       --  Note: Contrary to subprogram RTE, there is no need to do any special
1222       --  management with package system.ads because it has no record type
1223       --  declarations.
1224
1225       Save_Front_End_Inlining := Front_End_Inlining;
1226       Front_End_Inlining      := False;
1227
1228       --  Load unit if unit not previously loaded
1229
1230       if not Present (U.Entity) then
1231          Load_RTU (U_Id, Id => E);
1232       end if;
1233
1234       Lib_Unit := Unit (Cunit (U.Unum));
1235
1236       pragma Assert (Nkind (Lib_Unit) = N_Package_Declaration);
1237       Ename := RE_Chars (E);
1238
1239       --  Search the entity in the components of record type declarations
1240       --  found in the package entity chain.
1241
1242       Found_E := Empty;
1243       Pkg_Ent := First_Entity (U.Entity);
1244       Search : while Present (Pkg_Ent) loop
1245          if Is_Record_Type (Pkg_Ent) then
1246             E1 := First_Entity (Pkg_Ent);
1247             while Present (E1) loop
1248                if Ename = Chars (E1) then
1249                   pragma Assert (not Present (Found_E));
1250                   Found_E := E1;
1251                end if;
1252
1253                Next_Entity (E1);
1254             end loop;
1255          end if;
1256
1257          Next_Entity (Pkg_Ent);
1258       end loop Search;
1259
1260       --  If we didn't find the entity we want, something is wrong. The
1261       --  appropriate action will be taken by Check_CRT when we exit.
1262
1263       Maybe_Add_With (U);
1264
1265       Front_End_Inlining := Save_Front_End_Inlining;
1266       return Check_CRT (E, Found_E);
1267    end RTE_Record_Component;
1268
1269    ------------------------------------
1270    -- RTE_Record_Component_Available --
1271    ------------------------------------
1272
1273    function RTE_Record_Component_Available (E : RE_Id) return Boolean is
1274       Dummy : Entity_Id;
1275       pragma Warnings (Off, Dummy);
1276
1277       Result : Boolean;
1278
1279       Save_RTE_Available_Call : constant Boolean := RTE_Available_Call;
1280       Save_RTE_Is_Available   : constant Boolean := RTE_Is_Available;
1281       --  These are saved recursively because the call to load a unit
1282       --  caused by an upper level call may perform a recursive call
1283       --  to this routine during analysis of the corresponding unit.
1284
1285    begin
1286       RTE_Available_Call := True;
1287       RTE_Is_Available := True;
1288       Dummy := RTE_Record_Component (E);
1289       Result := RTE_Is_Available;
1290       RTE_Available_Call := Save_RTE_Available_Call;
1291       RTE_Is_Available   := Save_RTE_Is_Available;
1292       return Result;
1293
1294    exception
1295       when RE_Not_Available =>
1296          RTE_Available_Call := Save_RTE_Available_Call;
1297          RTE_Is_Available   := Save_RTE_Is_Available;
1298          return False;
1299    end RTE_Record_Component_Available;
1300
1301    -------------------
1302    -- RTE_Error_Msg --
1303    -------------------
1304
1305    procedure RTE_Error_Msg (Msg : String) is
1306    begin
1307       if RTE_Available_Call then
1308          RTE_Is_Available := False;
1309       else
1310          Error_Msg_N (Msg, Current_Error_Node);
1311
1312          --  Bump count of violations if we are in configurable run-time
1313          --  mode and this is not a continuation message.
1314
1315          if Configurable_Run_Time_Mode and then Msg (Msg'First) /= '\' then
1316             Configurable_Run_Time_Violations :=
1317               Configurable_Run_Time_Violations + 1;
1318          end if;
1319       end if;
1320    end RTE_Error_Msg;
1321
1322    ----------------
1323    -- RTU_Entity --
1324    ----------------
1325
1326    function RTU_Entity (U : RTU_Id) return Entity_Id is
1327    begin
1328       return RT_Unit_Table (U).Entity;
1329    end RTU_Entity;
1330
1331    ----------------
1332    -- RTU_Loaded --
1333    ----------------
1334
1335    function RTU_Loaded (U : RTU_Id) return Boolean is
1336    begin
1337       return Present (RT_Unit_Table (U).Entity);
1338    end RTU_Loaded;
1339
1340    --------------------
1341    -- Set_RTU_Loaded --
1342    --------------------
1343
1344    procedure Set_RTU_Loaded (N : Node_Id) is
1345       Loc   : constant Source_Ptr       := Sloc (N);
1346       Unum  : constant Unit_Number_Type := Get_Source_Unit (Loc);
1347       Uname : constant Unit_Name_Type   := Unit_Name (Unum);
1348       E     : constant Entity_Id        :=
1349                 Defining_Entity (Unit (Cunit (Unum)));
1350    begin
1351       pragma Assert (Is_Predefined_File_Name (Unit_File_Name (Unum)));
1352
1353       --  Loop through entries in RTU table looking for matching entry
1354
1355       for U_Id in RTU_Id'Range loop
1356
1357          --  Here we have a match
1358
1359          if Get_Unit_Name (U_Id) = Uname then
1360             declare
1361                U : RT_Unit_Table_Record renames RT_Unit_Table (U_Id);
1362                --  The RT_Unit_Table entry that may need updating
1363
1364             begin
1365                --  If entry is not set, set it now, and indicate that it was
1366                --  loaded through an explicit context clause.
1367
1368                if No (U.Entity) then
1369                   U := (Entity               => E,
1370                         Uname                => Get_Unit_Name (U_Id),
1371                         Unum                 => Unum,
1372                         First_Implicit_With  => Empty);
1373                end if;
1374
1375                return;
1376             end;
1377          end if;
1378       end loop;
1379    end Set_RTU_Loaded;
1380
1381    --------------------
1382    -- Text_IO_Kludge --
1383    --------------------
1384
1385    procedure Text_IO_Kludge (Nam : Node_Id) is
1386       Chrs : Name_Id;
1387
1388       type Name_Map_Type is array (Text_IO_Package_Name) of RTU_Id;
1389
1390       Name_Map : constant Name_Map_Type := Name_Map_Type'(
1391         Name_Decimal_IO     => Ada_Text_IO_Decimal_IO,
1392         Name_Enumeration_IO => Ada_Text_IO_Enumeration_IO,
1393         Name_Fixed_IO       => Ada_Text_IO_Fixed_IO,
1394         Name_Float_IO       => Ada_Text_IO_Float_IO,
1395         Name_Integer_IO     => Ada_Text_IO_Integer_IO,
1396         Name_Modular_IO     => Ada_Text_IO_Modular_IO);
1397
1398       Wide_Name_Map : constant Name_Map_Type := Name_Map_Type'(
1399         Name_Decimal_IO     => Ada_Wide_Text_IO_Decimal_IO,
1400         Name_Enumeration_IO => Ada_Wide_Text_IO_Enumeration_IO,
1401         Name_Fixed_IO       => Ada_Wide_Text_IO_Fixed_IO,
1402         Name_Float_IO       => Ada_Wide_Text_IO_Float_IO,
1403         Name_Integer_IO     => Ada_Wide_Text_IO_Integer_IO,
1404         Name_Modular_IO     => Ada_Wide_Text_IO_Modular_IO);
1405
1406       Wide_Wide_Name_Map : constant Name_Map_Type := Name_Map_Type'(
1407         Name_Decimal_IO     => Ada_Wide_Wide_Text_IO_Decimal_IO,
1408         Name_Enumeration_IO => Ada_Wide_Wide_Text_IO_Enumeration_IO,
1409         Name_Fixed_IO       => Ada_Wide_Wide_Text_IO_Fixed_IO,
1410         Name_Float_IO       => Ada_Wide_Wide_Text_IO_Float_IO,
1411         Name_Integer_IO     => Ada_Wide_Wide_Text_IO_Integer_IO,
1412         Name_Modular_IO     => Ada_Wide_Wide_Text_IO_Modular_IO);
1413
1414       To_Load : RTU_Id;
1415       --  Unit to be loaded, from one of the above maps
1416
1417    begin
1418       --  Nothing to do if name is not an identifier or a selected component
1419       --  whose selector_name is an identifier.
1420
1421       if Nkind (Nam) = N_Identifier then
1422          Chrs := Chars (Nam);
1423
1424       elsif Nkind (Nam) = N_Selected_Component
1425         and then Nkind (Selector_Name (Nam)) = N_Identifier
1426       then
1427          Chrs := Chars (Selector_Name (Nam));
1428
1429       else
1430          return;
1431       end if;
1432
1433       --  Nothing to do if name is not one of the Text_IO subpackages
1434       --  Otherwise look through loaded units, and if we find Text_IO
1435       --  or [Wide_]Wide_Text_IO already loaded, then load the proper child.
1436
1437       if Chrs in Text_IO_Package_Name then
1438          for U in Main_Unit .. Last_Unit loop
1439             Get_Name_String (Unit_File_Name (U));
1440
1441             if Name_Len = 12 then
1442
1443                --  Here is where we do the loads if we find one of the units
1444                --  Ada.Text_IO or Ada.[Wide_]Wide_Text_IO. An interesting
1445                --  detail is that these units may already be used (i.e. their
1446                --  In_Use flags may be set). Normally when the In_Use flag is
1447                --  set, the Is_Potentially_Use_Visible flag of all entities in
1448                --  the package is set, but the new entity we are mysteriously
1449                --  adding was not there to have its flag set at the time. So
1450                --  that's why we pass the extra parameter to RTU_Find, to make
1451                --  sure the flag does get set now. Given that those generic
1452                --  packages are in fact child units, we must indicate that
1453                --  they are visible.
1454
1455                if Name_Buffer (1 .. 12) = "a-textio.ads" then
1456                   To_Load := Name_Map (Chrs);
1457
1458                elsif Name_Buffer (1 .. 12) = "a-witeio.ads" then
1459                   To_Load := Wide_Name_Map (Chrs);
1460
1461                elsif Name_Buffer (1 .. 12) = "a-ztexio.ads" then
1462                   To_Load := Wide_Wide_Name_Map (Chrs);
1463
1464                else
1465                   goto Continue;
1466                end if;
1467
1468                Load_RTU (To_Load, Use_Setting => In_Use (Cunit_Entity (U)));
1469                Set_Is_Visible_Child_Unit (RT_Unit_Table (To_Load).Entity);
1470
1471                --  Prevent creation of an implicit 'with' from (for example)
1472                --  Ada.Wide_Text_IO.Integer_IO to Ada.Text_IO.Integer_IO,
1473                --  because these could create cycles. First check whether the
1474                --  simple names match ("integer_io" = "integer_io"), and then
1475                --  check whether the parent is indeed one of the
1476                --  [[Wide_]Wide_]Text_IO packages.
1477
1478                if Chrs = Chars (Cunit_Entity (Current_Sem_Unit)) then
1479                   declare
1480                      Parent_Name : constant Unit_Name_Type :=
1481                                      Get_Parent_Spec_Name
1482                                        (Unit_Name (Current_Sem_Unit));
1483
1484                   begin
1485                      if Parent_Name /= No_Unit_Name then
1486                         Get_Name_String (Parent_Name);
1487
1488                         declare
1489                            P : String renames Name_Buffer (1 .. Name_Len);
1490                         begin
1491                            if P = "ada.text_io%s"      or else
1492                               P = "ada.wide_text_io%s" or else
1493                               P = "ada.wide_wide_text_io%s"
1494                            then
1495                               goto Continue;
1496                            end if;
1497                         end;
1498                      end if;
1499                   end;
1500                end if;
1501
1502                --  Add an implicit with clause from the current unit to the
1503                --  [[Wide_]Wide_]Text_IO child (if necessary).
1504
1505                Maybe_Add_With (RT_Unit_Table (To_Load));
1506             end if;
1507
1508             <<Continue>> null;
1509          end loop;
1510       end if;
1511
1512    exception
1513       --  Generate error message if run-time unit not available
1514
1515       when RE_Not_Available =>
1516          Error_Msg_N ("& not available", Nam);
1517    end Text_IO_Kludge;
1518
1519 end Rtsfind;