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