2004-06-25 Pascal Obry <obry@gnat.com> * makegpr.adb (Build_Library): Remove parameter Lib_Address and Relocatable from Build_Dynamic_Library call. * gnat_ugn.texi: Change documentation about Library_Kind. Dynamic and Relocatable are now synonym. * Makefile.in: Use s-parame-mingw.adb on MingW platform. * mlib-prj.adb (Build_Library): Remove DLL_Address constant definition. Remove parameter Lib_Address and Relocatable from Build_Dynamic_Library call. * mlib-tgt.ads, mlib-tgt.adb (Build_Dynamic_Library): Remove parameter Lib_Address and Relocatable. (Default_DLL_Address): Removed. * mlib-tgt-tru64.adb, mlib-tgt-aix.adb, mlib-tgt-irix.adb, mlib-tgt-hpux.adb, mlib-tgt-linux.adb, mlib-tgt-solaris.adb, mlib-tgt-vms-alpha.adb, mlib-tgt-vms-ia64.adb, mlib-tgt-vxworks.adb: (Build_Dynamic_Library): Remove parameter Lib_Address and Relocatable. (Default_DLL_Address): Removed. * mlib-tgt-mingw.adb: Ditto. (Build_Dynamic_Library): Do not add "lib" prefix to the DLL name. * s-taprop-mingw.adb (Create_Task): Use Adjust_Storage_Size to compute the initial thread stack size. * a-strmap.ads: Move package L to private part as it is not used in the spec. Found while reading code. 2004-06-25 Olivier Hainque <hainque@act-europe.fr> * tracebak.c: Introduce support for a GCC infrastructure based implementation of __gnat_backtrace. * raise.c: Don't rely on a C mapping of the GNAT_GCC_Exception record any more. Use accessors instead. This eases maintenance and relaxes some alignment constraints. (_GNAT_Exception structure): Remove the Ada specific fields (EID_For, Adjust_N_Cleanups_For): New accessors, exported by a-exexpr.adb. (is_handled_by, __gnat_eh_personality): Replace component references to exception structure by use of the new accessors. * init.c (__gnat_initialize): Adjust comments to match the just reverted meaning of the -static link-time option. * adaint.c (convert_addresses): Arrange not to define a stub for mips-irix any more, as we now want to rely on a real version from a recent libaddr2line. * a-exexpr.adb: Provide new accessors to a GNAT_GCC occurrence, so that the personality routine can use them and not have to rely on a C counterpart of the record anymore. This simplifies maintenance and relaxes the constraint of having Standard'Maximum_Alignment match BIGGEST_ALIGNMENT. Update comments, and add a section on the common header alignment issue. 2004-06-25 Geert Bosch <bosch@gnat.com> * a-ngelfu.adb (Tanh): Use full 20 digit precision for constants in polynomial approximation. Fixes inconsistency with Cody/Waite algorithm. 2004-06-25 Robert Dewar <dewar@gnat.com> * gnat_rm.texi: Fix section on component clauses to indicate that the restriction on byte boundary placement still applies for bit packed arrays. Add comment on stack usage from Initialize_Scalars * gnat_ugn.texi: Add documentation for -gnatyLnnn * stylesw.ads, stylesw.adb: Implement new -gnatyLnnn option for limiting nesting level. * usage.adb: Add line for -gnatyLnnn switch * g-debpoo.ads, xtreeprs.adb, sinput.ads, sem_ch13.ads, sem_ch13.adb, exp_aggr.adb: Minor reformatting * sem_prag.adb (Process_Atomic_Shared_Volatile): Set Is_Atomic on base type as well as on the subtype. This corrects a problem in freeze in setting alignments of atomic types. * sem_eval.ads: Minor comment typo fixed * par-util.adb (Push_Scope_Stack): Check for violation of max nesting level. Minor reformatting. * fname.adb (Is_Predefined_File_Name): Require a letter after the minus sign. This means that file names like a--b.adb will not be considered predefined. * freeze.adb: Propagate new flag Must_Be_On_Byte_Boundary to containing record Test new flag and give diagnostic for bad component clause. (Freeze_Entity): Set alignment of array from component alignment in cases where this is safe to do. * exp_pakd.adb: Set new flag Must_Be_On_Byte_Boundary for large packed arrays. * cstand.adb: (Create_Standard): Set alignment of String to 1 * einfo.ads, einfo.adb: Introduce new flag Must_Be_On_Byte_Boundary * exp_ch4.adb (Expand_Array_Equality): Improve efficiency of generated code in the common constrained array cases. * a-storio.adb: Change implementation to avoid possible alignment problems on machines requiring strict alignment (data should be moved as type Buffer, not type Elmt). * checks.adb (Apply_Array_Size_Check): Improve these checks by killing the overflow checks which we really do not need (64-bits is enough). 2004-06-25 Vincent Celier <celier@gnat.com> * makegpr.adb (Is_Included_In_Global_Archive): New Boolean function (Add_Archives.Recursive_Add_Archives): Call Add_Archive_Path inconditionally for the main project. (Recursive_Add_Archives.Add_Archive_Path): New procedure (Link_Executables.Check_Time_Stamps): New procedure (Link_Executables.Link_Foreign): New procedure Changes made to reduce nesting level of this package (Check): New procedure (Add_Switches): When not in quiet output, check that a switch is not the concatenation of several valid switches. If it is, issue a warning. (Build_Global_Archive): If the global archive is rebuilt, linking need to be done. (Compile_Sources): Rebuilding a library archive does not imply rebuilding the global archive. (Build_Global_Archive): New procedure (Build_Library): New name for Build_Archive, now only for library project (Check_Archive_Builder): New procedure (Create_Global_Archive_Dependency_File): New procedure (Gprmake): Call Build_Global_Archive before linking * makegpr.adb: Use Other_Sources_Present instead of Sources_Present throughout. (Scan_Arg): Display the Copyright notice when -v is used * gnat_ugn.texi: Document new switch -files= (VMS qualifier /FILES=) for gnatls. * vms_data.ads: Add qualifier /MAX_NESTING=nnn (-gnatyLnnn) for GNAT COMPILE. Add new GNAT LIST qualifier /FILES= Added qualifier /DIRECTORY= to GNAT METRIC Added qualifier /FILES= to GNAT METRIC Added qualifier /FILES to GNAT PRETTY * switch.adb (Is_Front_End_Switch): Refine the test for --RTS or -fRTS, to take into account both versions of the switch. * switch-c.adb (Scan_Front_End_Switches): New switch -gnatez. Should always be the last switch to the gcc driver. Disable switch storing so that switches automatically added by the gcc driver are not put in the ALI file. * prj.adb (Project_Empty): Take into account changes in components of Project_Data. * prj.ads (Languages_Processed): New enumaration value All_Languages. * prj.ads (Project_Data): Remove component Lib_Elaboration: never used. Split Boolean component Ada_Sources_Present in two Boolean components Ada_Sources_Present and Other_Sources_Present. Minor reformatting * prj-env.adb (For_All_Source_Dirs.Add): Use Ada_Sources_Present instead of Sources_Present. (Set_Ada_Paths.Add.Recursive_Add): Ditto * prj-nmsc.adb: Minor reformatting (Check_Ada_Naming_Scheme): New name of procedure Check_Naming_Scheme (Check_Ada_Naming_Scheme_Validity): New name of previous procedure Check_Ada_Naming_Scheme. Change Sources_Present to Ada_Sources_Present or Other_Sources_Present throughout. * prj-part.adb (Post_Parse_Context_Clause): New Boolean parameter In_Limited. Make sure that all cycles where there is at least one "limited with" are detected. (Parse_Single_Project): New Boolean parameter In_Limited * prj-proc.adb (Recursive_Check): When Process_Languages is All_Languages, call first Prj.Nmsc.Ada_Check, then Prj.Nmsc.Other_Languages_Check. * prj-proc.adb (Process): Use Ada_Sources_Present or Other_Sources_Present (instead of Sources_Present) depending on Process_Languages. * lang-specs.h: Keep -g and -m switches in the same order, and as the last switches. * lib.adb (Switch_Storing_Enabled): New global Boolean flag (Disable_Switch_Storing): New procedure. Set Switch_Storing_Enabled to False. (Store_Compilation_Switch): Do nothing if Switch_Storing_Enabled is False. * lib.ads (Disable_Switch_Storing): New procedure. * make.adb: Modifications to reduce nesting level of this package. (Check_Standard_Library): New procedure (Gnatmake.Check_Mains): New procedure (Gnatmake.Create_Binder_Mapping_File): New procedure (Compile_Sources.Compile): Add switch -gnatez as the last option (Display): Never display -gnatez * Makefile.generic: When using $(MAIN_OBJECT), always use $(OBJ_DIR)/$(MAIN_OBJECT) * gnatcmd.adb (Check_Project): New function (Process_Link): New procedure to reduce nesting depth (Check_Files): New procedure to reduce the nesting depth. For GNAT METRIC, include the inherited sources in extending projects. (GNATCmd): When GNAT LS is invoked with a project file and no files, add the list of files from the sources of the project file. If this list is too long, put it in a temp text files and use switch -files= (Delete_Temp_Config_Files): Delete the temp text file that contains a list of source for gnatpp or gnatmetric, if one has been created. (GNATCmd): For GNAT METRIC and GNAT PRETTY, if the number of sources in the project file is too large, create a temporary text file that list them and pass it to the tool with "-files=<temp text file>". (GNATCmd): For GNAT METRIC add "-d=<abject dir>" as the first switch * gnatlink.adb (Gnatlink): Do not compile with --RTS= when the generated file is in not in Ada. * gnatls.adb: Remove all parameters And_Save that are no longer used. (Scan_Ls_Arg): Add processing for -files= (Usage): Add line for -files= * g-os_lib.adb (On_Windows): New global constant Boolean flag (Normalize_Pathname): When on Windows and the path starts with a directory separator, make sure that the resulting path will start with a drive letter. * clean.adb (Clean_Archive): New procedure (Clean_Project): When there is non-Ada code, delete the global archive, the archive dependency files, the object files and their dependency files, if they exist. (Gnatclean): Call Prj.Pars.Parse for All_Languages, not for Ada only. 2004-06-25 Thomas Quinot <quinot@act-europe.fr> * sinfo.ads: Fix typo in comment. * sem_dist.adb (Process_Remote_AST_Attribute): Simplify code that uses the TSS for remote access-to-subprogram types, since these TSS are always present once the type has been analyzed. (RAS_E_Dereference): Same. * sem_attr.adb (Analyze_Attribute): When analysis of an attribute reference raises Bad_Attribute, mark the reference as analyzed so the node (and any children resulting from rewrites that could have occurred during the analysis that ultimately failed) is not analyzed again. * exp_ch7.ads (Find_Final_List): Fix misaligned comment. * exp_dist.adb: Minor comment fix. * exp_ch4.adb (Expand_N_Allocator): For an allocator whose expected type is an anonymous access type, no unchecked deallocation of the allocated object can occur. If the object is controlled, attach it with a count of 1. This allows attachment to the Global_Final_List, if no other relevant list is available. (Get_Allocator_Final_List): For an anonymous access type that is the type of a discriminant or record component, the corresponding finalisation list is the one of the scope of the type. 2004-06-25 Ed Schonberg <schonberg@gnat.com> * sem_ch3.adb (Replace_Type): When computing the signature of an inherited subprogram, use the first subtype if the derived type declaration has no constraint. * exp_ch6.adb (Add_Call_By_Copy_Code): Check that formal is an array before applying previous optimization. Minor code cleanup. * exp_util.adb (Is_Possibly_Unaligned_Slice): If the component is placed at the beginning of an unpacked record without explicit alignment, a slice of it will be aligned and does not need a copy when used as an actual. 2004-06-25 Ed Schonberg <schonberg@gnat.com> PR ada/15591 PR ada/15592 * sem_ch8.adb (Attribute_Renaming): Reject renaming if the attribute reference is written with expressions mimicking parameters. 2004-06-25 Hristian Kirtchev <kirtchev@gnat.com> PR ada/15589 * sem_ch3.adb (Build_Derived_Record_Type): Add additional check to STEP 2a. The constraints of a full type declaration of a derived record type are checked for conformance with those declared in the corresponding private extension declaration. The message "not conformant with previous declaration" is emitted if an error is detected. 2004-06-25 Vasiliy Fofanov <fofanov@act-europe.fr> * g-traceb.ads: Document the need for -E binder switch in the spec. * g-trasym.ads: Document the need for -E binder switch in the spec. 2004-06-25 Jose Ruiz <ruiz@act-europe.fr> * sem_prag.adb: Add handling of pragma Detect_Blocking. * snames.h, snames.ads, snames.adb: Add entry for pragma Detect_Blocking. * s-rident.ads: Change reference to pragma Detect_Blocking. * targparm.ads, targparm.adb: Allow pragma Detect_Blocking in system.ads. * opt.ads (Detect_Blocking): New Boolean variable (defaulted to False) to indicate whether pragma Detect_Blocking is active. * par-prag.adb: Add entry for pragma Detect_Blocking. * rtsfind.adb (RTU_Loaded): Fix the temporary kludge to get past bug of not handling WITH. Note that this replaces the previous update which was incorrect. 2004-06-25 Javier Miranda <miranda@gnat.com> * sem_ch10.adb (Re_Install_Use_Clauses): Force the installation of the use-clauses to have a clean environment. * sem_ch8.adb (Install_Use_Clauses): Addition of a new formal to force the installation of the use-clauses to stablish a clean environment in case of compilation of a separate unit; otherwise the call to use_one_package is protected by the barrier Applicable_Use. * sem_ch8.ads (Install_Use_Clauses): Addition of a new formal to force the installation of the use-clauses to stablish a clean environment in case of compilation of a separate unit. (End_Use_Clauses): Minor comment cleanup. 2004-06-25 Sergey Rybin <rybin@act-europe.fr> * gnat_ugn.texi: Add description of the gnatpp 'files' switch From-SVN: r83658
1028 lines
30 KiB
Ada
1028 lines
30 KiB
Ada
------------------------------------------------------------------------------
|
|
-- --
|
|
-- GNAT COMPILER COMPONENTS --
|
|
-- --
|
|
-- L I B --
|
|
-- --
|
|
-- B o d y --
|
|
-- --
|
|
-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
|
|
-- --
|
|
-- GNAT is free software; you can redistribute it and/or modify it under --
|
|
-- terms of the GNU General Public License as published by the Free Soft- --
|
|
-- ware Foundation; either version 2, or (at your option) any later ver- --
|
|
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
|
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
|
|
-- for more details. You should have received a copy of the GNU General --
|
|
-- Public License distributed with GNAT; see file COPYING. If not, write --
|
|
-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
|
|
-- MA 02111-1307, USA. --
|
|
-- --
|
|
-- As a special exception, if other files instantiate generics from this --
|
|
-- unit, or you link this unit with other files to produce an executable, --
|
|
-- this unit does not by itself cause the resulting executable to be --
|
|
-- covered by the GNU General Public License. This exception does not --
|
|
-- however invalidate any other reasons why the executable file might be --
|
|
-- covered by the GNU Public License. --
|
|
-- --
|
|
-- GNAT was originally developed by the GNAT team at New York University. --
|
|
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
|
-- --
|
|
------------------------------------------------------------------------------
|
|
|
|
pragma Style_Checks (All_Checks);
|
|
-- Subprogram ordering not enforced in this unit
|
|
-- (because of some logical groupings).
|
|
|
|
with Atree; use Atree;
|
|
with Einfo; use Einfo;
|
|
with Fname; use Fname;
|
|
with Namet; use Namet;
|
|
with Namet; use Namet;
|
|
with Output; use Output;
|
|
with Sinfo; use Sinfo;
|
|
with Sinput; use Sinput;
|
|
with Stand; use Stand;
|
|
with Stringt; use Stringt;
|
|
with Tree_IO; use Tree_IO;
|
|
with Uname; use Uname;
|
|
|
|
package body Lib is
|
|
|
|
Switch_Storing_Enabled : Boolean := True;
|
|
-- Set to False by Disable_Switch_Storing
|
|
|
|
-----------------------
|
|
-- Local Subprograms --
|
|
-----------------------
|
|
|
|
type SEU_Result is (
|
|
Yes_Before, -- S1 is in same extended unit as S2 and appears before it
|
|
Yes_Same, -- S1 is in same extended unit as S2, Slocs are the same
|
|
Yes_After, -- S1 is in same extended unit as S2, and appears after it
|
|
No); -- S2 is not in same extended unit as S2
|
|
|
|
function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result;
|
|
-- Used by In_Same_Extended_Unit and Earlier_In_Extended_Unit. Returns
|
|
-- value as described above.
|
|
|
|
--------------------------------------------
|
|
-- Access Functions for Unit Table Fields --
|
|
--------------------------------------------
|
|
|
|
function Cunit (U : Unit_Number_Type) return Node_Id is
|
|
begin
|
|
return Units.Table (U).Cunit;
|
|
end Cunit;
|
|
|
|
function Cunit_Entity (U : Unit_Number_Type) return Entity_Id is
|
|
begin
|
|
return Units.Table (U).Cunit_Entity;
|
|
end Cunit_Entity;
|
|
|
|
function Dependency_Num (U : Unit_Number_Type) return Nat is
|
|
begin
|
|
return Units.Table (U).Dependency_Num;
|
|
end Dependency_Num;
|
|
|
|
function Dynamic_Elab (U : Unit_Number_Type) return Boolean is
|
|
begin
|
|
return Units.Table (U).Dynamic_Elab;
|
|
end Dynamic_Elab;
|
|
|
|
function Error_Location (U : Unit_Number_Type) return Source_Ptr is
|
|
begin
|
|
return Units.Table (U).Error_Location;
|
|
end Error_Location;
|
|
|
|
function Expected_Unit (U : Unit_Number_Type) return Unit_Name_Type is
|
|
begin
|
|
return Units.Table (U).Expected_Unit;
|
|
end Expected_Unit;
|
|
|
|
function Fatal_Error (U : Unit_Number_Type) return Boolean is
|
|
begin
|
|
return Units.Table (U).Fatal_Error;
|
|
end Fatal_Error;
|
|
|
|
function Generate_Code (U : Unit_Number_Type) return Boolean is
|
|
begin
|
|
return Units.Table (U).Generate_Code;
|
|
end Generate_Code;
|
|
|
|
function Has_RACW (U : Unit_Number_Type) return Boolean is
|
|
begin
|
|
return Units.Table (U).Has_RACW;
|
|
end Has_RACW;
|
|
|
|
function Ident_String (U : Unit_Number_Type) return Node_Id is
|
|
begin
|
|
return Units.Table (U).Ident_String;
|
|
end Ident_String;
|
|
|
|
function Loading (U : Unit_Number_Type) return Boolean is
|
|
begin
|
|
return Units.Table (U).Loading;
|
|
end Loading;
|
|
|
|
function Main_Priority (U : Unit_Number_Type) return Int is
|
|
begin
|
|
return Units.Table (U).Main_Priority;
|
|
end Main_Priority;
|
|
|
|
function Munit_Index (U : Unit_Number_Type) return Nat is
|
|
begin
|
|
return Units.Table (U).Munit_Index;
|
|
end Munit_Index;
|
|
|
|
function Source_Index (U : Unit_Number_Type) return Source_File_Index is
|
|
begin
|
|
return Units.Table (U).Source_Index;
|
|
end Source_Index;
|
|
|
|
function Unit_File_Name (U : Unit_Number_Type) return File_Name_Type is
|
|
begin
|
|
return Units.Table (U).Unit_File_Name;
|
|
end Unit_File_Name;
|
|
|
|
function Unit_Name (U : Unit_Number_Type) return Unit_Name_Type is
|
|
begin
|
|
return Units.Table (U).Unit_Name;
|
|
end Unit_Name;
|
|
|
|
------------------------------------------
|
|
-- Subprograms to Set Unit Table Fields --
|
|
------------------------------------------
|
|
|
|
procedure Set_Cunit (U : Unit_Number_Type; N : Node_Id) is
|
|
begin
|
|
Units.Table (U).Cunit := N;
|
|
end Set_Cunit;
|
|
|
|
procedure Set_Cunit_Entity (U : Unit_Number_Type; E : Entity_Id) is
|
|
begin
|
|
Units.Table (U).Cunit_Entity := E;
|
|
Set_Is_Compilation_Unit (E);
|
|
end Set_Cunit_Entity;
|
|
|
|
procedure Set_Dynamic_Elab (U : Unit_Number_Type; B : Boolean := True) is
|
|
begin
|
|
Units.Table (U).Dynamic_Elab := B;
|
|
end Set_Dynamic_Elab;
|
|
|
|
procedure Set_Error_Location (U : Unit_Number_Type; W : Source_Ptr) is
|
|
begin
|
|
Units.Table (U).Error_Location := W;
|
|
end Set_Error_Location;
|
|
|
|
procedure Set_Fatal_Error (U : Unit_Number_Type; B : Boolean := True) is
|
|
begin
|
|
Units.Table (U).Fatal_Error := B;
|
|
end Set_Fatal_Error;
|
|
|
|
procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True) is
|
|
begin
|
|
Units.Table (U).Generate_Code := B;
|
|
end Set_Generate_Code;
|
|
|
|
procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True) is
|
|
begin
|
|
Units.Table (U).Has_RACW := B;
|
|
end Set_Has_RACW;
|
|
|
|
procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id) is
|
|
begin
|
|
Units.Table (U).Ident_String := N;
|
|
end Set_Ident_String;
|
|
|
|
procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True) is
|
|
begin
|
|
Units.Table (U).Loading := B;
|
|
end Set_Loading;
|
|
|
|
procedure Set_Main_Priority (U : Unit_Number_Type; P : Int) is
|
|
begin
|
|
Units.Table (U).Main_Priority := P;
|
|
end Set_Main_Priority;
|
|
|
|
procedure Set_Unit_Name (U : Unit_Number_Type; N : Unit_Name_Type) is
|
|
begin
|
|
Units.Table (U).Unit_Name := N;
|
|
end Set_Unit_Name;
|
|
|
|
------------------------------
|
|
-- Check_Same_Extended_Unit --
|
|
------------------------------
|
|
|
|
function Check_Same_Extended_Unit (S1, S2 : Source_Ptr) return SEU_Result is
|
|
Sloc1 : Source_Ptr;
|
|
Sloc2 : Source_Ptr;
|
|
Sind1 : Source_File_Index;
|
|
Sind2 : Source_File_Index;
|
|
Inst1 : Source_Ptr;
|
|
Inst2 : Source_Ptr;
|
|
Unum1 : Unit_Number_Type;
|
|
Unum2 : Unit_Number_Type;
|
|
Unit1 : Node_Id;
|
|
Unit2 : Node_Id;
|
|
Depth1 : Nat;
|
|
Depth2 : Nat;
|
|
|
|
begin
|
|
if S1 = No_Location or else S2 = No_Location then
|
|
return No;
|
|
|
|
elsif S1 = Standard_Location then
|
|
if S2 = Standard_Location then
|
|
return Yes_Same;
|
|
else
|
|
return No;
|
|
end if;
|
|
|
|
elsif S2 = Standard_Location then
|
|
return No;
|
|
end if;
|
|
|
|
Sloc1 := S1;
|
|
Sloc2 := S2;
|
|
Unum1 := Get_Code_Unit (Sloc1);
|
|
Unum2 := Get_Code_Unit (Sloc2);
|
|
|
|
loop
|
|
Sind1 := Get_Source_File_Index (Sloc1);
|
|
Sind2 := Get_Source_File_Index (Sloc2);
|
|
|
|
if Sind1 = Sind2 then
|
|
if Sloc1 < Sloc2 then
|
|
return Yes_Before;
|
|
elsif Sloc1 > Sloc2 then
|
|
return Yes_After;
|
|
else
|
|
return Yes_Same;
|
|
end if;
|
|
end if;
|
|
|
|
-- OK, the two nodes are in separate source elements, but this is not
|
|
-- decisive, because of the issue of subunits and instantiations.
|
|
|
|
-- First we deal with subunits, since if the subunit is in an
|
|
-- instantiation, we know that the parent is in the corresponding
|
|
-- instantiation, since that is the only way we can have a subunit
|
|
-- that is part of an instantiation.
|
|
|
|
Unit1 := Unit (Cunit (Unum1));
|
|
Unit2 := Unit (Cunit (Unum2));
|
|
|
|
if Nkind (Unit1) = N_Subunit
|
|
and then Present (Corresponding_Stub (Unit1))
|
|
then
|
|
-- Both in subunits. They could have a common ancestor. If they
|
|
-- do, then the deeper one must have a longer unit name. Replace
|
|
-- the deeper one with its corresponding stub, in order to find
|
|
-- nearest common ancestor, if any.
|
|
|
|
if Nkind (Unit2) = N_Subunit
|
|
and then Present (Corresponding_Stub (Unit2))
|
|
then
|
|
if Length_Of_Name (Unit_Name (Unum1)) <
|
|
Length_Of_Name (Unit_Name (Unum2))
|
|
then
|
|
Sloc2 := Sloc (Corresponding_Stub (Unit2));
|
|
Unum2 := Get_Source_Unit (Sloc2);
|
|
goto Continue;
|
|
|
|
else
|
|
Sloc1 := Sloc (Corresponding_Stub (Unit1));
|
|
Unum1 := Get_Source_Unit (Sloc1);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- Nod1 in subunit, Nod2 not
|
|
|
|
else
|
|
Sloc1 := Sloc (Corresponding_Stub (Unit1));
|
|
Unum1 := Get_Source_Unit (Sloc1);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- Nod2 in subunit, Nod1 not
|
|
|
|
elsif Nkind (Unit2) = N_Subunit
|
|
and then Present (Corresponding_Stub (Unit2))
|
|
then
|
|
Sloc2 := Sloc (Corresponding_Stub (Unit2));
|
|
Unum2 := Get_Source_Unit (Sloc2);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- At this stage we know that neither is a subunit, so we deal
|
|
-- with instantiations, since we culd have a common ancestor
|
|
|
|
Inst1 := Instantiation (Sind1);
|
|
Inst2 := Instantiation (Sind2);
|
|
|
|
if Inst1 /= No_Location then
|
|
|
|
-- Both are instantiations
|
|
|
|
if Inst2 /= No_Location then
|
|
|
|
Depth1 := Instantiation_Depth (Sloc1);
|
|
Depth2 := Instantiation_Depth (Sloc2);
|
|
|
|
if Depth1 < Depth2 then
|
|
Sloc2 := Inst2;
|
|
Unum2 := Get_Source_Unit (Sloc2);
|
|
goto Continue;
|
|
|
|
elsif Depth1 > Depth2 then
|
|
Sloc1 := Inst1;
|
|
Unum1 := Get_Source_Unit (Sloc1);
|
|
goto Continue;
|
|
|
|
else
|
|
Sloc1 := Inst1;
|
|
Sloc2 := Inst2;
|
|
Unum1 := Get_Source_Unit (Sloc1);
|
|
Unum2 := Get_Source_Unit (Sloc2);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- Only first node is in instantiation
|
|
|
|
else
|
|
Sloc1 := Inst1;
|
|
Unum1 := Get_Source_Unit (Sloc1);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- Only second node is instantiation
|
|
|
|
elsif Inst2 /= No_Location then
|
|
Sloc2 := Inst2;
|
|
Unum2 := Get_Source_Unit (Sloc2);
|
|
goto Continue;
|
|
end if;
|
|
|
|
-- No instantiations involved, so we are not in the same unit
|
|
-- However, there is one case still to check, namely the case
|
|
-- where one location is in the spec, and the other in the
|
|
-- corresponding body (the spec location is earlier).
|
|
|
|
if Nkind (Unit1) = N_Subprogram_Body
|
|
or else
|
|
Nkind (Unit1) = N_Package_Body
|
|
then
|
|
if Library_Unit (Cunit (Unum1)) = Cunit (Unum2) then
|
|
return Yes_After;
|
|
end if;
|
|
|
|
elsif Nkind (Unit2) = N_Subprogram_Body
|
|
or else
|
|
Nkind (Unit2) = N_Package_Body
|
|
then
|
|
if Library_Unit (Cunit (Unum2)) = Cunit (Unum1) then
|
|
return Yes_Before;
|
|
end if;
|
|
end if;
|
|
|
|
-- If that special case does not occur, then we are certain that
|
|
-- the two locations are really in separate units.
|
|
|
|
return No;
|
|
|
|
<<Continue>>
|
|
null;
|
|
end loop;
|
|
end Check_Same_Extended_Unit;
|
|
|
|
-------------------------------
|
|
-- Compilation_Switches_Last --
|
|
-------------------------------
|
|
|
|
function Compilation_Switches_Last return Nat is
|
|
begin
|
|
return Compilation_Switches.Last;
|
|
end Compilation_Switches_Last;
|
|
|
|
procedure Disable_Switch_Storing is
|
|
begin
|
|
Switch_Storing_Enabled := False;
|
|
end Disable_Switch_Storing;
|
|
|
|
------------------------------
|
|
-- Earlier_In_Extended_Unit --
|
|
------------------------------
|
|
|
|
function Earlier_In_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
|
|
begin
|
|
return Check_Same_Extended_Unit (S1, S2) = Yes_Before;
|
|
end Earlier_In_Extended_Unit;
|
|
|
|
----------------------------
|
|
-- Entity_Is_In_Main_Unit --
|
|
----------------------------
|
|
|
|
function Entity_Is_In_Main_Unit (E : Entity_Id) return Boolean is
|
|
S : Entity_Id;
|
|
|
|
begin
|
|
S := Scope (E);
|
|
|
|
while S /= Standard_Standard loop
|
|
if S = Main_Unit_Entity then
|
|
return True;
|
|
elsif Ekind (S) = E_Package and then Is_Child_Unit (S) then
|
|
return False;
|
|
else
|
|
S := Scope (S);
|
|
end if;
|
|
end loop;
|
|
|
|
return False;
|
|
end Entity_Is_In_Main_Unit;
|
|
|
|
---------------------------------
|
|
-- Generic_Separately_Compiled --
|
|
---------------------------------
|
|
|
|
function Generic_Separately_Compiled (E : Entity_Id) return Boolean is
|
|
begin
|
|
-- We do not generate object files for internal generics, because
|
|
-- the only thing they would contain is the elaboration boolean, and
|
|
-- we are careful to elaborate all predefined units first anyway, so
|
|
-- this boolean is not needed.
|
|
|
|
if Is_Internal_File_Name
|
|
(Fname => Unit_File_Name (Get_Source_Unit (E)),
|
|
Renamings_Included => True)
|
|
then
|
|
return False;
|
|
|
|
-- All other generic units do generate object files
|
|
|
|
else
|
|
return True;
|
|
end if;
|
|
end Generic_Separately_Compiled;
|
|
|
|
function Generic_Separately_Compiled
|
|
(Sfile : File_Name_Type) return Boolean
|
|
is
|
|
begin
|
|
-- Exactly the same as previous function, but works directly on a file
|
|
-- name.
|
|
|
|
if Is_Internal_File_Name
|
|
(Fname => Sfile,
|
|
Renamings_Included => True)
|
|
then
|
|
return False;
|
|
|
|
-- All other generic units do generate object files
|
|
|
|
else
|
|
return True;
|
|
end if;
|
|
end Generic_Separately_Compiled;
|
|
|
|
-------------------
|
|
-- Get_Code_Unit --
|
|
-------------------
|
|
|
|
function Get_Code_Unit (S : Source_Ptr) return Unit_Number_Type is
|
|
begin
|
|
-- Search table unless we have No_Location, which can happen if the
|
|
-- relevant location has not been set yet. Happens for example when
|
|
-- we obtain Sloc (Cunit (Main_Unit)) before it is set.
|
|
|
|
if S /= No_Location then
|
|
declare
|
|
Source_File : constant Source_File_Index :=
|
|
Get_Source_File_Index (Top_Level_Location (S));
|
|
|
|
begin
|
|
for U in Units.First .. Units.Last loop
|
|
if Source_Index (U) = Source_File then
|
|
return U;
|
|
end if;
|
|
end loop;
|
|
end;
|
|
end if;
|
|
|
|
-- If S was No_Location, or was not in the table, we must be in the
|
|
-- main source unit (and the value has not been placed in the table yet)
|
|
|
|
return Main_Unit;
|
|
end Get_Code_Unit;
|
|
|
|
function Get_Code_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
|
|
begin
|
|
return Get_Code_Unit (Sloc (N));
|
|
end Get_Code_Unit;
|
|
|
|
----------------------------
|
|
-- Get_Compilation_Switch --
|
|
----------------------------
|
|
|
|
function Get_Compilation_Switch (N : Pos) return String_Ptr is
|
|
begin
|
|
if N <= Compilation_Switches.Last then
|
|
return Compilation_Switches.Table (N);
|
|
|
|
else
|
|
return null;
|
|
end if;
|
|
end Get_Compilation_Switch;
|
|
|
|
----------------------------------
|
|
-- Get_Cunit_Entity_Unit_Number --
|
|
----------------------------------
|
|
|
|
function Get_Cunit_Entity_Unit_Number
|
|
(E : Entity_Id) return Unit_Number_Type
|
|
is
|
|
begin
|
|
for U in Units.First .. Units.Last loop
|
|
if Cunit_Entity (U) = E then
|
|
return U;
|
|
end if;
|
|
end loop;
|
|
|
|
-- If not in the table, must be the main source unit, and we just
|
|
-- have not got it put into the table yet.
|
|
|
|
return Main_Unit;
|
|
end Get_Cunit_Entity_Unit_Number;
|
|
|
|
---------------------------
|
|
-- Get_Cunit_Unit_Number --
|
|
---------------------------
|
|
|
|
function Get_Cunit_Unit_Number (N : Node_Id) return Unit_Number_Type is
|
|
begin
|
|
for U in Units.First .. Units.Last loop
|
|
if Cunit (U) = N then
|
|
return U;
|
|
end if;
|
|
end loop;
|
|
|
|
-- If not in the table, must be the main source unit, and we just
|
|
-- have not got it put into the table yet.
|
|
|
|
return Main_Unit;
|
|
end Get_Cunit_Unit_Number;
|
|
|
|
---------------------
|
|
-- Get_Source_Unit --
|
|
---------------------
|
|
|
|
function Get_Source_Unit (S : Source_Ptr) return Unit_Number_Type is
|
|
begin
|
|
-- Search table unless we have No_Location, which can happen if the
|
|
-- relevant location has not been set yet. Happens for example when
|
|
-- we obtain Sloc (Cunit (Main_Unit)) before it is set.
|
|
|
|
if S /= No_Location then
|
|
declare
|
|
Source_File : Source_File_Index :=
|
|
Get_Source_File_Index (Top_Level_Location (S));
|
|
|
|
begin
|
|
Source_File := Get_Source_File_Index (S);
|
|
while Template (Source_File) /= No_Source_File loop
|
|
Source_File := Template (Source_File);
|
|
end loop;
|
|
|
|
for U in Units.First .. Units.Last loop
|
|
if Source_Index (U) = Source_File then
|
|
return U;
|
|
end if;
|
|
end loop;
|
|
end;
|
|
end if;
|
|
|
|
-- If S was No_Location, or was not in the table, we must be in the
|
|
-- main source unit (and the value has not got put into the table yet)
|
|
|
|
return Main_Unit;
|
|
end Get_Source_Unit;
|
|
|
|
function Get_Source_Unit (N : Node_Or_Entity_Id) return Unit_Number_Type is
|
|
begin
|
|
return Get_Source_Unit (Sloc (N));
|
|
end Get_Source_Unit;
|
|
|
|
--------------------------------
|
|
-- In_Extended_Main_Code_Unit --
|
|
--------------------------------
|
|
|
|
function In_Extended_Main_Code_Unit
|
|
(N : Node_Or_Entity_Id) return Boolean
|
|
is
|
|
begin
|
|
if Sloc (N) = Standard_Location then
|
|
return True;
|
|
|
|
elsif Sloc (N) = No_Location then
|
|
return False;
|
|
|
|
-- Special case Itypes to test the Sloc of the associated node. The
|
|
-- reason we do this is for possible calls from gigi after -gnatD
|
|
-- processing is complete in sprint. This processing updates the
|
|
-- sloc fields of all nodes in the tree, but itypes are not in the
|
|
-- tree so their slocs do not get updated.
|
|
|
|
elsif Nkind (N) = N_Defining_Identifier
|
|
and then Is_Itype (N)
|
|
then
|
|
return In_Extended_Main_Code_Unit (Associated_Node_For_Itype (N));
|
|
|
|
-- Otherwise see if we are in the main unit
|
|
|
|
elsif Get_Code_Unit (Sloc (N)) = Get_Code_Unit (Cunit (Main_Unit)) then
|
|
return True;
|
|
|
|
-- Node may be in spec (or subunit etc) of main unit
|
|
|
|
else
|
|
return
|
|
In_Same_Extended_Unit (N, Cunit (Main_Unit));
|
|
end if;
|
|
end In_Extended_Main_Code_Unit;
|
|
|
|
function In_Extended_Main_Code_Unit (Loc : Source_Ptr) return Boolean is
|
|
begin
|
|
if Loc = Standard_Location then
|
|
return True;
|
|
|
|
elsif Loc = No_Location then
|
|
return False;
|
|
|
|
-- Otherwise see if we are in the main unit
|
|
|
|
elsif Get_Code_Unit (Loc) = Get_Code_Unit (Cunit (Main_Unit)) then
|
|
return True;
|
|
|
|
-- Location may be in spec (or subunit etc) of main unit
|
|
|
|
else
|
|
return
|
|
In_Same_Extended_Unit (Loc, Sloc (Cunit (Main_Unit)));
|
|
end if;
|
|
end In_Extended_Main_Code_Unit;
|
|
|
|
----------------------------------
|
|
-- In_Extended_Main_Source_Unit --
|
|
----------------------------------
|
|
|
|
function In_Extended_Main_Source_Unit
|
|
(N : Node_Or_Entity_Id) return Boolean
|
|
is
|
|
Nloc : constant Source_Ptr := Sloc (N);
|
|
Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));
|
|
|
|
begin
|
|
-- If Mloc is not set, it means we are still parsing the main unit,
|
|
-- so everything so far is in the extended main source unit.
|
|
|
|
if Mloc = No_Location then
|
|
return True;
|
|
|
|
-- Special value cases
|
|
|
|
elsif Nloc = Standard_Location then
|
|
return True;
|
|
|
|
elsif Nloc = No_Location then
|
|
return False;
|
|
|
|
-- Special case Itypes to test the Sloc of the associated node. The
|
|
-- reason we do this is for possible calls from gigi after -gnatD
|
|
-- processing is complete in sprint. This processing updates the
|
|
-- sloc fields of all nodes in the tree, but itypes are not in the
|
|
-- tree so their slocs do not get updated.
|
|
|
|
elsif Nkind (N) = N_Defining_Identifier
|
|
and then Is_Itype (N)
|
|
then
|
|
return In_Extended_Main_Source_Unit (Associated_Node_For_Itype (N));
|
|
|
|
-- Otherwise compare original locations to see if in same unit
|
|
|
|
else
|
|
return
|
|
In_Same_Extended_Unit
|
|
(Original_Location (Nloc), Original_Location (Mloc));
|
|
end if;
|
|
end In_Extended_Main_Source_Unit;
|
|
|
|
function In_Extended_Main_Source_Unit
|
|
(Loc : Source_Ptr) return Boolean
|
|
is
|
|
Mloc : constant Source_Ptr := Sloc (Cunit (Main_Unit));
|
|
|
|
begin
|
|
-- If Mloc is not set, it means we are still parsing the main unit,
|
|
-- so everything so far is in the extended main source unit.
|
|
|
|
if Mloc = No_Location then
|
|
return True;
|
|
|
|
-- Special value cases
|
|
|
|
elsif Loc = Standard_Location then
|
|
return True;
|
|
|
|
elsif Loc = No_Location then
|
|
return False;
|
|
|
|
-- Otherwise compare original locations to see if in same unit
|
|
|
|
else
|
|
return
|
|
In_Same_Extended_Unit
|
|
(Original_Location (Loc), Original_Location (Mloc));
|
|
end if;
|
|
end In_Extended_Main_Source_Unit;
|
|
|
|
-----------------------
|
|
-- In_Same_Code_Unit --
|
|
-----------------------
|
|
|
|
function In_Same_Code_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
|
|
S1 : constant Source_Ptr := Sloc (N1);
|
|
S2 : constant Source_Ptr := Sloc (N2);
|
|
|
|
begin
|
|
if S1 = No_Location or else S2 = No_Location then
|
|
return False;
|
|
|
|
elsif S1 = Standard_Location then
|
|
return S2 = Standard_Location;
|
|
|
|
elsif S2 = Standard_Location then
|
|
return False;
|
|
end if;
|
|
|
|
return Get_Code_Unit (N1) = Get_Code_Unit (N2);
|
|
end In_Same_Code_Unit;
|
|
|
|
---------------------------
|
|
-- In_Same_Extended_Unit --
|
|
---------------------------
|
|
|
|
function In_Same_Extended_Unit
|
|
(N1, N2 : Node_Or_Entity_Id) return Boolean
|
|
is
|
|
begin
|
|
return Check_Same_Extended_Unit (Sloc (N1), Sloc (N2)) /= No;
|
|
end In_Same_Extended_Unit;
|
|
|
|
function In_Same_Extended_Unit (S1, S2 : Source_Ptr) return Boolean is
|
|
begin
|
|
return Check_Same_Extended_Unit (S1, S2) /= No;
|
|
end In_Same_Extended_Unit;
|
|
|
|
-------------------------
|
|
-- In_Same_Source_Unit --
|
|
-------------------------
|
|
|
|
function In_Same_Source_Unit (N1, N2 : Node_Or_Entity_Id) return Boolean is
|
|
S1 : constant Source_Ptr := Sloc (N1);
|
|
S2 : constant Source_Ptr := Sloc (N2);
|
|
|
|
begin
|
|
if S1 = No_Location or else S2 = No_Location then
|
|
return False;
|
|
|
|
elsif S1 = Standard_Location then
|
|
return S2 = Standard_Location;
|
|
|
|
elsif S2 = Standard_Location then
|
|
return False;
|
|
end if;
|
|
|
|
return Get_Source_Unit (N1) = Get_Source_Unit (N2);
|
|
end In_Same_Source_Unit;
|
|
|
|
-----------------------------
|
|
-- Increment_Serial_Number --
|
|
-----------------------------
|
|
|
|
function Increment_Serial_Number return Nat is
|
|
TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
|
|
begin
|
|
TSN := TSN + 1;
|
|
return TSN;
|
|
end Increment_Serial_Number;
|
|
|
|
----------------
|
|
-- Initialize --
|
|
----------------
|
|
|
|
procedure Initialize is
|
|
begin
|
|
Linker_Option_Lines.Init;
|
|
Load_Stack.Init;
|
|
Units.Init;
|
|
Unit_Exception_Table_Present := False;
|
|
Compilation_Switches.Init;
|
|
end Initialize;
|
|
|
|
---------------
|
|
-- Is_Loaded --
|
|
---------------
|
|
|
|
function Is_Loaded (Uname : Unit_Name_Type) return Boolean is
|
|
begin
|
|
for Unum in Units.First .. Units.Last loop
|
|
if Uname = Unit_Name (Unum) then
|
|
return True;
|
|
end if;
|
|
end loop;
|
|
|
|
return False;
|
|
end Is_Loaded;
|
|
|
|
---------------
|
|
-- Last_Unit --
|
|
---------------
|
|
|
|
function Last_Unit return Unit_Number_Type is
|
|
begin
|
|
return Units.Last;
|
|
end Last_Unit;
|
|
|
|
----------
|
|
-- List --
|
|
----------
|
|
|
|
procedure List (File_Names_Only : Boolean := False) is separate;
|
|
|
|
----------
|
|
-- Lock --
|
|
----------
|
|
|
|
procedure Lock is
|
|
begin
|
|
Linker_Option_Lines.Locked := True;
|
|
Load_Stack.Locked := True;
|
|
Units.Locked := True;
|
|
Linker_Option_Lines.Release;
|
|
Load_Stack.Release;
|
|
Units.Release;
|
|
end Lock;
|
|
|
|
---------------
|
|
-- Num_Units --
|
|
---------------
|
|
|
|
function Num_Units return Nat is
|
|
begin
|
|
return Int (Units.Last) - Int (Main_Unit) + 1;
|
|
end Num_Units;
|
|
|
|
-----------------
|
|
-- Remove_Unit --
|
|
-----------------
|
|
|
|
procedure Remove_Unit (U : Unit_Number_Type) is
|
|
begin
|
|
if U = Units.Last then
|
|
Units.Decrement_Last;
|
|
end if;
|
|
end Remove_Unit;
|
|
|
|
----------------------------------
|
|
-- Replace_Linker_Option_String --
|
|
----------------------------------
|
|
|
|
procedure Replace_Linker_Option_String
|
|
(S : String_Id; Match_String : String)
|
|
is
|
|
begin
|
|
if Match_String'Length > 0 then
|
|
for J in 1 .. Linker_Option_Lines.Last loop
|
|
String_To_Name_Buffer (Linker_Option_Lines.Table (J).Option);
|
|
|
|
if Match_String = Name_Buffer (1 .. Match_String'Length) then
|
|
Linker_Option_Lines.Table (J).Option := S;
|
|
return;
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
|
|
Store_Linker_Option_String (S);
|
|
end Replace_Linker_Option_String;
|
|
|
|
----------
|
|
-- Sort --
|
|
----------
|
|
|
|
procedure Sort (Tbl : in out Unit_Ref_Table) is separate;
|
|
|
|
------------------------------
|
|
-- Store_Compilation_Switch --
|
|
------------------------------
|
|
|
|
procedure Store_Compilation_Switch (Switch : String) is
|
|
begin
|
|
if Switch_Storing_Enabled then
|
|
Compilation_Switches.Increment_Last;
|
|
Compilation_Switches.Table (Compilation_Switches.Last) :=
|
|
new String'(Switch);
|
|
|
|
-- Fix up --RTS flag which has been transformed by the gcc driver
|
|
-- into -fRTS
|
|
|
|
if Switch'Last >= Switch'First + 4
|
|
and then Switch (Switch'First .. Switch'First + 4) = "-fRTS"
|
|
then
|
|
Compilation_Switches.Table
|
|
(Compilation_Switches.Last) (Switch'First + 1) := '-';
|
|
end if;
|
|
end if;
|
|
end Store_Compilation_Switch;
|
|
|
|
--------------------------------
|
|
-- Store_Linker_Option_String --
|
|
--------------------------------
|
|
|
|
procedure Store_Linker_Option_String (S : String_Id) is
|
|
begin
|
|
Linker_Option_Lines.Increment_Last;
|
|
Linker_Option_Lines.Table (Linker_Option_Lines.Last) :=
|
|
(Option => S, Unit => Current_Sem_Unit);
|
|
end Store_Linker_Option_String;
|
|
|
|
-------------------------------
|
|
-- Synchronize_Serial_Number --
|
|
-------------------------------
|
|
|
|
procedure Synchronize_Serial_Number is
|
|
TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
|
|
begin
|
|
TSN := TSN + 1;
|
|
end Synchronize_Serial_Number;
|
|
|
|
---------------
|
|
-- Tree_Read --
|
|
---------------
|
|
|
|
procedure Tree_Read is
|
|
N : Nat;
|
|
S : String_Ptr;
|
|
|
|
begin
|
|
Units.Tree_Read;
|
|
|
|
-- Read Compilation_Switches table
|
|
|
|
Tree_Read_Int (N);
|
|
Compilation_Switches.Set_Last (N);
|
|
|
|
for J in 1 .. N loop
|
|
Tree_Read_Str (S);
|
|
Compilation_Switches.Table (J) := S;
|
|
end loop;
|
|
end Tree_Read;
|
|
|
|
----------------
|
|
-- Tree_Write --
|
|
----------------
|
|
|
|
procedure Tree_Write is
|
|
begin
|
|
Units.Tree_Write;
|
|
|
|
-- Write Compilation_Switches table
|
|
|
|
Tree_Write_Int (Compilation_Switches.Last);
|
|
|
|
for J in 1 .. Compilation_Switches.Last loop
|
|
Tree_Write_Str (Compilation_Switches.Table (J));
|
|
end loop;
|
|
end Tree_Write;
|
|
|
|
-----------------
|
|
-- Version_Get --
|
|
-----------------
|
|
|
|
function Version_Get (U : Unit_Number_Type) return Word_Hex_String is
|
|
begin
|
|
return Get_Hex_String (Units.Table (U).Version);
|
|
end Version_Get;
|
|
|
|
------------------------
|
|
-- Version_Referenced --
|
|
------------------------
|
|
|
|
procedure Version_Referenced (S : String_Id) is
|
|
begin
|
|
Version_Ref.Append (S);
|
|
end Version_Referenced;
|
|
|
|
end Lib;
|