OSDN Git Service

PR c++/20293
[pf3gnuchains/gcc-fork.git] / gcc / ada / lib.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                                  L I B                                   --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2005 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 2,  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 COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- As a special exception,  if other files  instantiate  generics from this --
23 -- unit, or you link  this unit with other files  to produce an executable, --
24 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
25 -- covered  by the  GNU  General  Public  License.  This exception does not --
26 -- however invalidate  any other reasons why  the executable file  might be --
27 -- covered by the  GNU Public License.                                      --
28 --                                                                          --
29 -- GNAT was originally developed  by the GNAT team at  New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
31 --                                                                          --
32 ------------------------------------------------------------------------------
33
34 pragma Style_Checks (All_Checks);
35 --  Subprogram ordering not enforced in this unit
36 --  (because of some logical groupings).
37
38 with Atree;   use Atree;
39 with Einfo;   use Einfo;
40 with Fname;   use Fname;
41 with Namet;   use Namet;
42 with Output;  use Output;
43 with Sinfo;   use Sinfo;
44 with Sinput;  use Sinput;
45 with Stand;   use Stand;
46 with Stringt; use Stringt;
47 with Tree_IO; use Tree_IO;
48 with Uname;   use Uname;
49
50 package body Lib is
51
52    Switch_Storing_Enabled : Boolean := True;
53    --  Set to False by Disable_Switch_Storing
54
55    -----------------------
56    -- Local Subprograms --
57    -----------------------
58
59    type SEU_Result is (
60       Yes_Before, -- S1 is in same extended unit as S2 and appears before it
61       Yes_Same,   -- S1 is in same extended unit as S2, Slocs are the same
62       Yes_After,  -- S1 is in same extended unit as S2, and appears after it
63       No);        -- S2 is not in same extended unit as S2
64
65    function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result;
66    --  Used by In_Same_Extended_Unit and Earlier_In_Extended_Unit. Returns
67    --  value as described above.
68
69    --------------------------------------------
70    -- Access Functions for Unit Table Fields --
71    --------------------------------------------
72
73    function Cunit (U : Unit_Number_Type) return Node_Id is
74    begin
75       return Units.Table (U).Cunit;
76    end Cunit;
77
78    function Cunit_Entity (U : Unit_Number_Type) return Entity_Id is
79    begin
80       return Units.Table (U).Cunit_Entity;
81    end Cunit_Entity;
82
83    function Dependency_Num (U : Unit_Number_Type) return Nat is
84    begin
85       return Units.Table (U).Dependency_Num;
86    end Dependency_Num;
87
88    function Dynamic_Elab (U : Unit_Number_Type) return Boolean is
89    begin
90       return Units.Table (U).Dynamic_Elab;
91    end Dynamic_Elab;
92
93    function Error_Location (U : Unit_Number_Type) return Source_Ptr is
94    begin
95       return Units.Table (U).Error_Location;
96    end Error_Location;
97
98    function Expected_Unit (U : Unit_Number_Type) return Unit_Name_Type is
99    begin
100       return Units.Table (U).Expected_Unit;
101    end Expected_Unit;
102
103    function Fatal_Error (U : Unit_Number_Type) return Boolean is
104    begin
105       return Units.Table (U).Fatal_Error;
106    end Fatal_Error;
107
108    function Generate_Code (U : Unit_Number_Type) return Boolean is
109    begin
110       return Units.Table (U).Generate_Code;
111    end Generate_Code;
112
113    function Has_RACW (U : Unit_Number_Type) return Boolean is
114    begin
115       return Units.Table (U).Has_RACW;
116    end Has_RACW;
117
118    function Ident_String (U : Unit_Number_Type) return Node_Id is
119    begin
120       return Units.Table (U).Ident_String;
121    end Ident_String;
122
123    function Loading (U : Unit_Number_Type) return Boolean is
124    begin
125       return Units.Table (U).Loading;
126    end Loading;
127
128    function Main_Priority (U : Unit_Number_Type) return Int is
129    begin
130       return Units.Table (U).Main_Priority;
131    end Main_Priority;
132
133    function Munit_Index (U : Unit_Number_Type) return Nat is
134    begin
135       return Units.Table (U).Munit_Index;
136    end Munit_Index;
137
138    function Source_Index (U : Unit_Number_Type) return Source_File_Index is
139    begin
140       return Units.Table (U).Source_Index;
141    end Source_Index;
142
143    function Unit_File_Name (U : Unit_Number_Type) return File_Name_Type is
144    begin
145       return Units.Table (U).Unit_File_Name;
146    end Unit_File_Name;
147
148    function Unit_Name (U : Unit_Number_Type) return Unit_Name_Type is
149    begin
150       return Units.Table (U).Unit_Name;
151    end Unit_Name;
152
153    ------------------------------------------
154    -- Subprograms to Set Unit Table Fields --
155    ------------------------------------------
156
157    procedure Set_Cunit (U : Unit_Number_Type; N : Node_Id) is
158    begin
159       Units.Table (U).Cunit := N;
160    end Set_Cunit;
161
162    procedure Set_Cunit_Entity (U : Unit_Number_Type; E : Entity_Id) is
163    begin
164       Units.Table (U).Cunit_Entity := E;
165       Set_Is_Compilation_Unit (E);
166    end Set_Cunit_Entity;
167
168    procedure Set_Dynamic_Elab (U : Unit_Number_Type; B : Boolean := True) is
169    begin
170       Units.Table (U).Dynamic_Elab := B;
171    end Set_Dynamic_Elab;
172
173    procedure Set_Error_Location (U : Unit_Number_Type; W : Source_Ptr) is
174    begin
175       Units.Table (U).Error_Location := W;
176    end Set_Error_Location;
177
178    procedure Set_Fatal_Error (U : Unit_Number_Type; B : Boolean := True) is
179    begin
180       Units.Table (U).Fatal_Error := B;
181    end Set_Fatal_Error;
182
183    procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True) is
184    begin
185       Units.Table (U).Generate_Code := B;
186    end Set_Generate_Code;
187
188    procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True) is
189    begin
190       Units.Table (U).Has_RACW := B;
191    end Set_Has_RACW;
192
193    procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id) is
194    begin
195       Units.Table (U).Ident_String := N;
196    end Set_Ident_String;
197
198    procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True) is
199    begin
200       Units.Table (U).Loading := B;
201    end Set_Loading;
202
203    procedure Set_Main_Priority (U : Unit_Number_Type; P : Int) is
204    begin
205       Units.Table (U).Main_Priority := P;
206    end Set_Main_Priority;
207
208    procedure Set_Unit_Name (U : Unit_Number_Type; N : Unit_Name_Type) is
209    begin
210       Units.Table (U).Unit_Name := N;
211    end Set_Unit_Name;
212
213    ------------------------------
214    -- Check_Same_Extended_Unit --
215    ------------------------------
216
217    function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result is
218       Sloc1  : Source_Ptr;
219       Sloc2  : Source_Ptr;
220       Sind1  : Source_File_Index;
221       Sind2  : Source_File_Index;
222       Inst1  : Source_Ptr;
223       Inst2  : Source_Ptr;
224       Unum1  : Unit_Number_Type;
225       Unum2  : Unit_Number_Type;
226       Unit1  : Node_Id;
227       Unit2  : Node_Id;
228       Depth1 : Nat;
229       Depth2 : Nat;
230
231    begin
232       if S1 = No_Location or else S2 = No_Location then
233          return No;
234
235       elsif S1 = Standard_Location then
236          if S2 = Standard_Location then
237             return Yes_Same;
238          else
239             return No;
240          end if;
241
242       elsif S2 = Standard_Location then
243          return No;
244       end if;
245
246       Sloc1 := S1;
247       Sloc2 := S2;
248       Unum1 := Get_Code_Unit (Sloc1);
249       Unum2 := Get_Code_Unit (Sloc2);
250
251       loop
252          Sind1 := Get_Source_File_Index (Sloc1);
253          Sind2 := Get_Source_File_Index (Sloc2);
254
255          if Sind1 = Sind2 then
256             if Sloc1 < Sloc2 then
257                return Yes_Before;
258             elsif Sloc1 > Sloc2 then
259                return Yes_After;
260             else
261                return Yes_Same;
262             end if;
263          end if;
264
265          --  OK, the two nodes are in separate source elements, but this is not
266          --  decisive, because of the issue of subunits and instantiations.
267
268          --  First we deal with subunits, since if the subunit is in an
269          --  instantiation, we know that the parent is in the corresponding
270          --  instantiation, since that is the only way we can have a subunit
271          --  that is part of an instantiation.
272
273          Unit1 := Unit (Cunit (Unum1));
274          Unit2 := Unit (Cunit (Unum2));
275
276          if Nkind (Unit1) = N_Subunit
277            and then Present (Corresponding_Stub (Unit1))
278          then
279             --  Both in subunits. They could have a common ancestor. If they
280             --  do, then the deeper one must have a longer unit name. Replace
281             --  the deeper one with its corresponding stub, in order to find
282             --  nearest common ancestor, if any.
283
284             if Nkind (Unit2) = N_Subunit
285               and then Present (Corresponding_Stub (Unit2))
286             then
287                if Length_Of_Name (Unit_Name (Unum1)) <
288                   Length_Of_Name (Unit_Name (Unum2))
289                then
290                   Sloc2 := Sloc (Corresponding_Stub (Unit2));
291                   Unum2 := Get_Source_Unit (Sloc2);
292                   goto Continue;
293
294                else
295                   Sloc1 := Sloc (Corresponding_Stub (Unit1));
296                   Unum1 := Get_Source_Unit (Sloc1);
297                   goto Continue;
298                end if;
299
300             --  Nod1 in subunit, Nod2 not
301
302             else
303                Sloc1 := Sloc (Corresponding_Stub (Unit1));
304                Unum1 := Get_Source_Unit (Sloc1);
305                goto Continue;
306             end if;
307
308          --  Nod2 in subunit, Nod1 not
309
310          elsif Nkind (Unit2) = N_Subunit
311            and then Present (Corresponding_Stub (Unit2))
312          then
313             Sloc2 := Sloc (Corresponding_Stub (Unit2));
314             Unum2 := Get_Source_Unit (Sloc2);
315             goto Continue;
316          end if;
317
318          --  At this stage we know that neither is a subunit, so we deal
319          --  with instantiations, since we culd have a common ancestor
320
321          Inst1 := Instantiation (Sind1);
322          Inst2 := Instantiation (Sind2);
323
324          if Inst1 /= No_Location then
325
326             --  Both are instantiations
327
328             if Inst2 /= No_Location then
329
330                Depth1 := Instantiation_Depth (Sloc1);
331                Depth2 := Instantiation_Depth (Sloc2);
332
333                if Depth1 < Depth2 then
334                   Sloc2 := Inst2;
335                   Unum2 := Get_Source_Unit (Sloc2);
336                   goto Continue;
337
338                elsif Depth1 > Depth2 then
339                   Sloc1 := Inst1;
340                   Unum1 := Get_Source_Unit (Sloc1);
341                   goto Continue;
342
343                else
344                   Sloc1 := Inst1;
345                   Sloc2 := Inst2;
346                   Unum1 := Get_Source_Unit (Sloc1);
347                   Unum2 := Get_Source_Unit (Sloc2);
348                   goto Continue;
349                end if;
350
351             --  Only first node is in instantiation
352
353             else
354                Sloc1 := Inst1;
355                Unum1 := Get_Source_Unit (Sloc1);
356                goto Continue;
357             end if;
358
359          --  Only second node is instantiation
360
361          elsif Inst2 /= No_Location then
362             Sloc2 := Inst2;
363             Unum2 := Get_Source_Unit (Sloc2);
364             goto Continue;
365          end if;
366
367          --  No instantiations involved, so we are not in the same unit
368          --  However, there is one case still to check, namely the case
369          --  where one location is in the spec, and the other in the
370          --  corresponding body (the spec location is earlier).
371
372          if Nkind (Unit1) = N_Subprogram_Body
373               or else
374             Nkind (Unit1) = N_Package_Body
375          then
376             if Library_Unit (Cunit (Unum1)) = Cunit (Unum2) then
377                return Yes_After;
378             end if;
379
380          elsif Nkind (Unit2) = N_Subprogram_Body
381                  or else
382                Nkind (Unit2) = N_Package_Body
383          then
384             if Library_Unit (Cunit (Unum2)) = Cunit (Unum1) then
385                return Yes_Before;
386             end if;
387          end if;
388
389          --  If that special case does not occur, then we are certain that
390          --  the two locations are really in separate units.
391
392          return No;
393
394          <<Continue>>
395             null;
396       end loop;
397    end Check_Same_Extended_Unit;
398
399    -------------------------------
400    -- Compilation_Switches_Last --
401    -------------------------------
402
403    function Compilation_Switches_Last return Nat is
404    begin
405       return Compilation_Switches.Last;
406    end Compilation_Switches_Last;
407
408    procedure Disable_Switch_Storing is
409    begin
410       Switch_Storing_Enabled := False;
411    end Disable_Switch_Storing;
412
413    ------------------------------
414    -- Earlier_In_Extended_Unit --
415    ------------------------------
416
417    function Earlier_In_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
418    begin
419       return Check_Same_Extended_Unit (S1, S2) = Yes_Before;
420    end Earlier_In_Extended_Unit;
421
422    ----------------------------
423    -- Entity_Is_In_Main_Unit --
424    ----------------------------
425
426    function Entity_Is_In_Main_Unit (E : Entity_Id) return Boolean is
427       S : Entity_Id;
428
429    begin
430       S := Scope (E);
431
432       while S /= Standard_Standard loop
433          if S = Main_Unit_Entity then
434             return True;
435          elsif Ekind (S) = E_Package and then Is_Child_Unit (S) then
436             return False;
437          else
438             S := Scope (S);
439          end if;
440       end loop;
441
442       return False;
443    end Entity_Is_In_Main_Unit;
444
445    ---------------------------------
446    -- Generic_Separately_Compiled --
447    ---------------------------------
448
449    function Generic_Separately_Compiled (E : Entity_Id) return Boolean is
450    begin
451       --  We do not generate object files for internal generics, because
452       --  the only thing they would contain is the elaboration boolean, and
453       --  we are careful to elaborate all predefined units first anyway, so
454       --  this boolean is not needed.
455
456       if Is_Internal_File_Name
457           (Fname => Unit_File_Name (Get_Source_Unit (E)),
458            Renamings_Included => True)
459       then
460          return False;
461
462       --  All other generic units do generate object files
463
464       else
465          return True;
466       end if;
467    end Generic_Separately_Compiled;
468
469    function Generic_Separately_Compiled
470      (Sfile : File_Name_Type) return Boolean
471    is
472    begin
473       --  Exactly the same as previous function, but works directly on a file
474       --  name.
475
476       if Is_Internal_File_Name
477           (Fname              => Sfile,
478            Renamings_Included => True)
479       then
480          return False;
481
482       --  All other generic units do generate object files
483
484       else
485          return True;
486       end if;
487    end Generic_Separately_Compiled;
488
489    -------------------
490    -- Get_Code_Unit --
491    -------------------
492
493    function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type is
494    begin
495       --  Search table unless we have No_Location, which can happen if the
496       --  relevant location has not been set yet. Happens for example when
497       --  we obtain Sloc (Cunit (Main_Unit)) before it is set.
498
499       if S /= No_Location then
500          declare
501             Source_File : constant Source_File_Index :=
502                             Get_Source_File_Index (Top_Level_Location (S));
503
504          begin
505             for U in Units.First .. Units.Last loop
506                if Source_Index (U) = Source_File then
507                   return U;
508                end if;
509             end loop;
510          end;
511       end if;
512
513       --  If S was No_Location, or was not in the table, we must be in the
514       --  main source unit (and the value has not been placed in the table yet)
515
516       return Main_Unit;
517    end Get_Code_Unit;
518
519    function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
520    begin
521       return Get_Code_Unit (Sloc (N));
522    end Get_Code_Unit;
523
524    ----------------------------
525    -- Get_Compilation_Switch --
526    ----------------------------
527
528    function Get_Compilation_Switch (N : Pos) return String_Ptr is
529    begin
530       if N <= Compilation_Switches.Last then
531          return Compilation_Switches.Table (N);
532
533       else
534          return null;
535       end if;
536    end Get_Compilation_Switch;
537
538    ----------------------------------
539    -- Get_Cunit_Entity_Unit_Number --
540    ----------------------------------
541
542    function Get_Cunit_Entity_Unit_Number
543      (E : Entity_Id) return Unit_Number_Type
544    is
545    begin
546       for U in Units.First .. Units.Last loop
547          if Cunit_Entity (U) = E then
548             return U;
549          end if;
550       end loop;
551
552       --  If not in the table, must be the main source unit, and we just
553       --  have not got it put into the table yet.
554
555       return Main_Unit;
556    end Get_Cunit_Entity_Unit_Number;
557
558    ---------------------------
559    -- Get_Cunit_Unit_Number --
560    ---------------------------
561
562    function Get_Cunit_Unit_Number (N : Node_Id) return Unit_Number_Type is
563    begin
564       for U in Units.First .. Units.Last loop
565          if Cunit (U) = N then
566             return U;
567          end if;
568       end loop;
569
570       --  If not in the table, must be the main source unit, and we just
571       --  have not got it put into the table yet.
572
573       return Main_Unit;
574    end Get_Cunit_Unit_Number;
575
576    ---------------------
577    -- Get_Source_Unit --
578    ---------------------
579
580    function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type is
581    begin
582       --  Search table unless we have No_Location, which can happen if the
583       --  relevant location has not been set yet. Happens for example when
584       --  we obtain Sloc (Cunit (Main_Unit)) before it is set.
585
586       if S /= No_Location then
587          declare
588             Source_File : Source_File_Index :=
589                             Get_Source_File_Index (Top_Level_Location (S));
590
591          begin
592             Source_File := Get_Source_File_Index (S);
593             while Template (Source_File) /= No_Source_File loop
594                Source_File := Template (Source_File);
595             end loop;
596
597             for U in Units.First .. Units.Last loop
598                if Source_Index (U) = Source_File then
599                   return U;
600                end if;
601             end loop;
602          end;
603       end if;
604
605       --  If S was No_Location, or was not in the table, we must be in the
606       --  main source unit (and the value has not got put into the table yet)
607
608       return Main_Unit;
609    end Get_Source_Unit;
610
611    function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
612    begin
613       return Get_Source_Unit (Sloc (N));
614    end Get_Source_Unit;
615
616    --------------------------------
617    -- In_Extended_Main_Code_Unit --
618    --------------------------------
619
620    function In_Extended_Main_Code_Unit
621      (N : Node_Or_Entity_Id) return Boolean
622    is
623    begin
624       if Sloc (N) = Standard_Location then
625          return True;
626
627       elsif Sloc (N) = No_Location then
628          return False;
629
630       --  Special case Itypes to test the Sloc of the associated node. The
631       --  reason we do this is for possible calls from gigi after -gnatD
632       --  processing is complete in sprint. This processing updates the
633       --  sloc fields of all nodes in the tree, but itypes are not in the
634       --  tree so their slocs do not get updated.
635
636       elsif Nkind (N) = N_Defining_Identifier
637         and then Is_Itype (N)
638       then
639          return In_Extended_Main_Code_Unit (Associated_Node_For_Itype (N));
640
641       --  Otherwise see if we are in the main unit
642
643       elsif Get_Code_Unit (Sloc (N)) = Get_Code_Unit (Cunit (Main_Unit)) then
644          return True;
645
646       --  Node may be in spec (or subunit etc) of main unit
647
648       else
649          return
650            In_Same_Extended_Unit (N, Cunit (Main_Unit));
651       end if;
652    end In_Extended_Main_Code_Unit;
653
654    function In_Extended_Main_Code_Unit (Loc : Source_Ptr) return Boolean is
655    begin
656       if Loc = Standard_Location then
657          return True;
658
659       elsif Loc = No_Location then
660          return False;
661
662       --  Otherwise see if we are in the main unit
663
664       elsif Get_Code_Unit (Loc) = Get_Code_Unit (Cunit (Main_Unit)) then
665          return True;
666
667       --  Location may be in spec (or subunit etc) of main unit
668
669       else
670          return
671            In_Same_Extended_Unit (Loc, Sloc (Cunit (Main_Unit)));
672       end if;
673    end In_Extended_Main_Code_Unit;
674
675    ----------------------------------
676    -- In_Extended_Main_Source_Unit --
677    ----------------------------------
678
679    function In_Extended_Main_Source_Unit
680      (N : Node_Or_Entity_Id) return Boolean
681    is
682       Nloc : constant Source_Ptr := Sloc (N);
683       Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));
684
685    begin
686       --  If Mloc is not set, it means we are still parsing the main unit,
687       --  so everything so far is in the extended main source unit.
688
689       if Mloc = No_Location then
690          return True;
691
692       --  Special value cases
693
694       elsif Nloc = Standard_Location then
695          return True;
696
697       elsif Nloc = No_Location then
698          return False;
699
700       --  Special case Itypes to test the Sloc of the associated node. The
701       --  reason we do this is for possible calls from gigi after -gnatD
702       --  processing is complete in sprint. This processing updates the
703       --  sloc fields of all nodes in the tree, but itypes are not in the
704       --  tree so their slocs do not get updated.
705
706       elsif Nkind (N) = N_Defining_Identifier
707         and then Is_Itype (N)
708       then
709          return In_Extended_Main_Source_Unit (Associated_Node_For_Itype (N));
710
711       --  Otherwise compare original locations to see if in same unit
712
713       else
714          return
715            In_Same_Extended_Unit
716              (Original_Location (Nloc), Original_Location (Mloc));
717       end if;
718    end In_Extended_Main_Source_Unit;
719
720    function In_Extended_Main_Source_Unit
721      (Loc : Source_Ptr) return Boolean
722    is
723       Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));
724
725    begin
726       --  If Mloc is not set, it means we are still parsing the main unit,
727       --  so everything so far is in the extended main source unit.
728
729       if Mloc = No_Location then
730          return True;
731
732       --  Special value cases
733
734       elsif Loc = Standard_Location then
735          return True;
736
737       elsif Loc = No_Location then
738          return False;
739
740       --  Otherwise compare original locations to see if in same unit
741
742       else
743          return
744            In_Same_Extended_Unit
745              (Original_Location (Loc), Original_Location (Mloc));
746       end if;
747    end In_Extended_Main_Source_Unit;
748
749    -----------------------
750    -- In_Same_Code_Unit --
751    -----------------------
752
753    function In_Same_Code_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
754       S1 : constant Source_Ptr := Sloc (N1);
755       S2 : constant Source_Ptr := Sloc (N2);
756
757    begin
758       if S1 = No_Location or else S2 = No_Location then
759          return False;
760
761       elsif S1 = Standard_Location then
762          return S2 = Standard_Location;
763
764       elsif S2 = Standard_Location then
765          return False;
766       end if;
767
768       return Get_Code_Unit (N1) = Get_Code_Unit (N2);
769    end In_Same_Code_Unit;
770
771    ---------------------------
772    -- In_Same_Extended_Unit --
773    ---------------------------
774
775    function In_Same_Extended_Unit
776      (N1, N2 : Node_Or_Entity_Id) return Boolean
777    is
778    begin
779       return Check_Same_Extended_Unit (Sloc (N1), Sloc (N2)) /= No;
780    end In_Same_Extended_Unit;
781
782    function In_Same_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
783    begin
784       return Check_Same_Extended_Unit (S1, S2) /= No;
785    end In_Same_Extended_Unit;
786
787    -------------------------
788    -- In_Same_Source_Unit --
789    -------------------------
790
791    function In_Same_Source_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
792       S1 : constant Source_Ptr := Sloc (N1);
793       S2 : constant Source_Ptr := Sloc (N2);
794
795    begin
796       if S1 = No_Location or else S2 = No_Location then
797          return False;
798
799       elsif S1 = Standard_Location then
800          return S2 = Standard_Location;
801
802       elsif S2 = Standard_Location then
803          return False;
804       end if;
805
806       return Get_Source_Unit (N1) = Get_Source_Unit (N2);
807    end In_Same_Source_Unit;
808
809    -----------------------------
810    -- Increment_Serial_Number --
811    -----------------------------
812
813    function Increment_Serial_Number return Nat is
814       TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
815    begin
816       TSN := TSN + 1;
817       return TSN;
818    end Increment_Serial_Number;
819
820    ----------------
821    -- Initialize --
822    ----------------
823
824    procedure Initialize is
825    begin
826       Linker_Option_Lines.Init;
827       Load_Stack.Init;
828       Units.Init;
829       Compilation_Switches.Init;
830    end Initialize;
831
832    ---------------
833    -- Is_Loaded --
834    ---------------
835
836    function Is_Loaded (Uname : Unit_Name_Type) return Boolean is
837    begin
838       for Unum in Units.First .. Units.Last loop
839          if Uname = Unit_Name (Unum) then
840             return True;
841          end if;
842       end loop;
843
844       return False;
845    end Is_Loaded;
846
847    ---------------
848    -- Last_Unit --
849    ---------------
850
851    function Last_Unit return Unit_Number_Type is
852    begin
853       return Units.Last;
854    end Last_Unit;
855
856    ----------
857    -- List --
858    ----------
859
860    procedure List (File_Names_Only : Boolean := False) is separate;
861
862    ----------
863    -- Lock --
864    ----------
865
866    procedure Lock is
867    begin
868       Linker_Option_Lines.Locked := True;
869       Load_Stack.Locked := True;
870       Units.Locked := True;
871       Linker_Option_Lines.Release;
872       Load_Stack.Release;
873       Units.Release;
874    end Lock;
875
876    ---------------
877    -- Num_Units --
878    ---------------
879
880    function Num_Units return Nat is
881    begin
882       return Int (Units.Last) - Int (Main_Unit) + 1;
883    end Num_Units;
884
885    -----------------
886    -- Remove_Unit --
887    -----------------
888
889    procedure Remove_Unit (U : Unit_Number_Type) is
890    begin
891       if U = Units.Last then
892          Units.Decrement_Last;
893       end if;
894    end Remove_Unit;
895
896    ----------------------------------
897    -- Replace_Linker_Option_String --
898    ----------------------------------
899
900    procedure Replace_Linker_Option_String
901      (S : String_Id; Match_String : String)
902    is
903    begin
904       if Match_String'Length > 0 then
905          for J in 1 .. Linker_Option_Lines.Last loop
906             String_To_Name_Buffer (Linker_Option_Lines.Table (J).Option);
907
908             if Match_String = Name_Buffer (1 .. Match_String'Length) then
909                Linker_Option_Lines.Table (J).Option := S;
910                return;
911             end if;
912          end loop;
913       end if;
914
915       Store_Linker_Option_String (S);
916    end Replace_Linker_Option_String;
917
918    ----------
919    -- Sort --
920    ----------
921
922    procedure Sort (Tbl : in out Unit_Ref_Table) is separate;
923
924    ------------------------------
925    -- Store_Compilation_Switch --
926    ------------------------------
927
928    procedure Store_Compilation_Switch (Switch : String) is
929    begin
930       if Switch_Storing_Enabled then
931          Compilation_Switches.Increment_Last;
932          Compilation_Switches.Table (Compilation_Switches.Last) :=
933            new String'(Switch);
934
935          --  Fix up --RTS flag which has been transformed by the gcc driver
936          --  into -fRTS
937
938          if Switch'Last >= Switch'First + 4
939            and then Switch (Switch'First .. Switch'First + 4) = "-fRTS"
940          then
941             Compilation_Switches.Table
942               (Compilation_Switches.Last) (Switch'First + 1) := '-';
943          end if;
944       end if;
945    end Store_Compilation_Switch;
946
947    --------------------------------
948    -- Store_Linker_Option_String --
949    --------------------------------
950
951    procedure Store_Linker_Option_String (S : String_Id) is
952    begin
953       Linker_Option_Lines.Increment_Last;
954       Linker_Option_Lines.Table (Linker_Option_Lines.Last) :=
955         (Option => S, Unit => Current_Sem_Unit);
956    end Store_Linker_Option_String;
957
958    -------------------------------
959    -- Synchronize_Serial_Number --
960    -------------------------------
961
962    procedure Synchronize_Serial_Number is
963       TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
964    begin
965       TSN := TSN + 1;
966    end Synchronize_Serial_Number;
967
968    ---------------
969    -- Tree_Read --
970    ---------------
971
972    procedure Tree_Read is
973       N : Nat;
974       S : String_Ptr;
975
976    begin
977       Units.Tree_Read;
978
979       --  Read Compilation_Switches table
980
981       Tree_Read_Int (N);
982       Compilation_Switches.Set_Last (N);
983
984       for J in 1 .. N loop
985          Tree_Read_Str (S);
986          Compilation_Switches.Table (J) := S;
987       end loop;
988    end Tree_Read;
989
990    ----------------
991    -- Tree_Write --
992    ----------------
993
994    procedure Tree_Write is
995    begin
996       Units.Tree_Write;
997
998       --  Write Compilation_Switches table
999
1000       Tree_Write_Int (Compilation_Switches.Last);
1001
1002       for J in 1 .. Compilation_Switches.Last loop
1003          Tree_Write_Str (Compilation_Switches.Table (J));
1004       end loop;
1005    end Tree_Write;
1006
1007    -----------------
1008    -- Version_Get --
1009    -----------------
1010
1011    function Version_Get (U : Unit_Number_Type) return Word_Hex_String is
1012    begin
1013       return Get_Hex_String (Units.Table (U).Version);
1014    end Version_Get;
1015
1016    ------------------------
1017    -- Version_Referenced --
1018    ------------------------
1019
1020    procedure Version_Referenced (S : String_Id) is
1021    begin
1022       Version_Ref.Append (S);
1023    end Version_Referenced;
1024
1025 end Lib;