Daily bump.
[official-gcc.git] / gcc / ada / exp_dbug.adb
blob60f603951dda1da363fbbcc40c51524effcc5cb3
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ D B U G --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.2 $
10 -- --
11 -- Copyright (C) 1996-2001 Free Software Foundation, Inc. --
12 -- --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
23 -- --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- Extensive contributions were provided by Ada Core Technologies Inc. --
26 -- --
27 ------------------------------------------------------------------------------
29 with Alloc; use Alloc;
30 with Atree; use Atree;
31 with Debug; use Debug;
32 with Einfo; use Einfo;
33 with Exp_Util; use Exp_Util;
34 with Freeze; use Freeze;
35 with Lib; use Lib;
36 with Hostparm; use Hostparm;
37 with Namet; use Namet;
38 with Nlists; use Nlists;
39 with Nmake; use Nmake;
40 with Opt; use Opt;
41 with Output; use Output;
42 with Sem_Eval; use Sem_Eval;
43 with Sem_Util; use Sem_Util;
44 with Sinput; use Sinput;
45 with Snames; use Snames;
46 with Stand; use Stand;
47 with Stringt; use Stringt;
48 with Table;
49 with Urealp; use Urealp;
51 with GNAT.HTable;
53 package body Exp_Dbug is
55 -- The following table is used to queue up the entities passed as
56 -- arguments to Qualify_Entity_Names for later processing when
57 -- Qualify_All_Entity_Names is called.
59 package Name_Qualify_Units is new Table.Table (
60 Table_Component_Type => Node_Id,
61 Table_Index_Type => Nat,
62 Table_Low_Bound => 1,
63 Table_Initial => Alloc.Name_Qualify_Units_Initial,
64 Table_Increment => Alloc.Name_Qualify_Units_Increment,
65 Table_Name => "Name_Qualify_Units");
67 -- Define hash table for compressed debug names
69 -- This hash table keeps track of qualification prefix strings
70 -- that have been compressed. The element is the corresponding
71 -- hash value used in the compressed symbol.
73 type Hindex is range 0 .. 4096;
74 -- Type to define range of headers
76 function SHash (S : String_Ptr) return Hindex;
77 -- Hash function for this table
79 function SEq (F1, F2 : String_Ptr) return Boolean;
80 -- Equality function for this table
82 type Elmt is record
83 W : Word;
84 S : String_Ptr;
85 end record;
87 No_Elmt : Elmt := (0, null);
89 package CDN is new GNAT.HTable.Simple_HTable (
90 Header_Num => Hindex,
91 Element => Elmt,
92 No_Element => No_Elmt,
93 Key => String_Ptr,
94 Hash => SHash,
95 Equal => SEq);
97 --------------------------------
98 -- Use of Qualification Flags --
99 --------------------------------
101 -- There are two flags used to keep track of qualification of entities
103 -- Has_Fully_Qualified_Name
104 -- Has_Qualified_Name
106 -- The difference between these is as follows. Has_Qualified_Name is
107 -- set to indicate that the name has been qualified as required by the
108 -- spec of this package. As described there, this may involve the full
109 -- qualification for the name, but for some entities, notably procedure
110 -- local variables, this full qualification is not required.
112 -- The flag Has_Fully_Qualified_Name is set if indeed the name has been
113 -- fully qualified in the Ada sense. If Has_Fully_Qualified_Name is set,
114 -- then Has_Qualified_Name is also set, but the other way round is not
115 -- the case.
117 -- Consider the following example:
119 -- with ...
120 -- procedure X is
121 -- B : Ddd.Ttt;
122 -- procedure Y is ..
124 -- Here B is a procedure local variable, so it does not need fully
125 -- qualification. The flag Has_Qualified_Name will be set on the
126 -- first attempt to qualify B, to indicate that the job is done
127 -- and need not be redone.
129 -- But Y is qualified as x__y, since procedures are always fully
130 -- qualified, so the first time that an attempt is made to qualify
131 -- the name y, it will be replaced by x__y, and both flags are set.
133 -- Why the two flags? Well there are cases where we derive type names
134 -- from object names. As noted in the spec, type names are always
135 -- fully qualified. Suppose for example that the backend has to build
136 -- a padded type for variable B. then it will construct the PAD name
137 -- from B, but it requires full qualification, so the fully qualified
138 -- type name will be x__b___PAD. The two flags allow the circuit for
139 -- building this name to realize efficiently that b needs further
140 -- qualification.
142 ----------------------
143 -- Local Procedures --
144 ----------------------
146 procedure Add_Uint_To_Buffer (U : Uint);
147 -- Add image of universal integer to Name_Buffer, updating Name_Len
149 procedure Add_Real_To_Buffer (U : Ureal);
150 -- Add nnn_ddd to Name_Buffer, where nnn and ddd are integer values of
151 -- the normalized numerator and denominator of the given real value.
153 function Bounds_Match_Size (E : Entity_Id) return Boolean;
154 -- Determine whether the bounds of E match the size of the type. This is
155 -- used to determine whether encoding is required for a discrete type.
157 function CDN_Hash (S : String) return Word;
158 -- This is the hash function used to compress debug symbols. The string
159 -- S is the prefix which is a list of qualified names separated by double
160 -- underscore (no trailing double underscore). The returned value is the
161 -- hash value used in the compressed names. It is also used for the hash
162 -- table used to keep track of what prefixes have been compressed so far.
164 procedure Compress_Debug_Name (E : Entity_Id);
165 -- If the name of the entity E is too long, or compression is to be
166 -- attempted on all names (Compress_Debug_Names set), then an attempt
167 -- is made to compress the name of the entity.
169 function Double_Underscore (S : String; J : Natural) return Boolean;
170 -- Returns True if J is the start of a double underscore
171 -- sequence in the string S (defined as two underscores
172 -- which are preceded and followed by a non-underscore)
174 procedure Prepend_String_To_Buffer (S : String);
175 -- Prepend given string to the contents of the string buffer, updating
176 -- the value in Name_Len (i.e. string is added at start of buffer).
178 procedure Prepend_Uint_To_Buffer (U : Uint);
179 -- Prepend image of universal integer to Name_Buffer, updating Name_Len
181 procedure Put_Hex (W : Word; N : Natural);
182 -- Output W as 8 hex digits (0-9, a-f) in Name_Buffer (N .. N + 7)
184 procedure Qualify_Entity_Name (Ent : Entity_Id);
185 -- If not already done, replaces the Chars field of the given entity
186 -- with the appropriate fully qualified name.
188 procedure Strip_BNPE_Suffix (Suffix_Found : in out Boolean);
189 -- Given an qualified entity name in Name_Buffer, remove any plain X or
190 -- X{nb} qualification suffix. The contents of Name_Buffer is not changed
191 -- but Name_Len may be adjusted on return to remove the suffix. If a
192 -- suffix is found and stripped, then Suffix_Found is set to True. If
193 -- no suffix is found, then Suffix_Found is not modified.
195 ------------------------
196 -- Add_Real_To_Buffer --
197 ------------------------
199 procedure Add_Real_To_Buffer (U : Ureal) is
200 begin
201 Add_Uint_To_Buffer (Norm_Num (U));
202 Add_Str_To_Name_Buffer ("_");
203 Add_Uint_To_Buffer (Norm_Den (U));
204 end Add_Real_To_Buffer;
206 ------------------------
207 -- Add_Uint_To_Buffer --
208 ------------------------
210 procedure Add_Uint_To_Buffer (U : Uint) is
211 begin
212 if U < 0 then
213 Add_Uint_To_Buffer (-U);
214 Add_Char_To_Name_Buffer ('m');
215 else
216 UI_Image (U, Decimal);
217 Add_Str_To_Name_Buffer (UI_Image_Buffer (1 .. UI_Image_Length));
218 end if;
219 end Add_Uint_To_Buffer;
221 -----------------------
222 -- Bounds_Match_Size --
223 -----------------------
225 function Bounds_Match_Size (E : Entity_Id) return Boolean is
226 Siz : Uint;
228 begin
229 if not Is_OK_Static_Subtype (E) then
230 return False;
232 elsif Is_Integer_Type (E)
233 and then Subtypes_Statically_Match (E, Base_Type (E))
234 then
235 return True;
237 -- Here we check if the static bounds match the natural size, which
238 -- is the size passed through with the debugging information. This
239 -- is the Esize rounded up to 8, 16, 32 or 64 as appropriate.
241 else
242 declare
243 Umark : constant Uintp.Save_Mark := Uintp.Mark;
244 Result : Boolean;
246 begin
247 if Esize (E) <= 8 then
248 Siz := Uint_8;
249 elsif Esize (E) <= 16 then
250 Siz := Uint_16;
251 elsif Esize (E) <= 32 then
252 Siz := Uint_32;
253 else
254 Siz := Uint_64;
255 end if;
257 if Is_Modular_Integer_Type (E) or else Is_Enumeration_Type (E) then
258 Result :=
259 Expr_Rep_Value (Type_Low_Bound (E)) = 0
260 and then
261 2 ** Siz - Expr_Rep_Value (Type_High_Bound (E)) = 1;
263 else
264 Result :=
265 Expr_Rep_Value (Type_Low_Bound (E)) + 2 ** (Siz - 1) = 0
266 and then
267 2 ** (Siz - 1) - Expr_Rep_Value (Type_High_Bound (E)) = 1;
268 end if;
270 Release (Umark);
271 return Result;
272 end;
273 end if;
274 end Bounds_Match_Size;
276 --------------
277 -- CDN_Hash --
278 --------------
280 function CDN_Hash (S : String) return Word is
281 H : Word;
283 function Rotate_Left (Value : Word; Amount : Natural) return Word;
284 pragma Import (Intrinsic, Rotate_Left);
286 begin
287 H := 0;
288 for J in S'Range loop
289 H := Rotate_Left (H, 3) + Character'Pos (S (J));
290 end loop;
292 return H;
293 end CDN_Hash;
295 -------------------------
296 -- Compress_Debug_Name --
297 -------------------------
299 procedure Compress_Debug_Name (E : Entity_Id) is
300 Ptr : Natural;
301 Sptr : String_Ptr;
302 Cod : Word;
304 begin
305 if not Compress_Debug_Names
306 and then Length_Of_Name (Chars (E)) <= Max_Debug_Name_Length
307 then
308 return;
309 end if;
311 Get_Name_String (Chars (E));
313 -- Find rightmost double underscore
315 Ptr := Name_Len - 2;
316 loop
317 exit when Double_Underscore (Name_Buffer, Ptr);
319 -- Cannot compress if no double underscore anywhere
321 if Ptr < 2 then
322 return;
323 end if;
325 Ptr := Ptr - 1;
326 end loop;
328 -- At this stage we have
330 -- Name_Buffer (1 .. Ptr - 1) string to compress
331 -- Name_Buffer (Ptr) underscore
332 -- Name_Buffer (Ptr + 1) underscore
333 -- Name_Buffer (Ptr + 2 .. Name_Len) simple name to retain
335 -- See if we already have an entry for the compression string
337 -- No point in compressing if it does not make things shorter
339 if Name_Len <= (2 + 8 + 1) + (Name_Len - (Ptr + 1)) then
340 return;
341 end if;
343 -- Do not compress any reference to entity in internal file
345 if Name_Buffer (1 .. 5) = "ada__"
346 or else
347 Name_Buffer (1 .. 8) = "system__"
348 or else
349 Name_Buffer (1 .. 6) = "gnat__"
350 or else
351 Name_Buffer (1 .. 12) = "interfaces__"
352 or else
353 (OpenVMS and then Name_Buffer (1 .. 5) = "dec__")
354 then
355 return;
356 end if;
358 Sptr := Name_Buffer (1 .. Ptr - 1)'Unrestricted_Access;
359 Cod := CDN.Get (Sptr).W;
361 if Cod = 0 then
362 Cod := CDN_Hash (Sptr.all);
363 Sptr := new String'(Sptr.all);
364 CDN.Set (Sptr, (Cod, Sptr));
365 end if;
367 Name_Buffer (1) := 'X';
368 Name_Buffer (2) := 'C';
369 Put_Hex (Cod, 3);
370 Name_Buffer (11) := '_';
371 Name_Buffer (12 .. Name_Len - Ptr + 10) :=
372 Name_Buffer (Ptr + 2 .. Name_Len);
373 Name_Len := Name_Len - Ptr + 10;
375 Set_Chars (E, Name_Enter);
376 end Compress_Debug_Name;
378 --------------------------------
379 -- Debug_Renaming_Declaration --
380 --------------------------------
382 function Debug_Renaming_Declaration (N : Node_Id) return Node_Id is
383 Loc : constant Source_Ptr := Sloc (N);
384 Ent : constant Node_Id := Defining_Entity (N);
385 Nam : constant Node_Id := Name (N);
386 Rnm : Name_Id;
387 Ren : Node_Id;
388 Lit : Entity_Id;
389 Typ : Entity_Id;
390 Res : Node_Id;
391 Def : Entity_Id;
393 function Output_Subscript (N : Node_Id; S : String) return Boolean;
394 -- Outputs a single subscript value as ?nnn (subscript is compile
395 -- time known value with value nnn) or as ?e (subscript is local
396 -- constant with name e), where S supplies the proper string to
397 -- use for ?. Returns False if the subscript is not of an appropriate
398 -- type to output in one of these two forms. The result is prepended
399 -- to the name stored in Name_Buffer.
401 ----------------------
402 -- Output_Subscript --
403 ----------------------
405 function Output_Subscript (N : Node_Id; S : String) return Boolean is
406 begin
407 if Compile_Time_Known_Value (N) then
408 Prepend_Uint_To_Buffer (Expr_Value (N));
410 elsif Nkind (N) = N_Identifier
411 and then Scope (Entity (N)) = Scope (Ent)
412 and then Ekind (Entity (N)) = E_Constant
413 then
414 Prepend_String_To_Buffer (Get_Name_String (Chars (Entity (N))));
416 else
417 return False;
418 end if;
420 Prepend_String_To_Buffer (S);
421 return True;
422 end Output_Subscript;
424 -- Start of processing for Debug_Renaming_Declaration
426 begin
427 if not Comes_From_Source (N) then
428 return Empty;
429 end if;
431 -- Prepare entity name for type declaration
433 Get_Name_String (Chars (Ent));
435 case Nkind (N) is
436 when N_Object_Renaming_Declaration =>
437 Add_Str_To_Name_Buffer ("___XR");
439 when N_Exception_Renaming_Declaration =>
440 Add_Str_To_Name_Buffer ("___XRE");
442 when N_Package_Renaming_Declaration =>
443 Add_Str_To_Name_Buffer ("___XRP");
445 when others =>
446 return Empty;
447 end case;
449 Rnm := Name_Find;
451 -- Get renamed entity and compute suffix
453 Name_Len := 0;
454 Ren := Nam;
455 loop
456 case Nkind (Ren) is
458 when N_Identifier =>
459 exit;
461 when N_Expanded_Name =>
463 -- The entity field for an N_Expanded_Name is on the
464 -- expanded name node itself, so we are done here too.
466 exit;
468 when N_Selected_Component =>
469 Prepend_String_To_Buffer
470 (Get_Name_String (Chars (Selector_Name (Ren))));
471 Prepend_String_To_Buffer ("XR");
472 Ren := Prefix (Ren);
474 when N_Indexed_Component =>
475 declare
476 X : Node_Id := Last (Expressions (Ren));
478 begin
479 while Present (X) loop
480 if not Output_Subscript (X, "XS") then
481 Set_Materialize_Entity (Ent);
482 return Empty;
483 end if;
485 Prev (X);
486 end loop;
487 end;
489 Ren := Prefix (Ren);
491 when N_Slice =>
493 Typ := Etype (First_Index (Etype (Nam)));
495 if not Output_Subscript (Type_High_Bound (Typ), "XS") then
496 Set_Materialize_Entity (Ent);
497 return Empty;
498 end if;
500 if not Output_Subscript (Type_Low_Bound (Typ), "XL") then
501 Set_Materialize_Entity (Ent);
502 return Empty;
503 end if;
505 Ren := Prefix (Ren);
507 when N_Explicit_Dereference =>
508 Prepend_String_To_Buffer ("XA");
509 Ren := Prefix (Ren);
511 -- For now, anything else simply results in no translation
513 when others =>
514 Set_Materialize_Entity (Ent);
515 return Empty;
516 end case;
517 end loop;
519 Prepend_String_To_Buffer ("___XE");
521 -- For now, the literal name contains only the suffix. The Entity_Id
522 -- value for the name is used to create a link from this literal name
523 -- to the renamed entity using the Debug_Renaming_Link field. Then the
524 -- Qualify_Entity_Name procedure uses this link to create the proper
525 -- fully qualified name.
527 -- The reason we do things this way is that we really need to copy the
528 -- qualification of the renamed entity, and it is really much easier to
529 -- do this after the renamed entity has itself been fully qualified.
531 Lit := Make_Defining_Identifier (Loc, Chars => Name_Enter);
532 Set_Debug_Renaming_Link (Lit, Entity (Ren));
534 -- Return the appropriate enumeration type
536 Def := Make_Defining_Identifier (Loc, Chars => Rnm);
537 Res :=
538 Make_Full_Type_Declaration (Loc,
539 Defining_Identifier => Def,
540 Type_Definition =>
541 Make_Enumeration_Type_Definition (Loc,
542 Literals => New_List (Lit)));
544 Set_Needs_Debug_Info (Def);
545 Set_Needs_Debug_Info (Lit);
547 Set_Discard_Names (Defining_Identifier (Res));
548 return Res;
550 -- If we get an exception, just figure it is a case that we cannot
551 -- successfully handle using our current approach, since this is
552 -- only for debugging, no need to take the compilation with us!
554 exception
555 when others =>
556 return Make_Null_Statement (Loc);
557 end Debug_Renaming_Declaration;
559 -----------------------
560 -- Double_Underscore --
561 -----------------------
563 function Double_Underscore (S : String; J : Natural) return Boolean is
564 begin
565 if J = S'First or else J > S'Last - 2 then
566 return False;
568 else
569 return S (J) = '_'
570 and then S (J + 1) = '_'
571 and then S (J - 1) /= '_'
572 and then S (J + 2) /= '_';
573 end if;
574 end Double_Underscore;
576 ------------------------------
577 -- Generate_Auxiliary_Types --
578 ------------------------------
580 -- Note: right now there is only one auxiliary type to be generated,
581 -- namely the enumeration type for the compression sequences if used.
583 procedure Generate_Auxiliary_Types is
584 Loc : constant Source_Ptr := Sloc (Cunit (Current_Sem_Unit));
585 E : Elmt;
586 Code : Entity_Id;
587 Lit : Entity_Id;
588 Start : Natural;
589 Ptr : Natural;
590 Discard : List_Id;
592 Literal_List : List_Id := New_List;
593 -- Gathers the list of literals for the declaration
595 procedure Output_Literal;
596 -- Adds suffix of form Xnnn to name in Name_Buffer, where nnn is
597 -- a serial number that is one greater on each call, and then
598 -- builds an enumeration literal and adds it to the literal list.
600 Serial : Nat := 0;
601 -- Current serial number
603 procedure Output_Literal is
604 begin
605 Serial := Serial + 1;
606 Add_Char_To_Name_Buffer ('X');
607 Add_Nat_To_Name_Buffer (Serial);
609 Lit :=
610 Make_Defining_Identifier (Loc,
611 Chars => Name_Find);
612 Set_Has_Qualified_Name (Lit, True);
613 Append (Lit, Literal_List);
614 end Output_Literal;
616 -- Start of processing for Auxiliary_Types
618 begin
619 E := CDN.Get_First;
620 if E.S /= null then
621 while E.S /= null loop
623 -- We have E.S a String_Ptr that contains a string of the form:
625 -- b__c__d
627 -- In E.W is a 32-bit word representing the hash value
629 -- Our mission is to construct a type
631 -- type XChhhhhhhh is (b,c,d);
633 -- where hhhhhhhh is the 8 hex digits of the E.W value.
634 -- and append this type declaration to the result list
636 Name_Buffer (1) := 'X';
637 Name_Buffer (2) := 'C';
638 Put_Hex (E.W, 3);
639 Name_Len := 10;
640 Output_Literal;
642 Start := E.S'First;
643 Ptr := E.S'First;
644 while Ptr <= E.S'Last loop
645 if Ptr = E.S'Last
646 or else Double_Underscore (E.S.all, Ptr + 1)
647 then
648 Name_Len := Ptr - Start + 1;
649 Name_Buffer (1 .. Name_Len) := E.S (Start .. Ptr);
650 Output_Literal;
651 Start := Ptr + 3;
652 Ptr := Start;
653 else
654 Ptr := Ptr + 1;
655 end if;
656 end loop;
658 E := CDN.Get_Next;
659 end loop;
661 Name_Buffer (1) := 'X';
662 Name_Buffer (2) := 'C';
663 Name_Len := 2;
665 Code :=
666 Make_Defining_Identifier (Loc,
667 Chars => Name_Find);
668 Set_Has_Qualified_Name (Code, True);
670 Insert_Library_Level_Action (
671 Make_Full_Type_Declaration (Loc,
672 Defining_Identifier => Code,
673 Type_Definition =>
674 Make_Enumeration_Type_Definition (Loc,
675 Literals => Literal_List)));
677 -- We have to manually freeze this entity, since it is inserted
678 -- very late on into the tree, and otherwise will not be frozen.
679 -- No freeze actions are generated, so we can discard the result.
681 Discard := Freeze_Entity (Code, Loc);
682 end if;
683 end Generate_Auxiliary_Types;
685 ----------------------
686 -- Get_Encoded_Name --
687 ----------------------
689 -- Note: see spec for details on encodings
691 procedure Get_Encoded_Name (E : Entity_Id) is
692 Has_Suffix : Boolean;
694 begin
695 Get_Name_String (Chars (E));
697 -- Nothing to do if we do not have a type
699 if not Is_Type (E)
701 -- Or if this is an enumeration base type
703 or else (Is_Enumeration_Type (E)
704 and then E = Base_Type (E))
706 -- Or if this is a dummy type for a renaming
708 or else (Name_Len >= 3 and then
709 Name_Buffer (Name_Len - 2 .. Name_Len) = "_XR")
711 or else (Name_Len >= 4 and then
712 (Name_Buffer (Name_Len - 3 .. Name_Len) = "_XRE"
713 or else
714 Name_Buffer (Name_Len - 3 .. Name_Len) = "_XRP"))
716 -- For all these cases, just return the name unchanged
718 then
719 Name_Buffer (Name_Len + 1) := ASCII.Nul;
720 return;
721 end if;
723 Has_Suffix := True;
725 -- Fixed-point case
727 if Is_Fixed_Point_Type (E) then
728 Get_External_Name_With_Suffix (E, "XF_");
729 Add_Real_To_Buffer (Delta_Value (E));
731 if Small_Value (E) /= Delta_Value (E) then
732 Add_Str_To_Name_Buffer ("_");
733 Add_Real_To_Buffer (Small_Value (E));
734 end if;
736 -- Vax floating-point case
738 elsif Vax_Float (E) then
740 if Digits_Value (Base_Type (E)) = 6 then
741 Get_External_Name_With_Suffix (E, "XFF");
743 elsif Digits_Value (Base_Type (E)) = 9 then
744 Get_External_Name_With_Suffix (E, "XFF");
746 else
747 pragma Assert (Digits_Value (Base_Type (E)) = 15);
748 Get_External_Name_With_Suffix (E, "XFG");
749 end if;
751 -- Discrete case where bounds do not match size
753 elsif Is_Discrete_Type (E)
754 and then not Bounds_Match_Size (E)
755 then
756 if Has_Biased_Representation (E) then
757 Get_External_Name_With_Suffix (E, "XB");
758 else
759 Get_External_Name_With_Suffix (E, "XD");
760 end if;
762 declare
763 Lo : constant Node_Id := Type_Low_Bound (E);
764 Hi : constant Node_Id := Type_High_Bound (E);
766 Lo_Stat : constant Boolean := Is_OK_Static_Expression (Lo);
767 Hi_Stat : constant Boolean := Is_OK_Static_Expression (Hi);
769 Lo_Discr : constant Boolean :=
770 Nkind (Lo) = N_Identifier
771 and then
772 Ekind (Entity (Lo)) = E_Discriminant;
774 Hi_Discr : constant Boolean :=
775 Nkind (Hi) = N_Identifier
776 and then
777 Ekind (Entity (Hi)) = E_Discriminant;
779 Lo_Encode : constant Boolean := Lo_Stat or Lo_Discr;
780 Hi_Encode : constant Boolean := Hi_Stat or Hi_Discr;
782 begin
783 if Lo_Encode or Hi_Encode then
784 if Lo_Encode then
785 if Hi_Encode then
786 Add_Str_To_Name_Buffer ("LU_");
787 else
788 Add_Str_To_Name_Buffer ("L_");
789 end if;
790 else
791 Add_Str_To_Name_Buffer ("U_");
792 end if;
794 if Lo_Stat then
795 Add_Uint_To_Buffer (Expr_Rep_Value (Lo));
796 elsif Lo_Discr then
797 Get_Name_String_And_Append (Chars (Entity (Lo)));
798 end if;
800 if Lo_Encode and Hi_Encode then
801 Add_Str_To_Name_Buffer ("__");
802 end if;
804 if Hi_Stat then
805 Add_Uint_To_Buffer (Expr_Rep_Value (Hi));
806 elsif Hi_Discr then
807 Get_Name_String_And_Append (Chars (Entity (Hi)));
808 end if;
809 end if;
810 end;
812 -- For all other cases, the encoded name is the normal type name
814 else
815 Has_Suffix := False;
816 Get_External_Name (E, Has_Suffix);
817 end if;
819 if Debug_Flag_B and then Has_Suffix then
820 Write_Str ("**** type ");
821 Write_Name (Chars (E));
822 Write_Str (" is encoded as ");
823 Write_Str (Name_Buffer (1 .. Name_Len));
824 Write_Eol;
825 end if;
827 Name_Buffer (Name_Len + 1) := ASCII.NUL;
828 end Get_Encoded_Name;
830 -------------------
831 -- Get_Entity_Id --
832 -------------------
834 function Get_Entity_Id (External_Name : String) return Entity_Id is
835 begin
836 return Empty;
837 end Get_Entity_Id;
839 -----------------------
840 -- Get_External_Name --
841 -----------------------
843 procedure Get_External_Name (Entity : Entity_Id; Has_Suffix : Boolean)
845 E : Entity_Id := Entity;
846 Kind : Entity_Kind;
848 procedure Get_Qualified_Name_And_Append (Entity : Entity_Id);
849 -- Appends fully qualified name of given entity to Name_Buffer
851 -----------------------------------
852 -- Get_Qualified_Name_And_Append --
853 -----------------------------------
855 procedure Get_Qualified_Name_And_Append (Entity : Entity_Id) is
856 begin
857 -- If the entity is a compilation unit, its scope is Standard,
858 -- there is no outer scope, and the no further qualification
859 -- is required.
861 -- If the front end has already computed a fully qualified name,
862 -- then it is also the case that no further qualification is
863 -- required
865 if Present (Scope (Scope (Entity)))
866 and then not Has_Fully_Qualified_Name (Entity)
867 then
868 Get_Qualified_Name_And_Append (Scope (Entity));
869 Add_Str_To_Name_Buffer ("__");
870 end if;
872 Get_Name_String_And_Append (Chars (Entity));
873 end Get_Qualified_Name_And_Append;
875 -- Start of processing for Get_External_Name
877 begin
878 Name_Len := 0;
880 -- If this is a child unit, we want the child
882 if Nkind (E) = N_Defining_Program_Unit_Name then
883 E := Defining_Identifier (Entity);
884 end if;
886 Kind := Ekind (E);
888 -- Case of interface name being used
890 if (Kind = E_Procedure or else
891 Kind = E_Function or else
892 Kind = E_Constant or else
893 Kind = E_Variable or else
894 Kind = E_Exception)
895 and then Present (Interface_Name (E))
896 and then No (Address_Clause (E))
897 and then not Has_Suffix
898 then
899 -- The following code needs explanation ???
901 if Convention (E) = Convention_Stdcall
902 and then Ekind (E) = E_Variable
903 then
904 Add_Str_To_Name_Buffer ("_imp__");
905 end if;
907 Add_String_To_Name_Buffer (Strval (Interface_Name (E)));
909 -- All other cases besides the interface name case
911 else
912 -- If this is a library level subprogram (i.e. a subprogram that is a
913 -- compilation unit other than a subunit), then we prepend _ada_ to
914 -- ensure distinctions required as described in the spec.
915 -- Check explicitly for child units, because those are not flagged
916 -- as Compilation_Units by lib. Should they be ???
918 if Is_Subprogram (E)
919 and then (Is_Compilation_Unit (E) or Is_Child_Unit (E))
920 and then not Has_Suffix
921 then
922 Add_Str_To_Name_Buffer ("_ada_");
923 end if;
925 -- If the entity is a subprogram instance that is not a compilation
926 -- unit, generate the name of the original Ada entity, which is the
927 -- one gdb needs.
929 if Is_Generic_Instance (E)
930 and then Is_Subprogram (E)
931 and then not Is_Compilation_Unit (Scope (E))
932 then
933 E := Related_Instance (Scope (E));
934 end if;
936 Get_Qualified_Name_And_Append (E);
938 if Has_Homonym (E) then
939 declare
940 H : Entity_Id := Homonym (E);
941 Nr : Nat := 1;
943 begin
944 while Present (H) loop
945 if (Scope (H) = Scope (E)) then
946 Nr := Nr + 1;
947 end if;
949 H := Homonym (H);
950 end loop;
952 if Nr > 1 then
953 if No_Dollar_In_Label then
954 Add_Str_To_Name_Buffer ("__");
955 else
956 Add_Char_To_Name_Buffer ('$');
957 end if;
959 Add_Nat_To_Name_Buffer (Nr);
960 end if;
961 end;
962 end if;
963 end if;
965 Name_Buffer (Name_Len + 1) := ASCII.Nul;
966 end Get_External_Name;
968 -----------------------------------
969 -- Get_External_Name_With_Suffix --
970 -----------------------------------
972 procedure Get_External_Name_With_Suffix
973 (Entity : Entity_Id;
974 Suffix : String)
976 Has_Suffix : constant Boolean := (Suffix /= "");
977 begin
978 Get_External_Name (Entity, Has_Suffix);
980 if Has_Suffix then
981 Add_Str_To_Name_Buffer ("___");
982 Add_Str_To_Name_Buffer (Suffix);
984 Name_Buffer (Name_Len + 1) := ASCII.Nul;
985 end if;
986 end Get_External_Name_With_Suffix;
988 --------------------------
989 -- Get_Variant_Encoding --
990 --------------------------
992 procedure Get_Variant_Encoding (V : Node_Id) is
993 Choice : Node_Id;
995 procedure Choice_Val (Typ : Character; Choice : Node_Id);
996 -- Output encoded value for a single choice value. Typ is the key
997 -- character ('S', 'F', or 'T') that precedes the choice value.
999 ----------------
1000 -- Choice_Val --
1001 ----------------
1003 procedure Choice_Val (Typ : Character; Choice : Node_Id) is
1004 begin
1005 Add_Char_To_Name_Buffer (Typ);
1007 if Nkind (Choice) = N_Integer_Literal then
1008 Add_Uint_To_Buffer (Intval (Choice));
1010 -- Character literal with no entity present (this is the case
1011 -- Standard.Character or Standard.Wide_Character as root type)
1013 elsif Nkind (Choice) = N_Character_Literal
1014 and then No (Entity (Choice))
1015 then
1016 Add_Uint_To_Buffer
1017 (UI_From_Int (Int (Char_Literal_Value (Choice))));
1019 else
1020 declare
1021 Ent : constant Entity_Id := Entity (Choice);
1023 begin
1024 if Ekind (Ent) = E_Enumeration_Literal then
1025 Add_Uint_To_Buffer (Enumeration_Rep (Ent));
1027 else
1028 pragma Assert (Ekind (Ent) = E_Constant);
1029 Choice_Val (Typ, Constant_Value (Ent));
1030 end if;
1031 end;
1032 end if;
1033 end Choice_Val;
1035 -- Start of processing for Get_Variant_Encoding
1037 begin
1038 Name_Len := 0;
1040 Choice := First (Discrete_Choices (V));
1041 while Present (Choice) loop
1042 if Nkind (Choice) = N_Others_Choice then
1043 Add_Char_To_Name_Buffer ('O');
1045 elsif Nkind (Choice) = N_Range then
1046 Choice_Val ('R', Low_Bound (Choice));
1047 Choice_Val ('T', High_Bound (Choice));
1049 elsif Is_Entity_Name (Choice)
1050 and then Is_Type (Entity (Choice))
1051 then
1052 Choice_Val ('R', Type_Low_Bound (Entity (Choice)));
1053 Choice_Val ('T', Type_High_Bound (Entity (Choice)));
1055 elsif Nkind (Choice) = N_Subtype_Indication then
1056 declare
1057 Rang : constant Node_Id :=
1058 Range_Expression (Constraint (Choice));
1059 begin
1060 Choice_Val ('R', Low_Bound (Rang));
1061 Choice_Val ('T', High_Bound (Rang));
1062 end;
1064 else
1065 Choice_Val ('S', Choice);
1066 end if;
1068 Next (Choice);
1069 end loop;
1071 Name_Buffer (Name_Len + 1) := ASCII.NUL;
1073 if Debug_Flag_B then
1074 declare
1075 VP : constant Node_Id := Parent (V); -- Variant_Part
1076 CL : constant Node_Id := Parent (VP); -- Component_List
1077 RD : constant Node_Id := Parent (CL); -- Record_Definition
1078 FT : constant Node_Id := Parent (RD); -- Full_Type_Declaration
1080 begin
1081 Write_Str ("**** variant for type ");
1082 Write_Name (Chars (Defining_Identifier (FT)));
1083 Write_Str (" is encoded as ");
1084 Write_Str (Name_Buffer (1 .. Name_Len));
1085 Write_Eol;
1086 end;
1087 end if;
1088 end Get_Variant_Encoding;
1090 ---------------------------------
1091 -- Make_Packed_Array_Type_Name --
1092 ---------------------------------
1094 function Make_Packed_Array_Type_Name
1095 (Typ : Entity_Id;
1096 Csize : Uint)
1097 return Name_Id
1099 begin
1100 Get_Name_String (Chars (Typ));
1101 Add_Str_To_Name_Buffer ("___XP");
1102 Add_Uint_To_Buffer (Csize);
1103 return Name_Find;
1104 end Make_Packed_Array_Type_Name;
1106 ------------------------------
1107 -- Prepend_String_To_Buffer --
1108 ------------------------------
1110 procedure Prepend_String_To_Buffer (S : String) is
1111 N : constant Integer := S'Length;
1113 begin
1114 Name_Buffer (1 + N .. Name_Len + N) := Name_Buffer (1 .. Name_Len);
1115 Name_Buffer (1 .. N) := S;
1116 Name_Len := Name_Len + N;
1117 end Prepend_String_To_Buffer;
1119 ----------------------------
1120 -- Prepend_Uint_To_Buffer --
1121 ----------------------------
1123 procedure Prepend_Uint_To_Buffer (U : Uint) is
1124 begin
1125 if U < 0 then
1126 Prepend_String_To_Buffer ("m");
1127 Prepend_Uint_To_Buffer (-U);
1128 else
1129 UI_Image (U, Decimal);
1130 Prepend_String_To_Buffer (UI_Image_Buffer (1 .. UI_Image_Length));
1131 end if;
1132 end Prepend_Uint_To_Buffer;
1134 -------------
1135 -- Put_Hex --
1136 -------------
1138 procedure Put_Hex (W : Word; N : Natural) is
1139 Hex : constant array (Word range 0 .. 15) of Character :=
1140 "0123456789abcdef";
1142 Cod : Word;
1144 begin
1145 Cod := W;
1146 for J in reverse N .. N + 7 loop
1147 Name_Buffer (J) := Hex (Cod and 16#F#);
1148 Cod := Cod / 16;
1149 end loop;
1150 end Put_Hex;
1152 ------------------------------
1153 -- Qualify_All_Entity_Names --
1154 ------------------------------
1156 procedure Qualify_All_Entity_Names is
1157 E : Entity_Id;
1158 Ent : Entity_Id;
1160 begin
1161 for J in Name_Qualify_Units.First .. Name_Qualify_Units.Last loop
1162 E := Defining_Entity (Name_Qualify_Units.Table (J));
1163 Qualify_Entity_Name (E);
1165 Ent := First_Entity (E);
1166 while Present (Ent) loop
1167 Qualify_Entity_Name (Ent);
1168 Next_Entity (Ent);
1170 -- There are odd cases where Last_Entity (E) = E. This happens
1171 -- in the case of renaming of packages. This test avoids getting
1172 -- stuck in such cases.
1174 exit when Ent = E;
1175 end loop;
1176 end loop;
1178 -- Second loop compresses any names that need compressing
1180 for J in Name_Qualify_Units.First .. Name_Qualify_Units.Last loop
1181 E := Defining_Entity (Name_Qualify_Units.Table (J));
1182 Compress_Debug_Name (E);
1184 Ent := First_Entity (E);
1185 while Present (Ent) loop
1186 Compress_Debug_Name (Ent);
1187 Next_Entity (Ent);
1188 exit when Ent = E;
1189 end loop;
1190 end loop;
1191 end Qualify_All_Entity_Names;
1193 -------------------------
1194 -- Qualify_Entity_Name --
1195 -------------------------
1197 procedure Qualify_Entity_Name (Ent : Entity_Id) is
1199 Full_Qualify_Name : String (1 .. Name_Buffer'Length);
1200 Full_Qualify_Len : Natural := 0;
1201 -- Used to accumulate fully qualified name of subprogram
1203 procedure Fully_Qualify_Name (E : Entity_Id);
1204 -- Used to qualify a subprogram or type name, where full
1205 -- qualification up to Standard is always used. Name is set
1206 -- in Full_Qualify_Name with the length in Full_Qualify_Len.
1207 -- Note that this routine does not prepend the _ada_ string
1208 -- required for library subprograms (this is done in the back end).
1210 function Is_BNPE (S : Entity_Id) return Boolean;
1211 -- Determines if S is a BNPE, i.e. Body-Nested Package Entity, which
1212 -- is defined to be a package which is immediately nested within a
1213 -- package body.
1215 function Qualify_Needed (S : Entity_Id) return Boolean;
1216 -- Given a scope, determines if the scope is to be included in the
1217 -- fully qualified name, True if so, False if not.
1219 procedure Set_BNPE_Suffix (E : Entity_Id);
1220 -- Recursive routine to append the BNPE qualification suffix. Works
1221 -- from right to left with E being the current entity in the list.
1222 -- The result does NOT have the trailing n's and trailing b stripped.
1223 -- The caller must do this required stripping.
1225 procedure Set_Entity_Name (E : Entity_Id);
1226 -- Internal recursive routine that does most of the work. This routine
1227 -- leaves the result sitting in Name_Buffer and Name_Len.
1229 BNPE_Suffix_Needed : Boolean := False;
1230 -- Set true if a body-nested package entity suffix is required
1232 Save_Chars : constant Name_Id := Chars (Ent);
1233 -- Save original name
1235 ------------------------
1236 -- Fully_Qualify_Name --
1237 ------------------------
1239 procedure Fully_Qualify_Name (E : Entity_Id) is
1240 Discard : Boolean := False;
1242 begin
1243 -- If this we are qualifying entities local to a generic
1244 -- instance, use the name of the original instantiation,
1245 -- not that of the anonymous subprogram in the wrapper
1246 -- package, so that gdb doesn't have to know about these.
1248 if Is_Generic_Instance (E)
1249 and then Is_Subprogram (E)
1250 and then not Comes_From_Source (E)
1251 and then not Is_Compilation_Unit (Scope (E))
1252 then
1253 Fully_Qualify_Name (Related_Instance (Scope (E)));
1254 return;
1255 end if;
1257 -- If we reached fully qualified name, then just copy it
1259 if Has_Fully_Qualified_Name (E) then
1260 Get_Name_String (Chars (E));
1261 Strip_BNPE_Suffix (Discard);
1262 Full_Qualify_Name (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
1263 Full_Qualify_Len := Name_Len;
1264 Set_Has_Fully_Qualified_Name (Ent);
1266 -- Case of non-fully qualified name
1268 else
1269 if Scope (E) = Standard_Standard then
1270 Set_Has_Fully_Qualified_Name (Ent);
1271 else
1272 Fully_Qualify_Name (Scope (E));
1273 Full_Qualify_Name (Full_Qualify_Len + 1) := '_';
1274 Full_Qualify_Name (Full_Qualify_Len + 2) := '_';
1275 Full_Qualify_Len := Full_Qualify_Len + 2;
1276 end if;
1278 if Has_Qualified_Name (E) then
1279 Get_Unqualified_Name_String (Chars (E));
1280 else
1281 Get_Name_String (Chars (E));
1282 end if;
1284 Full_Qualify_Name
1285 (Full_Qualify_Len + 1 .. Full_Qualify_Len + Name_Len) :=
1286 Name_Buffer (1 .. Name_Len);
1287 Full_Qualify_Len := Full_Qualify_Len + Name_Len;
1288 end if;
1290 if Is_BNPE (E) then
1291 BNPE_Suffix_Needed := True;
1292 end if;
1293 end Fully_Qualify_Name;
1295 -------------
1296 -- Is_BNPE --
1297 -------------
1299 function Is_BNPE (S : Entity_Id) return Boolean is
1300 begin
1301 return
1302 Ekind (S) = E_Package
1303 and then Is_Package_Body_Entity (S);
1304 end Is_BNPE;
1306 --------------------
1307 -- Qualify_Needed --
1308 --------------------
1310 function Qualify_Needed (S : Entity_Id) return Boolean is
1311 begin
1312 -- If we got all the way to Standard, then we have certainly
1313 -- fully qualified the name, so set the flag appropriately,
1314 -- and then return False, since we are most certainly done!
1316 if S = Standard_Standard then
1317 Set_Has_Fully_Qualified_Name (Ent, True);
1318 return False;
1320 -- Otherwise figure out if further qualification is required
1322 else
1323 return
1324 Is_Subprogram (Ent)
1325 or else
1326 Ekind (Ent) = E_Subprogram_Body
1327 or else
1328 (Ekind (S) /= E_Block
1329 and then not Is_Dynamic_Scope (S));
1330 end if;
1331 end Qualify_Needed;
1333 ---------------------
1334 -- Set_BNPE_Suffix --
1335 ---------------------
1337 procedure Set_BNPE_Suffix (E : Entity_Id) is
1338 S : constant Entity_Id := Scope (E);
1340 begin
1341 if Qualify_Needed (S) then
1342 Set_BNPE_Suffix (S);
1344 if Is_BNPE (E) then
1345 Add_Char_To_Name_Buffer ('b');
1346 else
1347 Add_Char_To_Name_Buffer ('n');
1348 end if;
1350 else
1351 Add_Char_To_Name_Buffer ('X');
1352 end if;
1354 end Set_BNPE_Suffix;
1356 ---------------------
1357 -- Set_Entity_Name --
1358 ---------------------
1360 procedure Set_Entity_Name (E : Entity_Id) is
1361 S : constant Entity_Id := Scope (E);
1363 begin
1364 -- If we reach an already qualified name, just take the encoding
1365 -- except that we strip the package body suffixes, since these
1366 -- will be separately put on later.
1368 if Has_Qualified_Name (E) then
1369 Get_Name_String_And_Append (Chars (E));
1370 Strip_BNPE_Suffix (BNPE_Suffix_Needed);
1372 -- If the top level name we are adding is itself fully
1373 -- qualified, then that means that the name that we are
1374 -- preparing for the Fully_Qualify_Name call will also
1375 -- generate a fully qualified name.
1377 if Has_Fully_Qualified_Name (E) then
1378 Set_Has_Fully_Qualified_Name (Ent);
1379 end if;
1381 -- Case where upper level name is not encoded yet
1383 else
1384 -- Recurse if further qualification required
1386 if Qualify_Needed (S) then
1387 Set_Entity_Name (S);
1388 Add_Str_To_Name_Buffer ("__");
1389 end if;
1391 -- Otherwise get name and note if it is a NPBE
1393 Get_Name_String_And_Append (Chars (E));
1395 if Is_BNPE (E) then
1396 BNPE_Suffix_Needed := True;
1397 end if;
1398 end if;
1399 end Set_Entity_Name;
1401 -- Start of processing for Qualify_Entity_Name
1403 begin
1404 if Has_Qualified_Name (Ent) then
1405 return;
1407 -- Here is where we create the proper link for renaming
1409 elsif Ekind (Ent) = E_Enumeration_Literal
1410 and then Present (Debug_Renaming_Link (Ent))
1411 then
1412 Set_Entity_Name (Debug_Renaming_Link (Ent));
1413 Get_Name_String (Chars (Ent));
1414 Prepend_String_To_Buffer
1415 (Get_Name_String (Chars (Debug_Renaming_Link (Ent))));
1416 Set_Chars (Ent, Name_Enter);
1417 Set_Has_Qualified_Name (Ent);
1418 return;
1420 elsif Is_Subprogram (Ent)
1421 or else Ekind (Ent) = E_Subprogram_Body
1422 or else Is_Type (Ent)
1423 then
1424 Fully_Qualify_Name (Ent);
1425 Name_Len := Full_Qualify_Len;
1426 Name_Buffer (1 .. Name_Len) := Full_Qualify_Name (1 .. Name_Len);
1428 elsif Qualify_Needed (Scope (Ent)) then
1429 Name_Len := 0;
1430 Set_Entity_Name (Ent);
1432 else
1433 Set_Has_Qualified_Name (Ent);
1434 return;
1435 end if;
1437 -- Fall through with a fully qualified name in Name_Buffer/Name_Len
1439 -- Add body-nested package suffix if required
1441 if BNPE_Suffix_Needed
1442 and then Ekind (Ent) /= E_Enumeration_Literal
1443 then
1444 Set_BNPE_Suffix (Ent);
1446 -- Strip trailing n's and last trailing b as required. note that
1447 -- we know there is at least one b, or no suffix would be generated.
1449 while Name_Buffer (Name_Len) = 'n' loop
1450 Name_Len := Name_Len - 1;
1451 end loop;
1453 Name_Len := Name_Len - 1;
1454 end if;
1456 Set_Chars (Ent, Name_Enter);
1457 Set_Has_Qualified_Name (Ent);
1459 if Debug_Flag_BB then
1460 Write_Str ("*** ");
1461 Write_Name (Save_Chars);
1462 Write_Str (" qualified as ");
1463 Write_Name (Chars (Ent));
1464 Write_Eol;
1465 end if;
1466 end Qualify_Entity_Name;
1468 --------------------------
1469 -- Qualify_Entity_Names --
1470 --------------------------
1472 procedure Qualify_Entity_Names (N : Node_Id) is
1473 begin
1474 Name_Qualify_Units.Append (N);
1475 end Qualify_Entity_Names;
1477 --------------------------------
1478 -- Save_Unitname_And_Use_List --
1479 --------------------------------
1481 procedure Save_Unitname_And_Use_List
1482 (Main_Unit_Node : Node_Id;
1483 Main_Kind : Node_Kind)
1485 INITIAL_NAME_LENGTH : constant := 1024;
1487 Item : Node_Id;
1488 Pack_Name : Node_Id;
1490 Unit_Spec : Node_Id := 0;
1491 Unit_Body : Node_Id := 0;
1493 Main_Name : String_Id;
1494 -- Fully qualified name of Main Unit
1496 Unit_Name : String_Id;
1497 -- Name of unit specified in a Use clause
1499 Spec_Unit_Index : Source_File_Index;
1500 Spec_File_Name : File_Name_Type := No_File;
1502 Body_Unit_Index : Source_File_Index;
1503 Body_File_Name : File_Name_Type := No_File;
1505 type String_Ptr is access all String;
1507 Spec_File_Name_Str : String_Ptr;
1508 Body_File_Name_Str : String_Ptr;
1510 type Label is record
1511 Label_Name : String_Ptr;
1512 Name_Length : Integer;
1513 Pos : Integer;
1514 end record;
1516 Spec_Label : Label;
1517 Body_Label : Label;
1519 procedure Initialize (L : out Label);
1520 -- Initialize label
1522 procedure Append (L : in out Label; Ch : Character);
1523 -- Append character to label
1525 procedure Append (L : in out Label; Str : String);
1526 -- Append string to label
1528 procedure Append_Name (L : in out Label; Unit_Name : String_Id);
1529 -- Append name to label
1531 function Sufficient_Space
1532 (L : Label;
1533 Unit_Name : String_Id)
1534 return Boolean;
1535 -- Does sufficient space exist to append another name?
1537 procedure Append (L : in out Label; Str : String) is
1538 begin
1539 L.Label_Name (L.Pos + 1 .. L.Pos + Str'Length) := Str;
1540 L.Pos := L.Pos + Str'Length;
1541 end Append;
1543 procedure Append (L : in out Label; Ch : Character) is
1544 begin
1545 L.Pos := L.Pos + 1;
1546 L.Label_Name (L.Pos) := Ch;
1547 end Append;
1549 procedure Append_Name (L : in out Label; Unit_Name : String_Id) is
1550 Char : Char_Code;
1551 Upper_Offset : constant := Character'Pos ('a') - Character'Pos ('A');
1553 begin
1554 for J in 1 .. String_Length (Unit_Name) loop
1555 Char := Get_String_Char (Unit_Name, J);
1557 if Character'Val (Char) = '.' then
1558 Append (L, "__");
1559 elsif Character'Val (Char) in 'A' .. 'Z' then
1560 Append (L, Character'Val (Char + Upper_Offset));
1561 elsif Char /= 0 then
1562 Append (L, Character'Val (Char));
1563 end if;
1564 end loop;
1565 end Append_Name;
1567 procedure Initialize (L : out Label) is
1568 begin
1569 L.Name_Length := INITIAL_NAME_LENGTH;
1570 L.Pos := 0;
1571 L.Label_Name := new String (1 .. L.Name_Length);
1572 end Initialize;
1574 function Sufficient_Space
1575 (L : Label;
1576 Unit_Name : String_Id)
1577 return Boolean
1579 Len : Integer := Integer (String_Length (Unit_Name)) + 1;
1581 begin
1582 for J in 1 .. String_Length (Unit_Name) loop
1583 if Character'Val (Get_String_Char (Unit_Name, J)) = '.' then
1584 Len := Len + 1;
1585 end if;
1586 end loop;
1588 return L.Pos + Len < L.Name_Length;
1589 end Sufficient_Space;
1591 -- Start of processing for Save_Unitname_And_Use_List
1593 begin
1594 Initialize (Spec_Label);
1595 Initialize (Body_Label);
1597 case Main_Kind is
1598 when N_Package_Declaration =>
1599 Main_Name := Full_Qualified_Name
1600 (Defining_Unit_Name (Specification (Unit (Main_Unit_Node))));
1601 Unit_Spec := Main_Unit_Node;
1602 Append (Spec_Label, "_LPS__");
1603 Append (Body_Label, "_LPB__");
1605 when N_Package_Body =>
1606 Unit_Spec := Corresponding_Spec (Unit (Main_Unit_Node));
1607 Unit_Body := Main_Unit_Node;
1608 Main_Name := Full_Qualified_Name (Unit_Spec);
1609 Append (Spec_Label, "_LPS__");
1610 Append (Body_Label, "_LPB__");
1612 when N_Subprogram_Body =>
1613 Unit_Body := Main_Unit_Node;
1615 if Present (Corresponding_Spec (Unit (Main_Unit_Node))) then
1616 Unit_Spec := Corresponding_Spec (Unit (Main_Unit_Node));
1617 Main_Name := Full_Qualified_Name
1618 (Corresponding_Spec (Unit (Main_Unit_Node)));
1619 else
1620 Main_Name := Full_Qualified_Name
1621 (Defining_Unit_Name (Specification (Unit (Main_Unit_Node))));
1622 end if;
1624 Append (Spec_Label, "_LSS__");
1625 Append (Body_Label, "_LSB__");
1627 when others =>
1628 return;
1629 end case;
1631 Append_Name (Spec_Label, Main_Name);
1632 Append_Name (Body_Label, Main_Name);
1634 -- If we have a body, process it first
1636 if Present (Unit_Body) then
1638 Item := First (Context_Items (Unit_Body));
1640 while Present (Item) loop
1641 if Nkind (Item) = N_Use_Package_Clause then
1642 Pack_Name := First (Names (Item));
1643 while Present (Pack_Name) loop
1644 Unit_Name := Full_Qualified_Name (Entity (Pack_Name));
1646 if Sufficient_Space (Body_Label, Unit_Name) then
1647 Append (Body_Label, '$');
1648 Append_Name (Body_Label, Unit_Name);
1649 end if;
1651 Pack_Name := Next (Pack_Name);
1652 end loop;
1653 end if;
1655 Item := Next (Item);
1656 end loop;
1657 end if;
1659 while Present (Unit_Spec) and then
1660 Nkind (Unit_Spec) /= N_Compilation_Unit
1661 loop
1662 Unit_Spec := Parent (Unit_Spec);
1663 end loop;
1665 if Present (Unit_Spec) then
1667 Item := First (Context_Items (Unit_Spec));
1669 while Present (Item) loop
1670 if Nkind (Item) = N_Use_Package_Clause then
1671 Pack_Name := First (Names (Item));
1672 while Present (Pack_Name) loop
1673 Unit_Name := Full_Qualified_Name (Entity (Pack_Name));
1675 if Sufficient_Space (Spec_Label, Unit_Name) then
1676 Append (Spec_Label, '$');
1677 Append_Name (Spec_Label, Unit_Name);
1678 end if;
1680 if Sufficient_Space (Body_Label, Unit_Name) then
1681 Append (Body_Label, '$');
1682 Append_Name (Body_Label, Unit_Name);
1683 end if;
1685 Pack_Name := Next (Pack_Name);
1686 end loop;
1687 end if;
1689 Item := Next (Item);
1690 end loop;
1691 end if;
1693 if Present (Unit_Spec) then
1694 Append (Spec_Label, Character'Val (0));
1695 Spec_Unit_Index := Source_Index (Get_Cunit_Unit_Number (Unit_Spec));
1696 Spec_File_Name := Full_File_Name (Spec_Unit_Index);
1697 Get_Name_String (Spec_File_Name);
1698 Spec_File_Name_Str := new String (1 .. Name_Len + 1);
1699 Spec_File_Name_Str (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
1700 Spec_File_Name_Str (Name_Len + 1) := Character'Val (0);
1701 Spec_Filename := Spec_File_Name_Str (1)'Unrestricted_Access;
1702 Spec_Context_List :=
1703 Spec_Label.Label_Name.all (1)'Unrestricted_Access;
1704 end if;
1706 if Present (Unit_Body) then
1707 Append (Body_Label, Character'Val (0));
1708 Body_Unit_Index := Source_Index (Get_Cunit_Unit_Number (Unit_Body));
1709 Body_File_Name := Full_File_Name (Body_Unit_Index);
1710 Get_Name_String (Body_File_Name);
1711 Body_File_Name_Str := new String (1 .. Name_Len + 1);
1712 Body_File_Name_Str (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
1713 Body_File_Name_Str (Name_Len + 1) := Character'Val (0);
1714 Body_Filename := Body_File_Name_Str (1)'Unrestricted_Access;
1715 Body_Context_List :=
1716 Body_Label.Label_Name.all (1)'Unrestricted_Access;
1717 end if;
1719 end Save_Unitname_And_Use_List;
1721 ---------
1722 -- SEq --
1723 ---------
1725 function SEq (F1, F2 : String_Ptr) return Boolean is
1726 begin
1727 return F1.all = F2.all;
1728 end SEq;
1730 -----------
1731 -- SHash --
1732 -----------
1734 function SHash (S : String_Ptr) return Hindex is
1735 begin
1736 return Hindex
1737 (Hindex'First + Hindex (CDN_Hash (S.all) mod Hindex'Range_Length));
1738 end SHash;
1740 -----------------------
1741 -- Strip_BNPE_Suffix --
1742 -----------------------
1744 procedure Strip_BNPE_Suffix (Suffix_Found : in out Boolean) is
1745 begin
1746 for J in reverse 2 .. Name_Len loop
1747 if Name_Buffer (J) = 'X' then
1748 Name_Len := J - 1;
1749 Suffix_Found := True;
1750 exit;
1751 end if;
1753 exit when Name_Buffer (J) /= 'b' and then Name_Buffer (J) /= 'n';
1754 end loop;
1755 end Strip_BNPE_Suffix;
1757 end Exp_Dbug;