OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ada/] [rtsfind.adb] - Blame information for rev 281

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.