2004-06-07 Robert Dewar <dewar@gnat.com> * a-direct.ads, einfo.ads: Minor comment updates * s-taprop-lynxos.adb, s-taprop-tru64.adb, s-taprop-irix.adb, s-taprop-irix-athread.adb, s-taprop-hpux-dce.adb, s-taprop-linux.adb, s-taprop-dummy.adb, s-taprop-os2.adb, s-taprop-solaris.adb, s-taprop-vms.adb, s-taprop-mingw.adb, s-taprop-vxworks.adb, s-taprop-posix.adb, s-taprop.ads, exp_dbug.adb: Minor reformatting. * s-interr-sigaction.adb: Remove unreferenced variable (Attached_Interrupts). Minor reformatting. Avoid use of variable I (replace by J). * par-ch10.adb: Fix text of one error message * checks.adb, checks.ads, cstand.adb, vms_data.ads, errout.ads, exp_aggr.adb, exp_ch3.adb, exp_ch3.ads, exp_ch5.adb, exp_ch6.adb, exp_ch9.adb, exp_code.adb, gnat1drv.adb, lib-load.adb, lib-writ.adb, opt.adb, par.adb, opt.ads, par-ch11.adb, par-ch3.adb, par-ch4.adb, par-ch5.adb, par-ch6.adb, par-ch8.adb, par-ch9.adb, par-prag.adb, par-util.adb, scng.adb, sem_aggr.adb, sem_attr.adb, sem_cat.adb, sem_ch10.adb, sem_ch10.adb, sem_ch11.adb, sem_ch12.adb, sem_ch2.adb, sem_ch3.adb, sem_ch3.ads, sem_ch4.adb, sem_ch5.adb, sem_ch6.adb, sem_ch7.adb, sem_ch8.adb, sem_ch9.adb, sem_eval.adb, sem_prag.adb, sem_res.adb, sem_type.adb, sem_util.adb, sinfo.ads, snames.adb, snames.ads, snames.h, sprint.adb, switch-c.adb: Modifications for Ada 2005 support. 2004-06-07 Doug Rupp <rupp@gnat.com> * mlib-tgt-vms.adb: Rename mlib-tgt-vms.adb mlib-tgt-vms-alpha.adb * s-vaflop-vms.adb: Rename s-vaflop-vms.adb to s-vaflop-vms-alpha.adb * mlib-tgt-vms-ia64.adb: New file. * Makefile.in: Rename mlib-tgt-vms.adb to mlib-tgt-vms-alpha.adb Add mlib-tgt-vms-ia64.adb Rename s-vaflop-vms.adb to s-vaflop-vms-alpha.adb. Move to alpha specific ifeq section. Add VMS specific versions of symbols.adb Renaming of 5q vms files. * 5qsystem.ads renamed to system-vms_64.ads. 2004-06-07 Vincent Celier <celier@gnat.com> * a-calend.ads: Add a GNAT Note comment after function Time_Of to explain that when a time of day corresponding to the non existing hour on the day switching to DST is specified, Split may return a different value for Seconds. * gnatcmd.adb: Add processing of GNAT METRIC (for gnatmetric), similar to GNAT PRETTY. * g-os_lib.adb (OpenVMS): New Boolean value imported from System. (Normalize_Pathname): Only resolve VMS logical names when on VMS. * mlib-prj.adb (Build_Library): New flag Gtrasymobj_Needed, initialize to False. If Gtrasymobj_Needed is True, add the full path of g-trasym.obj to the linking options. (Build_Library.Check_Libs): On VMS, if there is a dependency on g-trasym.ads, set Gtrasymobj_Needed to True. * prj-attr.adb: Add new package Metrics for gnatmetric * prj-nmsc.adb (Record_Other_Sources): Put source file names in canonical case to take into account files with upper case characters on Windows. (Ada_Check): Load the reference symbol file name in the name buffer to check it, not the symbol file name. * snames.ads, snames.adb: Add standard name Metrics (name of project file package for gnatmetric). * vms_conv.ads: Add Metric to Comment_Type * vms_conv.adb (Initialize): Add component dor Metric in Command_List * vms_data.ads: Add qualifiers for GNAT METRIC * makegpr.adb (Link_Executables): Take into account the switches specified in package Linker of the main project. 2004-06-07 Thomas Quinot <quinot@act-europe.fr> * bindgen.adb (Set_Unit_Number): Units is an instance of Table, and so the index of the last element is Units.Last, not Units.Table'Last (which is usually not a valid index within the actually allocated storage for the table). * exp_ch4.adb (Insert_Dereference_Action): Change predicate that determines whether to generate a call to a checked storage pool Dereference action. Generate such a call only for a dereference that either comes from source, or is the result of rewriting a dereference that comes from source. 2004-06-07 Romain Berrendonner <berrendo@act-europe.fr> * bindgen.adb (Gen_Output_File): Add support for GAP builds. 2004-06-07 Eric Botcazou <ebotcazou@act-europe.fr> (gnat_to_gnu_entity) <E_Array_Subtype>: For multi-dimensional arrays at file level, elaborate the stride for inner dimensions in alignment units, not bytes. * exp_ch5.adb: Correct wrong reference to Component_May_Be_Bit_Aligned in a comment. 2004-06-07 Javier Miranda <miranda@gnat.com> * exp_ch6.adb: Correct wrong modification in previous patch 2004-06-07 Vasiliy Fofanov <fofanov@act-europe.fr> * g-trasym.ads: Corrected comment to properly reflect level of support on VMS. 2004-06-07 Hristian Kirtchev <kirtchev@gnat.com> * lib-xref.adb (Generate_Reference): Add nested function Is_On_LHS. It includes case of a variable referenced on the left hand side of an assignment, therefore remove redundant code. Variables and prefixes of indexed or selected components are now marked as referenced on left hand side. Warnings are now properly emitted when variables or prefixes are assigned but not read. * sem_warn.adb (Output_Unreferenced_Messages): Add additional checks to left hand side referenced variables. Private access types do not produce the warning "variable ... is assigned but never read". Add also additional checks to left hand side referenced variables. Aliased, renamed objects and access types do not produce the warning "variable ... is assigned but never read" since other entities may read the memory location. 2004-06-07 Jerome Guitton <guitton@act-europe.fr> * Makefile.in: In the powerpc/vxworks-specific section, restore EXTRA_GNATRTL_NONTASKING_OBJS and EXTRA_GNATRTL_TASKING_OBJS (removed by mistake). 2004-06-07 Ed Schonberg <schonberg@gnat.com> * sem_ch4.adb (Remove_Abstract_Operations): Refine the removal of predefined operators. Removes spurious type errors from g-trasym-vms.adb. * sem_res.adb (Rewrite_Renamed_Operator): If intrinsic operator is distinct from the operator appearing in the source, call appropriate routine to insert conversions when needed, and complete resolution of node. (Resolve_Intrinsic_Operator): Fix cut-and-paste bug on transfer of interpretations for rewritten right operand. (Set_Mixed_Mode_Operand): Handle properly a universal real operand when the other operand is overloaded and the context is a type conversion. 2004-06-07 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> * ada-tree.def (BLOCK_STMT): Now has two operands. (BREAK_STMT): New. * ada-tree.h: (BLOCK_STMT_BLOCK): New macro. * gigi.h: (gnat_poplevel): Now returns a tree. * trans.c (end_block_stmt): Add arg; all callers changed. (tree_transform, case N_Case_Statement): Make a BLOCK_STMT for a WHEN. (start_block_stmt): Clear BLOCK_STMT_BLOCK. (add_stmt): Set TREE_TYPE. (gnat_expand_stmt, case BLOCK_STMT): Handle BLOCK_STMT_BLOCK. (gnat_expand_stmt, case BREAK_STMT): New case. * utils.c (gnat_poplevel): Return a BLOCK, if we made one. 2004-06-07 Jose Ruiz <ruiz@act-europe.fr> * s-stchop.adsm s-stchop.adb, s-stchop-vxworks.adb: Remove the procedure Set_Stack_Size that is not needed. 2004-06-07 Sergey Rybin <rybin@act-europe.fr> * gnat_ugn.texi: Clarify the case when non-standard naming scheme is used for gnatpp input file and for the files upon which it depends 2004-06-07 Ben Brosgol <brosgol@gnat.com> * gnat_ugn.texi: Wordsmithing of "GNAT and Libraries" chapter 2004-06-07 Arnaud Charlet <charlet@act-europe.fr> * gnatvsn.ads: Bump version numbers appropriately. Add new build type. 2004-06-07 Pascal Obry <obry@gnat.com> * gnat_ugn.texi: Improve comments about imported names and link names on Windows. Add a note about the requirement to use -k gnatdll's option when working with a DLL which has stripped stdcall symbols (no @nn suffix). From-SVN: r82691
1332 lines
43 KiB
Ada
1332 lines
43 KiB
Ada
------------------------------------------------------------------------------
|
|
-- --
|
|
-- GNAT COMPILER COMPONENTS --
|
|
-- --
|
|
-- E X P _ D B U G --
|
|
-- --
|
|
-- B o d y --
|
|
-- --
|
|
-- Copyright (C) 1996-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. --
|
|
-- --
|
|
-- GNAT was originally developed by the GNAT team at New York University. --
|
|
-- Extensive contributions were provided by Ada Core Technologies Inc. --
|
|
-- --
|
|
------------------------------------------------------------------------------
|
|
|
|
with Alloc; use Alloc;
|
|
with Atree; use Atree;
|
|
with Debug; use Debug;
|
|
with Einfo; use Einfo;
|
|
with Namet; use Namet;
|
|
with Nlists; use Nlists;
|
|
with Nmake; use Nmake;
|
|
with Opt;
|
|
with Output; use Output;
|
|
with Sem_Eval; use Sem_Eval;
|
|
with Sem_Util; use Sem_Util;
|
|
with Sinfo; use Sinfo;
|
|
with Snames; use Snames;
|
|
with Stand; use Stand;
|
|
with Stringt; use Stringt;
|
|
with Table;
|
|
with Urealp; use Urealp;
|
|
|
|
package body Exp_Dbug is
|
|
|
|
-- The following table is used to queue up the entities passed as
|
|
-- arguments to Qualify_Entity_Names for later processing when
|
|
-- Qualify_All_Entity_Names is called.
|
|
|
|
package Name_Qualify_Units is new Table.Table (
|
|
Table_Component_Type => Node_Id,
|
|
Table_Index_Type => Nat,
|
|
Table_Low_Bound => 1,
|
|
Table_Initial => Alloc.Name_Qualify_Units_Initial,
|
|
Table_Increment => Alloc.Name_Qualify_Units_Increment,
|
|
Table_Name => "Name_Qualify_Units");
|
|
|
|
--------------------------------
|
|
-- Use of Qualification Flags --
|
|
--------------------------------
|
|
|
|
-- There are two flags used to keep track of qualification of entities
|
|
|
|
-- Has_Fully_Qualified_Name
|
|
-- Has_Qualified_Name
|
|
|
|
-- The difference between these is as follows. Has_Qualified_Name is
|
|
-- set to indicate that the name has been qualified as required by the
|
|
-- spec of this package. As described there, this may involve the full
|
|
-- qualification for the name, but for some entities, notably procedure
|
|
-- local variables, this full qualification is not required.
|
|
|
|
-- The flag Has_Fully_Qualified_Name is set if indeed the name has been
|
|
-- fully qualified in the Ada sense. If Has_Fully_Qualified_Name is set,
|
|
-- then Has_Qualified_Name is also set, but the other way round is not
|
|
-- the case.
|
|
|
|
-- Consider the following example:
|
|
|
|
-- with ...
|
|
-- procedure X is
|
|
-- B : Ddd.Ttt;
|
|
-- procedure Y is ..
|
|
|
|
-- Here B is a procedure local variable, so it does not need fully
|
|
-- qualification. The flag Has_Qualified_Name will be set on the
|
|
-- first attempt to qualify B, to indicate that the job is done
|
|
-- and need not be redone.
|
|
|
|
-- But Y is qualified as x__y, since procedures are always fully
|
|
-- qualified, so the first time that an attempt is made to qualify
|
|
-- the name y, it will be replaced by x__y, and both flags are set.
|
|
|
|
-- Why the two flags? Well there are cases where we derive type names
|
|
-- from object names. As noted in the spec, type names are always
|
|
-- fully qualified. Suppose for example that the backend has to build
|
|
-- a padded type for variable B. then it will construct the PAD name
|
|
-- from B, but it requires full qualification, so the fully qualified
|
|
-- type name will be x__b___PAD. The two flags allow the circuit for
|
|
-- building this name to realize efficiently that b needs further
|
|
-- qualification.
|
|
|
|
--------------------
|
|
-- Homonym_Suffix --
|
|
--------------------
|
|
|
|
-- The string defined here (and its associated length) is used to
|
|
-- gather the homonym string that will be appended to Name_Buffer
|
|
-- when the name is complete. Strip_Suffixes appends to this string
|
|
-- as does Append_Homonym_Number, and Output_Homonym_Numbers_Suffix
|
|
-- appends the string to the end of Name_Buffer.
|
|
|
|
Homonym_Numbers : String (1 .. 256);
|
|
Homonym_Len : Natural := 0;
|
|
|
|
----------------------
|
|
-- Local Procedures --
|
|
----------------------
|
|
|
|
procedure Add_Uint_To_Buffer (U : Uint);
|
|
-- Add image of universal integer to Name_Buffer, updating Name_Len
|
|
|
|
procedure Add_Real_To_Buffer (U : Ureal);
|
|
-- Add nnn_ddd to Name_Buffer, where nnn and ddd are integer values of
|
|
-- the normalized numerator and denominator of the given real value.
|
|
|
|
procedure Append_Homonym_Number (E : Entity_Id);
|
|
-- If the entity E has homonyms in the same scope, then make an entry
|
|
-- in the Homonym_Numbers array, bumping Homonym_Count accordingly.
|
|
|
|
function Bounds_Match_Size (E : Entity_Id) return Boolean;
|
|
-- Determine whether the bounds of E match the size of the type. This is
|
|
-- used to determine whether encoding is required for a discrete type.
|
|
|
|
procedure Output_Homonym_Numbers_Suffix;
|
|
-- If homonym numbers are stored, then output them into Name_Buffer.
|
|
|
|
procedure Prepend_String_To_Buffer (S : String);
|
|
-- Prepend given string to the contents of the string buffer, updating
|
|
-- the value in Name_Len (i.e. string is added at start of buffer).
|
|
|
|
procedure Prepend_Uint_To_Buffer (U : Uint);
|
|
-- Prepend image of universal integer to Name_Buffer, updating Name_Len
|
|
|
|
procedure Qualify_Entity_Name (Ent : Entity_Id);
|
|
-- If not already done, replaces the Chars field of the given entity
|
|
-- with the appropriate fully qualified name.
|
|
|
|
procedure Strip_Suffixes (BNPE_Suffix_Found : in out Boolean);
|
|
-- Given an qualified entity name in Name_Buffer, remove any plain X or
|
|
-- X{nb} qualification suffix. The contents of Name_Buffer is not changed
|
|
-- but Name_Len may be adjusted on return to remove the suffix. If a
|
|
-- BNPE suffix is found and stripped, then BNPE_Suffix_Found is set to
|
|
-- True. If no suffix is found, then BNPE_Suffix_Found is not modified.
|
|
-- This routine also searches for a homonym suffix, and if one is found
|
|
-- it is also stripped, and the entries are added to the global homonym
|
|
-- list (Homonym_Numbers) so that they can later be put back.
|
|
|
|
------------------------
|
|
-- Add_Real_To_Buffer --
|
|
------------------------
|
|
|
|
procedure Add_Real_To_Buffer (U : Ureal) is
|
|
begin
|
|
Add_Uint_To_Buffer (Norm_Num (U));
|
|
Add_Str_To_Name_Buffer ("_");
|
|
Add_Uint_To_Buffer (Norm_Den (U));
|
|
end Add_Real_To_Buffer;
|
|
|
|
------------------------
|
|
-- Add_Uint_To_Buffer --
|
|
------------------------
|
|
|
|
procedure Add_Uint_To_Buffer (U : Uint) is
|
|
begin
|
|
if U < 0 then
|
|
Add_Uint_To_Buffer (-U);
|
|
Add_Char_To_Name_Buffer ('m');
|
|
else
|
|
UI_Image (U, Decimal);
|
|
Add_Str_To_Name_Buffer (UI_Image_Buffer (1 .. UI_Image_Length));
|
|
end if;
|
|
end Add_Uint_To_Buffer;
|
|
|
|
---------------------------
|
|
-- Append_Homonym_Number --
|
|
---------------------------
|
|
|
|
procedure Append_Homonym_Number (E : Entity_Id) is
|
|
|
|
procedure Add_Nat_To_H (Nr : Nat);
|
|
-- Little procedure to append Nr to Homonym_Numbers
|
|
|
|
------------------
|
|
-- Add_Nat_To_H --
|
|
------------------
|
|
|
|
procedure Add_Nat_To_H (Nr : Nat) is
|
|
begin
|
|
if Nr >= 10 then
|
|
Add_Nat_To_H (Nr / 10);
|
|
end if;
|
|
|
|
Homonym_Len := Homonym_Len + 1;
|
|
Homonym_Numbers (Homonym_Len) :=
|
|
Character'Val (Nr mod 10 + Character'Pos ('0'));
|
|
end Add_Nat_To_H;
|
|
|
|
-- Start of processing for Append_Homonym_Number
|
|
|
|
begin
|
|
if Has_Homonym (E) then
|
|
declare
|
|
H : Entity_Id := Homonym (E);
|
|
Nr : Nat := 1;
|
|
|
|
begin
|
|
while Present (H) loop
|
|
if Scope (H) = Scope (E) then
|
|
Nr := Nr + 1;
|
|
end if;
|
|
|
|
H := Homonym (H);
|
|
end loop;
|
|
|
|
if Homonym_Len > 0 then
|
|
Homonym_Len := Homonym_Len + 1;
|
|
Homonym_Numbers (Homonym_Len) := '_';
|
|
end if;
|
|
|
|
Add_Nat_To_H (Nr);
|
|
end;
|
|
end if;
|
|
end Append_Homonym_Number;
|
|
|
|
-----------------------
|
|
-- Bounds_Match_Size --
|
|
-----------------------
|
|
|
|
function Bounds_Match_Size (E : Entity_Id) return Boolean is
|
|
Siz : Uint;
|
|
|
|
begin
|
|
if not Is_OK_Static_Subtype (E) then
|
|
return False;
|
|
|
|
elsif Is_Integer_Type (E)
|
|
and then Subtypes_Statically_Match (E, Base_Type (E))
|
|
then
|
|
return True;
|
|
|
|
-- Here we check if the static bounds match the natural size, which
|
|
-- is the size passed through with the debugging information. This
|
|
-- is the Esize rounded up to 8, 16, 32 or 64 as appropriate.
|
|
|
|
else
|
|
declare
|
|
Umark : constant Uintp.Save_Mark := Uintp.Mark;
|
|
Result : Boolean;
|
|
|
|
begin
|
|
if Esize (E) <= 8 then
|
|
Siz := Uint_8;
|
|
elsif Esize (E) <= 16 then
|
|
Siz := Uint_16;
|
|
elsif Esize (E) <= 32 then
|
|
Siz := Uint_32;
|
|
else
|
|
Siz := Uint_64;
|
|
end if;
|
|
|
|
if Is_Modular_Integer_Type (E) or else Is_Enumeration_Type (E) then
|
|
Result :=
|
|
Expr_Rep_Value (Type_Low_Bound (E)) = 0
|
|
and then
|
|
2 ** Siz - Expr_Rep_Value (Type_High_Bound (E)) = 1;
|
|
|
|
else
|
|
Result :=
|
|
Expr_Rep_Value (Type_Low_Bound (E)) + 2 ** (Siz - 1) = 0
|
|
and then
|
|
2 ** (Siz - 1) - Expr_Rep_Value (Type_High_Bound (E)) = 1;
|
|
end if;
|
|
|
|
Release (Umark);
|
|
return Result;
|
|
end;
|
|
end if;
|
|
end Bounds_Match_Size;
|
|
|
|
--------------------------------
|
|
-- Debug_Renaming_Declaration --
|
|
--------------------------------
|
|
|
|
function Debug_Renaming_Declaration (N : Node_Id) return Node_Id is
|
|
Loc : constant Source_Ptr := Sloc (N);
|
|
Ent : constant Node_Id := Defining_Entity (N);
|
|
Nam : constant Node_Id := Name (N);
|
|
Rnm : Name_Id;
|
|
Ren : Node_Id;
|
|
Lit : Entity_Id;
|
|
Typ : Entity_Id;
|
|
Res : Node_Id;
|
|
Def : Entity_Id;
|
|
|
|
function Output_Subscript (N : Node_Id; S : String) return Boolean;
|
|
-- Outputs a single subscript value as ?nnn (subscript is compile
|
|
-- time known value with value nnn) or as ?e (subscript is local
|
|
-- constant with name e), where S supplies the proper string to
|
|
-- use for ?. Returns False if the subscript is not of an appropriate
|
|
-- type to output in one of these two forms. The result is prepended
|
|
-- to the name stored in Name_Buffer.
|
|
|
|
----------------------
|
|
-- Output_Subscript --
|
|
----------------------
|
|
|
|
function Output_Subscript (N : Node_Id; S : String) return Boolean is
|
|
begin
|
|
if Compile_Time_Known_Value (N) then
|
|
Prepend_Uint_To_Buffer (Expr_Value (N));
|
|
|
|
elsif Nkind (N) = N_Identifier
|
|
and then Scope (Entity (N)) = Scope (Ent)
|
|
and then Ekind (Entity (N)) = E_Constant
|
|
then
|
|
Prepend_String_To_Buffer (Get_Name_String (Chars (Entity (N))));
|
|
|
|
else
|
|
return False;
|
|
end if;
|
|
|
|
Prepend_String_To_Buffer (S);
|
|
return True;
|
|
end Output_Subscript;
|
|
|
|
-- Start of processing for Debug_Renaming_Declaration
|
|
|
|
begin
|
|
if not Comes_From_Source (N)
|
|
and then not Needs_Debug_Info (Ent)
|
|
then
|
|
return Empty;
|
|
end if;
|
|
|
|
-- Prepare entity name for type declaration
|
|
|
|
Get_Name_String (Chars (Ent));
|
|
|
|
case Nkind (N) is
|
|
when N_Object_Renaming_Declaration =>
|
|
Add_Str_To_Name_Buffer ("___XR");
|
|
|
|
when N_Exception_Renaming_Declaration =>
|
|
Add_Str_To_Name_Buffer ("___XRE");
|
|
|
|
when N_Package_Renaming_Declaration =>
|
|
Add_Str_To_Name_Buffer ("___XRP");
|
|
|
|
-- If it is a child unit create a fully qualified name,
|
|
-- to disambiguate multiple child units with the same
|
|
-- name and different parents.
|
|
|
|
if Is_Child_Unit (Ent) then
|
|
Prepend_String_To_Buffer ("__");
|
|
Prepend_String_To_Buffer
|
|
(Get_Name_String (Chars (Scope (Ent))));
|
|
end if;
|
|
|
|
when others =>
|
|
return Empty;
|
|
end case;
|
|
|
|
Rnm := Name_Find;
|
|
|
|
-- Get renamed entity and compute suffix
|
|
|
|
Name_Len := 0;
|
|
Ren := Nam;
|
|
loop
|
|
case Nkind (Ren) is
|
|
|
|
when N_Identifier =>
|
|
exit;
|
|
|
|
when N_Expanded_Name =>
|
|
|
|
-- The entity field for an N_Expanded_Name is on the
|
|
-- expanded name node itself, so we are done here too.
|
|
|
|
exit;
|
|
|
|
when N_Selected_Component =>
|
|
Prepend_String_To_Buffer
|
|
(Get_Name_String (Chars (Selector_Name (Ren))));
|
|
Prepend_String_To_Buffer ("XR");
|
|
Ren := Prefix (Ren);
|
|
|
|
when N_Indexed_Component =>
|
|
declare
|
|
X : Node_Id := Last (Expressions (Ren));
|
|
|
|
begin
|
|
while Present (X) loop
|
|
if not Output_Subscript (X, "XS") then
|
|
Set_Materialize_Entity (Ent);
|
|
return Empty;
|
|
end if;
|
|
|
|
Prev (X);
|
|
end loop;
|
|
end;
|
|
|
|
Ren := Prefix (Ren);
|
|
|
|
when N_Slice =>
|
|
|
|
Typ := Etype (First_Index (Etype (Nam)));
|
|
|
|
if not Output_Subscript (Type_High_Bound (Typ), "XS") then
|
|
Set_Materialize_Entity (Ent);
|
|
return Empty;
|
|
end if;
|
|
|
|
if not Output_Subscript (Type_Low_Bound (Typ), "XL") then
|
|
Set_Materialize_Entity (Ent);
|
|
return Empty;
|
|
end if;
|
|
|
|
Ren := Prefix (Ren);
|
|
|
|
when N_Explicit_Dereference =>
|
|
Prepend_String_To_Buffer ("XA");
|
|
Ren := Prefix (Ren);
|
|
|
|
-- For now, anything else simply results in no translation
|
|
|
|
when others =>
|
|
Set_Materialize_Entity (Ent);
|
|
return Empty;
|
|
end case;
|
|
end loop;
|
|
|
|
Prepend_String_To_Buffer ("___XE");
|
|
|
|
-- For now, the literal name contains only the suffix. The Entity_Id
|
|
-- value for the name is used to create a link from this literal name
|
|
-- to the renamed entity using the Debug_Renaming_Link field. Then the
|
|
-- Qualify_Entity_Name procedure uses this link to create the proper
|
|
-- fully qualified name.
|
|
|
|
-- The reason we do things this way is that we really need to copy the
|
|
-- qualification of the renamed entity, and it is really much easier to
|
|
-- do this after the renamed entity has itself been fully qualified.
|
|
|
|
Lit := Make_Defining_Identifier (Loc, Chars => Name_Enter);
|
|
Set_Debug_Renaming_Link (Lit, Entity (Ren));
|
|
|
|
-- Return the appropriate enumeration type
|
|
|
|
Def := Make_Defining_Identifier (Loc, Chars => Rnm);
|
|
Res :=
|
|
Make_Full_Type_Declaration (Loc,
|
|
Defining_Identifier => Def,
|
|
Type_Definition =>
|
|
Make_Enumeration_Type_Definition (Loc,
|
|
Literals => New_List (Lit)));
|
|
|
|
Set_Needs_Debug_Info (Def);
|
|
Set_Needs_Debug_Info (Lit);
|
|
|
|
Set_Discard_Names (Defining_Identifier (Res));
|
|
return Res;
|
|
|
|
-- If we get an exception, just figure it is a case that we cannot
|
|
-- successfully handle using our current approach, since this is
|
|
-- only for debugging, no need to take the compilation with us!
|
|
|
|
exception
|
|
when others =>
|
|
return Make_Null_Statement (Loc);
|
|
end Debug_Renaming_Declaration;
|
|
|
|
----------------------
|
|
-- Get_Encoded_Name --
|
|
----------------------
|
|
|
|
-- Note: see spec for details on encodings
|
|
|
|
procedure Get_Encoded_Name (E : Entity_Id) is
|
|
Has_Suffix : Boolean;
|
|
|
|
begin
|
|
Get_Name_String (Chars (E));
|
|
|
|
-- Nothing to do if we do not have a type
|
|
|
|
if not Is_Type (E)
|
|
|
|
-- Or if this is an enumeration base type
|
|
|
|
or else (Is_Enumeration_Type (E)
|
|
and then E = Base_Type (E))
|
|
|
|
-- Or if this is a dummy type for a renaming
|
|
|
|
or else (Name_Len >= 3 and then
|
|
Name_Buffer (Name_Len - 2 .. Name_Len) = "_XR")
|
|
|
|
or else (Name_Len >= 4 and then
|
|
(Name_Buffer (Name_Len - 3 .. Name_Len) = "_XRE"
|
|
or else
|
|
Name_Buffer (Name_Len - 3 .. Name_Len) = "_XRP"))
|
|
|
|
-- For all these cases, just return the name unchanged
|
|
|
|
then
|
|
Name_Buffer (Name_Len + 1) := ASCII.Nul;
|
|
return;
|
|
end if;
|
|
|
|
Has_Suffix := True;
|
|
|
|
-- Fixed-point case
|
|
|
|
if Is_Fixed_Point_Type (E) then
|
|
Get_External_Name_With_Suffix (E, "XF_");
|
|
Add_Real_To_Buffer (Delta_Value (E));
|
|
|
|
if Small_Value (E) /= Delta_Value (E) then
|
|
Add_Str_To_Name_Buffer ("_");
|
|
Add_Real_To_Buffer (Small_Value (E));
|
|
end if;
|
|
|
|
-- Vax floating-point case
|
|
|
|
elsif Vax_Float (E) then
|
|
|
|
if Digits_Value (Base_Type (E)) = 6 then
|
|
Get_External_Name_With_Suffix (E, "XFF");
|
|
|
|
elsif Digits_Value (Base_Type (E)) = 9 then
|
|
Get_External_Name_With_Suffix (E, "XFF");
|
|
|
|
else
|
|
pragma Assert (Digits_Value (Base_Type (E)) = 15);
|
|
Get_External_Name_With_Suffix (E, "XFG");
|
|
end if;
|
|
|
|
-- Discrete case where bounds do not match size
|
|
|
|
elsif Is_Discrete_Type (E)
|
|
and then not Bounds_Match_Size (E)
|
|
then
|
|
if Has_Biased_Representation (E) then
|
|
Get_External_Name_With_Suffix (E, "XB");
|
|
else
|
|
Get_External_Name_With_Suffix (E, "XD");
|
|
end if;
|
|
|
|
declare
|
|
Lo : constant Node_Id := Type_Low_Bound (E);
|
|
Hi : constant Node_Id := Type_High_Bound (E);
|
|
|
|
Lo_Con : constant Boolean := Compile_Time_Known_Value (Lo);
|
|
Hi_Con : constant Boolean := Compile_Time_Known_Value (Hi);
|
|
|
|
Lo_Discr : constant Boolean :=
|
|
Nkind (Lo) = N_Identifier
|
|
and then
|
|
Ekind (Entity (Lo)) = E_Discriminant;
|
|
|
|
Hi_Discr : constant Boolean :=
|
|
Nkind (Hi) = N_Identifier
|
|
and then
|
|
Ekind (Entity (Hi)) = E_Discriminant;
|
|
|
|
Lo_Encode : constant Boolean := Lo_Con or Lo_Discr;
|
|
Hi_Encode : constant Boolean := Hi_Con or Hi_Discr;
|
|
|
|
begin
|
|
if Lo_Encode or Hi_Encode then
|
|
if Lo_Encode then
|
|
if Hi_Encode then
|
|
Add_Str_To_Name_Buffer ("LU_");
|
|
else
|
|
Add_Str_To_Name_Buffer ("L_");
|
|
end if;
|
|
else
|
|
Add_Str_To_Name_Buffer ("U_");
|
|
end if;
|
|
|
|
if Lo_Con then
|
|
Add_Uint_To_Buffer (Expr_Rep_Value (Lo));
|
|
elsif Lo_Discr then
|
|
Get_Name_String_And_Append (Chars (Entity (Lo)));
|
|
end if;
|
|
|
|
if Lo_Encode and Hi_Encode then
|
|
Add_Str_To_Name_Buffer ("__");
|
|
end if;
|
|
|
|
if Hi_Con then
|
|
Add_Uint_To_Buffer (Expr_Rep_Value (Hi));
|
|
elsif Hi_Discr then
|
|
Get_Name_String_And_Append (Chars (Entity (Hi)));
|
|
end if;
|
|
end if;
|
|
end;
|
|
|
|
-- For all other cases, the encoded name is the normal type name
|
|
|
|
else
|
|
Has_Suffix := False;
|
|
Get_External_Name (E, Has_Suffix);
|
|
end if;
|
|
|
|
if Debug_Flag_B and then Has_Suffix then
|
|
Write_Str ("**** type ");
|
|
Write_Name (Chars (E));
|
|
Write_Str (" is encoded as ");
|
|
Write_Str (Name_Buffer (1 .. Name_Len));
|
|
Write_Eol;
|
|
end if;
|
|
|
|
Name_Buffer (Name_Len + 1) := ASCII.NUL;
|
|
end Get_Encoded_Name;
|
|
|
|
-----------------------
|
|
-- Get_External_Name --
|
|
-----------------------
|
|
|
|
procedure Get_External_Name (Entity : Entity_Id; Has_Suffix : Boolean) is
|
|
E : Entity_Id := Entity;
|
|
Kind : Entity_Kind;
|
|
|
|
procedure Get_Qualified_Name_And_Append (Entity : Entity_Id);
|
|
-- Appends fully qualified name of given entity to Name_Buffer
|
|
|
|
-----------------------------------
|
|
-- Get_Qualified_Name_And_Append --
|
|
-----------------------------------
|
|
|
|
procedure Get_Qualified_Name_And_Append (Entity : Entity_Id) is
|
|
begin
|
|
-- If the entity is a compilation unit, its scope is Standard,
|
|
-- there is no outer scope, and the no further qualification
|
|
-- is required.
|
|
|
|
-- If the front end has already computed a fully qualified name,
|
|
-- then it is also the case that no further qualification is
|
|
-- required
|
|
|
|
if Present (Scope (Scope (Entity)))
|
|
and then not Has_Fully_Qualified_Name (Entity)
|
|
then
|
|
Get_Qualified_Name_And_Append (Scope (Entity));
|
|
Add_Str_To_Name_Buffer ("__");
|
|
Get_Name_String_And_Append (Chars (Entity));
|
|
Append_Homonym_Number (Entity);
|
|
|
|
else
|
|
Get_Name_String_And_Append (Chars (Entity));
|
|
end if;
|
|
|
|
end Get_Qualified_Name_And_Append;
|
|
|
|
-- Start of processing for Get_External_Name
|
|
|
|
begin
|
|
Name_Len := 0;
|
|
|
|
-- If this is a child unit, we want the child
|
|
|
|
if Nkind (E) = N_Defining_Program_Unit_Name then
|
|
E := Defining_Identifier (Entity);
|
|
end if;
|
|
|
|
Kind := Ekind (E);
|
|
|
|
-- Case of interface name being used
|
|
|
|
if (Kind = E_Procedure or else
|
|
Kind = E_Function or else
|
|
Kind = E_Constant or else
|
|
Kind = E_Variable or else
|
|
Kind = E_Exception)
|
|
and then Present (Interface_Name (E))
|
|
and then No (Address_Clause (E))
|
|
and then not Has_Suffix
|
|
then
|
|
Add_String_To_Name_Buffer (Strval (Interface_Name (E)));
|
|
|
|
-- All other cases besides the interface name case
|
|
|
|
else
|
|
-- If this is a library level subprogram (i.e. a subprogram that is a
|
|
-- compilation unit other than a subunit), then we prepend _ada_ to
|
|
-- ensure distinctions required as described in the spec.
|
|
-- Check explicitly for child units, because those are not flagged
|
|
-- as Compilation_Units by lib. Should they be ???
|
|
|
|
if Is_Subprogram (E)
|
|
and then (Is_Compilation_Unit (E) or Is_Child_Unit (E))
|
|
and then not Has_Suffix
|
|
then
|
|
Add_Str_To_Name_Buffer ("_ada_");
|
|
end if;
|
|
|
|
-- If the entity is a subprogram instance that is not a compilation
|
|
-- unit, generate the name of the original Ada entity, which is the
|
|
-- one gdb needs.
|
|
|
|
if Is_Generic_Instance (E)
|
|
and then Is_Subprogram (E)
|
|
and then not Is_Compilation_Unit (Scope (E))
|
|
and then (Ekind (Scope (E)) = E_Package
|
|
or else
|
|
Ekind (Scope (E)) = E_Package_Body)
|
|
and then Present (Related_Instance (Scope (E)))
|
|
then
|
|
E := Related_Instance (Scope (E));
|
|
end if;
|
|
|
|
Get_Qualified_Name_And_Append (E);
|
|
end if;
|
|
|
|
Name_Buffer (Name_Len + 1) := ASCII.Nul;
|
|
end Get_External_Name;
|
|
|
|
-----------------------------------
|
|
-- Get_External_Name_With_Suffix --
|
|
-----------------------------------
|
|
|
|
procedure Get_External_Name_With_Suffix
|
|
(Entity : Entity_Id;
|
|
Suffix : String)
|
|
is
|
|
Has_Suffix : constant Boolean := (Suffix /= "");
|
|
use type Opt.Operating_Mode_Type;
|
|
|
|
begin
|
|
if Opt.Operating_Mode /= Opt.Generate_Code then
|
|
|
|
-- If we are not in code generation mode, we still may call this
|
|
-- procedure from Back_End (more specifically - from gigi for doing
|
|
-- type representation annotation or some representation-specific
|
|
-- checks). But in this mode there is no need to mess with external
|
|
-- names. Furthermore, the call causes difficulties in this case
|
|
-- because the string representing the homonym number is not
|
|
-- correctly reset as a part of the call to
|
|
-- Output_Homonym_Numbers_Suffix (which is not called in gigi)
|
|
|
|
return;
|
|
end if;
|
|
|
|
Get_External_Name (Entity, Has_Suffix);
|
|
|
|
if Has_Suffix then
|
|
Add_Str_To_Name_Buffer ("___");
|
|
Add_Str_To_Name_Buffer (Suffix);
|
|
|
|
Name_Buffer (Name_Len + 1) := ASCII.Nul;
|
|
end if;
|
|
end Get_External_Name_With_Suffix;
|
|
|
|
--------------------------
|
|
-- Get_Variant_Encoding --
|
|
--------------------------
|
|
|
|
procedure Get_Variant_Encoding (V : Node_Id) is
|
|
Choice : Node_Id;
|
|
|
|
procedure Choice_Val (Typ : Character; Choice : Node_Id);
|
|
-- Output encoded value for a single choice value. Typ is the key
|
|
-- character ('S', 'F', or 'T') that precedes the choice value.
|
|
|
|
----------------
|
|
-- Choice_Val --
|
|
----------------
|
|
|
|
procedure Choice_Val (Typ : Character; Choice : Node_Id) is
|
|
begin
|
|
Add_Char_To_Name_Buffer (Typ);
|
|
|
|
if Nkind (Choice) = N_Integer_Literal then
|
|
Add_Uint_To_Buffer (Intval (Choice));
|
|
|
|
-- Character literal with no entity present (this is the case
|
|
-- Standard.Character or Standard.Wide_Character as root type)
|
|
|
|
elsif Nkind (Choice) = N_Character_Literal
|
|
and then No (Entity (Choice))
|
|
then
|
|
Add_Uint_To_Buffer
|
|
(UI_From_Int (Int (Char_Literal_Value (Choice))));
|
|
|
|
else
|
|
declare
|
|
Ent : constant Entity_Id := Entity (Choice);
|
|
|
|
begin
|
|
if Ekind (Ent) = E_Enumeration_Literal then
|
|
Add_Uint_To_Buffer (Enumeration_Rep (Ent));
|
|
|
|
else
|
|
pragma Assert (Ekind (Ent) = E_Constant);
|
|
Choice_Val (Typ, Constant_Value (Ent));
|
|
end if;
|
|
end;
|
|
end if;
|
|
end Choice_Val;
|
|
|
|
-- Start of processing for Get_Variant_Encoding
|
|
|
|
begin
|
|
Name_Len := 0;
|
|
|
|
Choice := First (Discrete_Choices (V));
|
|
while Present (Choice) loop
|
|
if Nkind (Choice) = N_Others_Choice then
|
|
Add_Char_To_Name_Buffer ('O');
|
|
|
|
elsif Nkind (Choice) = N_Range then
|
|
Choice_Val ('R', Low_Bound (Choice));
|
|
Choice_Val ('T', High_Bound (Choice));
|
|
|
|
elsif Is_Entity_Name (Choice)
|
|
and then Is_Type (Entity (Choice))
|
|
then
|
|
Choice_Val ('R', Type_Low_Bound (Entity (Choice)));
|
|
Choice_Val ('T', Type_High_Bound (Entity (Choice)));
|
|
|
|
elsif Nkind (Choice) = N_Subtype_Indication then
|
|
declare
|
|
Rang : constant Node_Id :=
|
|
Range_Expression (Constraint (Choice));
|
|
begin
|
|
Choice_Val ('R', Low_Bound (Rang));
|
|
Choice_Val ('T', High_Bound (Rang));
|
|
end;
|
|
|
|
else
|
|
Choice_Val ('S', Choice);
|
|
end if;
|
|
|
|
Next (Choice);
|
|
end loop;
|
|
|
|
Name_Buffer (Name_Len + 1) := ASCII.NUL;
|
|
|
|
if Debug_Flag_B then
|
|
declare
|
|
VP : constant Node_Id := Parent (V); -- Variant_Part
|
|
CL : constant Node_Id := Parent (VP); -- Component_List
|
|
RD : constant Node_Id := Parent (CL); -- Record_Definition
|
|
FT : constant Node_Id := Parent (RD); -- Full_Type_Declaration
|
|
|
|
begin
|
|
Write_Str ("**** variant for type ");
|
|
Write_Name (Chars (Defining_Identifier (FT)));
|
|
Write_Str (" is encoded as ");
|
|
Write_Str (Name_Buffer (1 .. Name_Len));
|
|
Write_Eol;
|
|
end;
|
|
end if;
|
|
end Get_Variant_Encoding;
|
|
|
|
---------------------------------
|
|
-- Make_Packed_Array_Type_Name --
|
|
---------------------------------
|
|
|
|
function Make_Packed_Array_Type_Name
|
|
(Typ : Entity_Id;
|
|
Csize : Uint)
|
|
return Name_Id
|
|
is
|
|
begin
|
|
Get_Name_String (Chars (Typ));
|
|
Add_Str_To_Name_Buffer ("___XP");
|
|
Add_Uint_To_Buffer (Csize);
|
|
return Name_Find;
|
|
end Make_Packed_Array_Type_Name;
|
|
|
|
-----------------------------------
|
|
-- Output_Homonym_Numbers_Suffix --
|
|
-----------------------------------
|
|
|
|
procedure Output_Homonym_Numbers_Suffix is
|
|
J : Natural;
|
|
|
|
begin
|
|
if Homonym_Len > 0 then
|
|
|
|
-- Check for all 1's, in which case we do not output
|
|
|
|
J := 1;
|
|
loop
|
|
exit when Homonym_Numbers (J) /= '1';
|
|
|
|
-- If we reached end of string we do not output
|
|
|
|
if J = Homonym_Len then
|
|
Homonym_Len := 0;
|
|
return;
|
|
end if;
|
|
|
|
exit when Homonym_Numbers (J + 1) /= '_';
|
|
J := J + 2;
|
|
end loop;
|
|
|
|
-- If we exit the loop then suffix must be output
|
|
|
|
Add_Str_To_Name_Buffer ("__");
|
|
Add_Str_To_Name_Buffer (Homonym_Numbers (1 .. Homonym_Len));
|
|
Homonym_Len := 0;
|
|
end if;
|
|
end Output_Homonym_Numbers_Suffix;
|
|
|
|
------------------------------
|
|
-- Prepend_String_To_Buffer --
|
|
------------------------------
|
|
|
|
procedure Prepend_String_To_Buffer (S : String) is
|
|
N : constant Integer := S'Length;
|
|
begin
|
|
Name_Buffer (1 + N .. Name_Len + N) := Name_Buffer (1 .. Name_Len);
|
|
Name_Buffer (1 .. N) := S;
|
|
Name_Len := Name_Len + N;
|
|
end Prepend_String_To_Buffer;
|
|
|
|
----------------------------
|
|
-- Prepend_Uint_To_Buffer --
|
|
----------------------------
|
|
|
|
procedure Prepend_Uint_To_Buffer (U : Uint) is
|
|
begin
|
|
if U < 0 then
|
|
Prepend_String_To_Buffer ("m");
|
|
Prepend_Uint_To_Buffer (-U);
|
|
else
|
|
UI_Image (U, Decimal);
|
|
Prepend_String_To_Buffer (UI_Image_Buffer (1 .. UI_Image_Length));
|
|
end if;
|
|
end Prepend_Uint_To_Buffer;
|
|
|
|
------------------------------
|
|
-- Qualify_All_Entity_Names --
|
|
------------------------------
|
|
|
|
procedure Qualify_All_Entity_Names is
|
|
E : Entity_Id;
|
|
Ent : Entity_Id;
|
|
|
|
begin
|
|
for J in Name_Qualify_Units.First .. Name_Qualify_Units.Last loop
|
|
E := Defining_Entity (Name_Qualify_Units.Table (J));
|
|
Qualify_Entity_Name (E);
|
|
|
|
Ent := First_Entity (E);
|
|
while Present (Ent) loop
|
|
Qualify_Entity_Name (Ent);
|
|
Next_Entity (Ent);
|
|
|
|
-- There are odd cases where Last_Entity (E) = E. This happens
|
|
-- in the case of renaming of packages. This test avoids getting
|
|
-- stuck in such cases.
|
|
|
|
exit when Ent = E;
|
|
end loop;
|
|
end loop;
|
|
end Qualify_All_Entity_Names;
|
|
|
|
-------------------------
|
|
-- Qualify_Entity_Name --
|
|
-------------------------
|
|
|
|
procedure Qualify_Entity_Name (Ent : Entity_Id) is
|
|
|
|
Full_Qualify_Name : String (1 .. Name_Buffer'Length);
|
|
Full_Qualify_Len : Natural := 0;
|
|
-- Used to accumulate fully qualified name of subprogram
|
|
|
|
procedure Fully_Qualify_Name (E : Entity_Id);
|
|
-- Used to qualify a subprogram or type name, where full
|
|
-- qualification up to Standard is always used. Name is set
|
|
-- in Full_Qualify_Name with the length in Full_Qualify_Len.
|
|
-- Note that this routine does not prepend the _ada_ string
|
|
-- required for library subprograms (this is done in the back end).
|
|
|
|
function Is_BNPE (S : Entity_Id) return Boolean;
|
|
-- Determines if S is a BNPE, i.e. Body-Nested Package Entity, which
|
|
-- is defined to be a package which is immediately nested within a
|
|
-- package body.
|
|
|
|
function Qualify_Needed (S : Entity_Id) return Boolean;
|
|
-- Given a scope, determines if the scope is to be included in the
|
|
-- fully qualified name, True if so, False if not.
|
|
|
|
procedure Set_BNPE_Suffix (E : Entity_Id);
|
|
-- Recursive routine to append the BNPE qualification suffix. Works
|
|
-- from right to left with E being the current entity in the list.
|
|
-- The result does NOT have the trailing n's and trailing b stripped.
|
|
-- The caller must do this required stripping.
|
|
|
|
procedure Set_Entity_Name (E : Entity_Id);
|
|
-- Internal recursive routine that does most of the work. This routine
|
|
-- leaves the result sitting in Name_Buffer and Name_Len.
|
|
|
|
BNPE_Suffix_Needed : Boolean := False;
|
|
-- Set true if a body-nested package entity suffix is required
|
|
|
|
Save_Chars : constant Name_Id := Chars (Ent);
|
|
-- Save original name
|
|
|
|
------------------------
|
|
-- Fully_Qualify_Name --
|
|
------------------------
|
|
|
|
procedure Fully_Qualify_Name (E : Entity_Id) is
|
|
Discard : Boolean := False;
|
|
|
|
begin
|
|
-- Ignore empty entry (can happen in error cases)
|
|
|
|
if No (E) then
|
|
return;
|
|
|
|
-- If this we are qualifying entities local to a generic
|
|
-- instance, use the name of the original instantiation,
|
|
-- not that of the anonymous subprogram in the wrapper
|
|
-- package, so that gdb doesn't have to know about these.
|
|
|
|
elsif Is_Generic_Instance (E)
|
|
and then Is_Subprogram (E)
|
|
and then not Comes_From_Source (E)
|
|
and then not Is_Compilation_Unit (Scope (E))
|
|
then
|
|
Fully_Qualify_Name (Related_Instance (Scope (E)));
|
|
return;
|
|
end if;
|
|
|
|
-- If we reached fully qualified name, then just copy it
|
|
|
|
if Has_Fully_Qualified_Name (E) then
|
|
Get_Name_String (Chars (E));
|
|
Strip_Suffixes (Discard);
|
|
Full_Qualify_Name (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
|
|
Full_Qualify_Len := Name_Len;
|
|
Set_Has_Fully_Qualified_Name (Ent);
|
|
|
|
-- Case of non-fully qualified name
|
|
|
|
else
|
|
if Scope (E) = Standard_Standard then
|
|
Set_Has_Fully_Qualified_Name (Ent);
|
|
else
|
|
Fully_Qualify_Name (Scope (E));
|
|
Full_Qualify_Name (Full_Qualify_Len + 1) := '_';
|
|
Full_Qualify_Name (Full_Qualify_Len + 2) := '_';
|
|
Full_Qualify_Len := Full_Qualify_Len + 2;
|
|
end if;
|
|
|
|
if Has_Qualified_Name (E) then
|
|
Get_Unqualified_Name_String (Chars (E));
|
|
else
|
|
Get_Name_String (Chars (E));
|
|
end if;
|
|
|
|
-- A special check here, we never add internal block or loop
|
|
-- names, since they intefere with debugging. We identify these
|
|
-- by the fact that they start with an upper case B or L.
|
|
-- But do add these if what we are qualifying is a __clean
|
|
-- procedure since those need to be made unique.
|
|
|
|
if (Name_Buffer (1) = 'B' or else Name_Buffer (1) = 'L')
|
|
and then (not Debug_Flag_VV)
|
|
and then Full_Qualify_Len > 2
|
|
and then Chars (Ent) /= Name_uClean
|
|
then
|
|
Full_Qualify_Len := Full_Qualify_Len - 2;
|
|
|
|
else
|
|
Full_Qualify_Name
|
|
(Full_Qualify_Len + 1 .. Full_Qualify_Len + Name_Len) :=
|
|
Name_Buffer (1 .. Name_Len);
|
|
Full_Qualify_Len := Full_Qualify_Len + Name_Len;
|
|
Append_Homonym_Number (E);
|
|
end if;
|
|
end if;
|
|
|
|
if Is_BNPE (E) then
|
|
BNPE_Suffix_Needed := True;
|
|
end if;
|
|
end Fully_Qualify_Name;
|
|
|
|
-------------
|
|
-- Is_BNPE --
|
|
-------------
|
|
|
|
function Is_BNPE (S : Entity_Id) return Boolean is
|
|
begin
|
|
return
|
|
Ekind (S) = E_Package
|
|
and then Is_Package_Body_Entity (S);
|
|
end Is_BNPE;
|
|
|
|
--------------------
|
|
-- Qualify_Needed --
|
|
--------------------
|
|
|
|
function Qualify_Needed (S : Entity_Id) return Boolean is
|
|
begin
|
|
-- If we got all the way to Standard, then we have certainly
|
|
-- fully qualified the name, so set the flag appropriately,
|
|
-- and then return False, since we are most certainly done!
|
|
|
|
if S = Standard_Standard then
|
|
Set_Has_Fully_Qualified_Name (Ent, True);
|
|
return False;
|
|
|
|
-- Otherwise figure out if further qualification is required
|
|
|
|
else
|
|
return
|
|
Is_Subprogram (Ent)
|
|
or else
|
|
Ekind (Ent) = E_Subprogram_Body
|
|
or else
|
|
(Ekind (S) /= E_Block
|
|
and then not Is_Dynamic_Scope (S));
|
|
end if;
|
|
end Qualify_Needed;
|
|
|
|
---------------------
|
|
-- Set_BNPE_Suffix --
|
|
---------------------
|
|
|
|
procedure Set_BNPE_Suffix (E : Entity_Id) is
|
|
S : constant Entity_Id := Scope (E);
|
|
|
|
begin
|
|
if Qualify_Needed (S) then
|
|
Set_BNPE_Suffix (S);
|
|
|
|
if Is_BNPE (E) then
|
|
Add_Char_To_Name_Buffer ('b');
|
|
else
|
|
Add_Char_To_Name_Buffer ('n');
|
|
end if;
|
|
|
|
else
|
|
Add_Char_To_Name_Buffer ('X');
|
|
end if;
|
|
|
|
end Set_BNPE_Suffix;
|
|
|
|
---------------------
|
|
-- Set_Entity_Name --
|
|
---------------------
|
|
|
|
procedure Set_Entity_Name (E : Entity_Id) is
|
|
S : constant Entity_Id := Scope (E);
|
|
|
|
begin
|
|
-- If we reach an already qualified name, just take the encoding
|
|
-- except that we strip the package body suffixes, since these
|
|
-- will be separately put on later.
|
|
|
|
if Has_Qualified_Name (E) then
|
|
Get_Name_String_And_Append (Chars (E));
|
|
Strip_Suffixes (BNPE_Suffix_Needed);
|
|
|
|
-- If the top level name we are adding is itself fully
|
|
-- qualified, then that means that the name that we are
|
|
-- preparing for the Fully_Qualify_Name call will also
|
|
-- generate a fully qualified name.
|
|
|
|
if Has_Fully_Qualified_Name (E) then
|
|
Set_Has_Fully_Qualified_Name (Ent);
|
|
end if;
|
|
|
|
-- Case where upper level name is not encoded yet
|
|
|
|
else
|
|
-- Recurse if further qualification required
|
|
|
|
if Qualify_Needed (S) then
|
|
Set_Entity_Name (S);
|
|
Add_Str_To_Name_Buffer ("__");
|
|
end if;
|
|
|
|
-- Otherwise get name and note if it is a NPBE
|
|
|
|
Get_Name_String_And_Append (Chars (E));
|
|
|
|
if Is_BNPE (E) then
|
|
BNPE_Suffix_Needed := True;
|
|
end if;
|
|
|
|
Append_Homonym_Number (E);
|
|
end if;
|
|
end Set_Entity_Name;
|
|
|
|
-- Start of processing for Qualify_Entity_Name
|
|
|
|
begin
|
|
if Has_Qualified_Name (Ent) then
|
|
return;
|
|
|
|
-- Here is where we create the proper link for renaming
|
|
|
|
elsif Ekind (Ent) = E_Enumeration_Literal
|
|
and then Present (Debug_Renaming_Link (Ent))
|
|
then
|
|
Name_Len := 0;
|
|
Qualify_Entity_Name (Debug_Renaming_Link (Ent));
|
|
Get_Name_String (Chars (Ent));
|
|
Prepend_String_To_Buffer
|
|
(Get_Name_String (Chars (Debug_Renaming_Link (Ent))));
|
|
Set_Chars (Ent, Name_Enter);
|
|
Set_Has_Qualified_Name (Ent);
|
|
return;
|
|
|
|
elsif Is_Subprogram (Ent)
|
|
or else Ekind (Ent) = E_Subprogram_Body
|
|
or else Is_Type (Ent)
|
|
then
|
|
Fully_Qualify_Name (Ent);
|
|
Name_Len := Full_Qualify_Len;
|
|
Name_Buffer (1 .. Name_Len) := Full_Qualify_Name (1 .. Name_Len);
|
|
|
|
elsif Qualify_Needed (Scope (Ent)) then
|
|
Name_Len := 0;
|
|
Set_Entity_Name (Ent);
|
|
|
|
else
|
|
Set_Has_Qualified_Name (Ent);
|
|
return;
|
|
end if;
|
|
|
|
-- Fall through with a fully qualified name in Name_Buffer/Name_Len
|
|
|
|
Output_Homonym_Numbers_Suffix;
|
|
|
|
-- Add body-nested package suffix if required
|
|
|
|
if BNPE_Suffix_Needed
|
|
and then Ekind (Ent) /= E_Enumeration_Literal
|
|
then
|
|
Set_BNPE_Suffix (Ent);
|
|
|
|
-- Strip trailing n's and last trailing b as required. note that
|
|
-- we know there is at least one b, or no suffix would be generated.
|
|
|
|
while Name_Buffer (Name_Len) = 'n' loop
|
|
Name_Len := Name_Len - 1;
|
|
end loop;
|
|
|
|
Name_Len := Name_Len - 1;
|
|
end if;
|
|
|
|
Set_Chars (Ent, Name_Enter);
|
|
Set_Has_Qualified_Name (Ent);
|
|
|
|
if Debug_Flag_BB then
|
|
Write_Str ("*** ");
|
|
Write_Name (Save_Chars);
|
|
Write_Str (" qualified as ");
|
|
Write_Name (Chars (Ent));
|
|
Write_Eol;
|
|
end if;
|
|
end Qualify_Entity_Name;
|
|
|
|
--------------------------
|
|
-- Qualify_Entity_Names --
|
|
--------------------------
|
|
|
|
procedure Qualify_Entity_Names (N : Node_Id) is
|
|
begin
|
|
Name_Qualify_Units.Append (N);
|
|
end Qualify_Entity_Names;
|
|
|
|
--------------------
|
|
-- Strip_Suffixes --
|
|
--------------------
|
|
|
|
procedure Strip_Suffixes (BNPE_Suffix_Found : in out Boolean) is
|
|
SL : Natural;
|
|
|
|
begin
|
|
-- Search for and strip BNPE suffix
|
|
|
|
for J in reverse 2 .. Name_Len loop
|
|
if Name_Buffer (J) = 'X' then
|
|
Name_Len := J - 1;
|
|
BNPE_Suffix_Found := True;
|
|
exit;
|
|
end if;
|
|
|
|
exit when Name_Buffer (J) /= 'b' and then Name_Buffer (J) /= 'n';
|
|
end loop;
|
|
|
|
-- Search for and strip homonym numbers suffix
|
|
|
|
for J in reverse 2 .. Name_Len - 2 loop
|
|
if Name_Buffer (J) = '_'
|
|
and then Name_Buffer (J + 1) = '_'
|
|
then
|
|
if Name_Buffer (J + 2) in '0' .. '9' then
|
|
if Homonym_Len > 0 then
|
|
Homonym_Len := Homonym_Len + 1;
|
|
Homonym_Numbers (Homonym_Len) := '-';
|
|
end if;
|
|
|
|
SL := Name_Len - (J + 1);
|
|
|
|
Homonym_Numbers (Homonym_Len + 1 .. Homonym_Len + SL) :=
|
|
Name_Buffer (J + 2 .. Name_Len);
|
|
Name_Len := J - 1;
|
|
Homonym_Len := Homonym_Len + SL;
|
|
end if;
|
|
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
end Strip_Suffixes;
|
|
|
|
end Exp_Dbug;
|