1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
33 ------------------------------------------------------------------------------
35 -- WARNING: There is a C version of this package. Any changes to this
36 -- source file must be properly reflected in the C header file a-namet.h
37 -- which is created manually from namet.ads and namet.adb.
39 with Debug
; use Debug
;
40 with Output
; use Output
;
41 with Tree_IO
; use Tree_IO
;
42 with Widechar
; use Widechar
;
46 Name_Chars_Reserve
: constant := 5000;
47 Name_Entries_Reserve
: constant := 100;
48 -- The names table is locked during gigi processing, since gigi assumes
49 -- that the table does not move. After returning from gigi, the names
50 -- table is unlocked again, since writing library file information needs
51 -- to generate some extra names. To avoid the inefficiency of always
52 -- reallocating during this second unlocked phase, we reserve a bit of
53 -- extra space before doing the release call.
55 Hash_Num
: constant Int
:= 2**12;
56 -- Number of headers in the hash table. Current hash algorithm is closely
57 -- tailored to this choice, so it can only be changed if a corresponding
58 -- change is made to the hash alogorithm.
60 Hash_Max
: constant Int
:= Hash_Num
- 1;
61 -- Indexes in the hash header table run from 0 to Hash_Num - 1
63 subtype Hash_Index_Type
is Int
range 0 .. Hash_Max
;
64 -- Range of hash index values
66 Hash_Table
: array (Hash_Index_Type
) of Name_Id
;
67 -- The hash table is used to locate existing entries in the names table.
68 -- The entries point to the first names table entry whose hash value
69 -- matches the hash code. Then subsequent names table entries with the
70 -- same hash code value are linked through the Hash_Link fields.
72 -----------------------
73 -- Local Subprograms --
74 -----------------------
76 function Hash
return Hash_Index_Type
;
78 -- Compute hash code for name stored in Name_Buffer (length in Name_Len)
80 procedure Strip_Qualification_And_Suffixes
;
81 -- Given an encoded entity name in Name_Buffer, remove package body
82 -- suffix as described for Strip_Package_Body_Suffix, and also remove
83 -- all qualification, i.e. names followed by two underscores. The
84 -- contents of Name_Buffer is modified by this call, and on return
85 -- Name_Buffer and Name_Len reflect the stripped name.
87 -----------------------------
88 -- Add_Char_To_Name_Buffer --
89 -----------------------------
91 procedure Add_Char_To_Name_Buffer
(C
: Character) is
93 if Name_Len
< Name_Buffer
'Last then
94 Name_Len
:= Name_Len
+ 1;
95 Name_Buffer
(Name_Len
) := C
;
97 end Add_Char_To_Name_Buffer
;
99 ----------------------------
100 -- Add_Nat_To_Name_Buffer --
101 ----------------------------
103 procedure Add_Nat_To_Name_Buffer
(V
: Nat
) is
106 Add_Nat_To_Name_Buffer
(V
/ 10);
109 Add_Char_To_Name_Buffer
(Character'Val (Character'Pos ('0') + V
rem 10));
110 end Add_Nat_To_Name_Buffer
;
112 ----------------------------
113 -- Add_Str_To_Name_Buffer --
114 ----------------------------
116 procedure Add_Str_To_Name_Buffer
(S
: String) is
118 for J
in S
'Range loop
119 Add_Char_To_Name_Buffer
(S
(J
));
121 end Add_Str_To_Name_Buffer
;
127 procedure Finalize
is
128 Max_Chain_Length
: constant := 50;
129 -- Max length of chains for which specific information is output
131 F
: array (Int
range 0 .. Max_Chain_Length
) of Int
;
132 -- N'th entry is number of chains of length N
135 -- Used to compute average number of probes
138 -- Number of symbols in table
143 for J
in F
'Range loop
147 for I
in Hash_Index_Type
loop
148 if Hash_Table
(I
) = No_Name
then
152 Write_Str
("Hash_Table (");
154 Write_Str
(") has ");
165 while N
/= No_Name
loop
166 N
:= Name_Entries
.Table
(N
).Hash_Link
;
171 Write_Str
(" entries");
174 if C
< Max_Chain_Length
then
177 F
(Max_Chain_Length
) := F
(Max_Chain_Length
) + 1;
182 while N
/= No_Name
loop
183 S
:= Name_Entries
.Table
(N
).Name_Chars_Index
;
186 for J
in 1 .. Name_Entries
.Table
(N
).Name_Len
loop
187 Write_Char
(Name_Chars
.Table
(S
+ Int
(J
)));
191 N
:= Name_Entries
.Table
(N
).Hash_Link
;
199 for I
in Int
range 0 .. Max_Chain_Length
loop
201 Write_Str
("Number of hash chains of length ");
209 if I
= Max_Chain_Length
then
210 Write_Str
(" or greater");
218 Nsyms
:= Nsyms
+ F
(I
);
219 Probes
:= Probes
+ F
(I
) * (1 + I
) * 100;
225 Write_Str
("Average number of probes for lookup = ");
226 Probes
:= Probes
/ Nsyms
;
227 Write_Int
(Probes
/ 200);
229 Probes
:= (Probes
mod 200) / 2;
230 Write_Char
(Character'Val (48 + Probes
/ 10));
231 Write_Char
(Character'Val (48 + Probes
mod 10));
237 -----------------------------
238 -- Get_Decoded_Name_String --
239 -----------------------------
241 procedure Get_Decoded_Name_String
(Id
: Name_Id
) is
246 Get_Name_String
(Id
);
248 -- Quick loop to see if there is anything special to do
256 C
:= Name_Buffer
(P
);
268 -- Here we have at least some encoding that we must decode
270 -- Here we have to decode one or more Uhh or Whhhh sequences
275 New_Buf
: String (1 .. Name_Buffer
'Last);
277 procedure Insert_Character
(C
: Character);
278 -- Insert a new character into output decoded name
280 procedure Copy_One_Character
;
281 -- Copy a character from Name_Buffer to New_Buf. Includes case
282 -- of copying a Uhh or Whhhh sequence and decoding it.
284 function Hex
(N
: Natural) return Natural;
285 -- Scans past N digits using Old pointer and returns hex value
287 procedure Copy_One_Character
is
291 C
:= Name_Buffer
(Old
);
295 Insert_Character
(Character'Val (Hex
(2)));
299 Widechar
.Set_Wide
(Char_Code
(Hex
(4)), New_Buf
, New_Len
);
302 Insert_Character
(Name_Buffer
(Old
));
305 end Copy_One_Character
;
307 function Hex
(N
: Natural) return Natural is
313 C
:= Name_Buffer
(Old
);
316 pragma Assert
(C
in '0' .. '9' or else C
in 'a' .. 'f');
319 T
:= 16 * T
+ Character'Pos (C
) - Character'Pos ('0');
320 else -- C in 'a' .. 'f'
321 T
:= 16 * T
+ Character'Pos (C
) - (Character'Pos ('a') - 10);
328 procedure Insert_Character
(C
: Character) is
330 New_Len
:= New_Len
+ 1;
331 New_Buf
(New_Len
) := C
;
332 end Insert_Character
;
334 -- Actual decoding processing
340 -- Loop through characters of name
342 while Old
<= Name_Len
loop
344 -- Case of character literal, put apostrophes around character
346 if Name_Buffer
(Old
) = 'Q' then
348 Insert_Character
(''');
350 Insert_Character
(''');
352 -- Case of operator name
354 elsif Name_Buffer
(Old
) = 'O' then
358 -- This table maps the 2nd and 3rd characters of the name
359 -- into the required output. Two blanks means leave the
362 Map
: constant String :=
363 "ab " & -- Oabs => "abs"
364 "ad+ " & -- Oadd => "+"
365 "an " & -- Oand => "and"
366 "co& " & -- Oconcat => "&"
367 "di/ " & -- Odivide => "/"
368 "eq= " & -- Oeq => "="
369 "ex**" & -- Oexpon => "**"
370 "gt> " & -- Ogt => ">"
371 "ge>=" & -- Oge => ">="
372 "le<=" & -- Ole => "<="
373 "lt< " & -- Olt => "<"
374 "mo " & -- Omod => "mod"
375 "mu* " & -- Omutliply => "*"
376 "ne/=" & -- One => "/="
377 "no " & -- Onot => "not"
378 "or " & -- Oor => "or"
379 "re " & -- Orem => "rem"
380 "su- " & -- Osubtract => "-"
381 "xo "; -- Oxor => "xor"
386 Insert_Character
('"');
388 -- Search the map. Note that this loop must terminate, if
389 -- not we have some kind of internal error, and a constraint
390 -- constraint error may be raised.
394 exit when Name_Buffer
(Old
) = Map
(J
)
395 and then Name_Buffer
(Old
+ 1) = Map
(J
+ 1);
399 -- Special operator name
401 if Map
(J
+ 2) /= ' ' then
402 Insert_Character
(Map
(J
+ 2));
404 if Map
(J
+ 3) /= ' ' then
405 Insert_Character
(Map
(J
+ 3));
408 Insert_Character
('"');
410 -- Skip past original operator name in input
412 while Old
<= Name_Len
413 and then Name_Buffer
(Old
) in 'a' .. 'z'
418 -- For other operator names, leave them in lower case,
419 -- surrounded by apostrophes
422 -- Copy original operator name from input to output
424 while Old
<= Name_Len
425 and then Name_Buffer
(Old
) in 'a' .. 'z'
430 Insert_Character
('"');
434 -- Else copy one character and keep going
441 -- Copy new buffer as result
444 Name_Buffer
(1 .. New_Len
) := New_Buf
(1 .. New_Len
);
447 end Get_Decoded_Name_String
;
449 -------------------------------------------
450 -- Get_Decoded_Name_String_With_Brackets --
451 -------------------------------------------
453 procedure Get_Decoded_Name_String_With_Brackets
(Id
: Name_Id
) is
457 -- Case of operator name, normal decoding is fine
459 if Name_Buffer
(1) = 'O' then
460 Get_Decoded_Name_String
(Id
);
462 -- For character literals, normal decoding is fine
464 elsif Name_Buffer
(1) = 'Q' then
465 Get_Decoded_Name_String
(Id
);
467 -- Only remaining issue is U/W sequences
470 Get_Name_String
(Id
);
473 while P
< Name_Len
loop
474 if Name_Buffer
(P
) = 'U' then
475 for J
in reverse P
+ 3 .. P
+ Name_Len
loop
476 Name_Buffer
(J
+ 3) := Name_Buffer
(J
);
479 Name_Len
:= Name_Len
+ 3;
480 Name_Buffer
(P
+ 3) := Name_Buffer
(P
+ 2);
481 Name_Buffer
(P
+ 2) := Name_Buffer
(P
+ 1);
482 Name_Buffer
(P
) := '[';
483 Name_Buffer
(P
+ 1) := '"';
484 Name_Buffer
(P
+ 4) := '"';
485 Name_Buffer
(P
+ 5) := ']';
488 elsif Name_Buffer
(P
) = 'W' then
489 Name_Buffer
(P
+ 8 .. P
+ Name_Len
+ 5) :=
490 Name_Buffer
(P
+ 5 .. Name_Len
);
491 Name_Buffer
(P
+ 5) := Name_Buffer
(P
+ 4);
492 Name_Buffer
(P
+ 4) := Name_Buffer
(P
+ 3);
493 Name_Buffer
(P
+ 3) := Name_Buffer
(P
+ 2);
494 Name_Buffer
(P
+ 2) := Name_Buffer
(P
+ 1);
495 Name_Buffer
(P
) := '[';
496 Name_Buffer
(P
+ 1) := '"';
497 Name_Buffer
(P
+ 6) := '"';
498 Name_Buffer
(P
+ 7) := ']';
499 Name_Len
:= Name_Len
+ 5;
507 end Get_Decoded_Name_String_With_Brackets
;
509 ---------------------
510 -- Get_Name_String --
511 ---------------------
513 procedure Get_Name_String
(Id
: Name_Id
) is
517 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
519 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
520 Name_Len
:= Natural (Name_Entries
.Table
(Id
).Name_Len
);
522 for J
in 1 .. Name_Len
loop
523 Name_Buffer
(J
) := Name_Chars
.Table
(S
+ Int
(J
));
527 function Get_Name_String
(Id
: Name_Id
) return String is
531 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
532 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
535 R
: String (1 .. Natural (Name_Entries
.Table
(Id
).Name_Len
));
538 for J
in R
'Range loop
539 R
(J
) := Name_Chars
.Table
(S
+ Int
(J
));
546 --------------------------------
547 -- Get_Name_String_And_Append --
548 --------------------------------
550 procedure Get_Name_String_And_Append
(Id
: Name_Id
) is
554 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
556 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
558 for J
in 1 .. Natural (Name_Entries
.Table
(Id
).Name_Len
) loop
559 Name_Len
:= Name_Len
+ 1;
560 Name_Buffer
(Name_Len
) := Name_Chars
.Table
(S
+ Int
(J
));
562 end Get_Name_String_And_Append
;
564 -------------------------
565 -- Get_Name_Table_Byte --
566 -------------------------
568 function Get_Name_Table_Byte
(Id
: Name_Id
) return Byte
is
570 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
571 return Name_Entries
.Table
(Id
).Byte_Info
;
572 end Get_Name_Table_Byte
;
574 -------------------------
575 -- Get_Name_Table_Info --
576 -------------------------
578 function Get_Name_Table_Info
(Id
: Name_Id
) return Int
is
580 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
581 return Name_Entries
.Table
(Id
).Int_Info
;
582 end Get_Name_Table_Info
;
584 -----------------------------------------
585 -- Get_Unqualified_Decoded_Name_String --
586 -----------------------------------------
588 procedure Get_Unqualified_Decoded_Name_String
(Id
: Name_Id
) is
590 Get_Decoded_Name_String
(Id
);
591 Strip_Qualification_And_Suffixes
;
592 end Get_Unqualified_Decoded_Name_String
;
594 ---------------------------------
595 -- Get_Unqualified_Name_String --
596 ---------------------------------
598 procedure Get_Unqualified_Name_String
(Id
: Name_Id
) is
600 Get_Name_String
(Id
);
601 Strip_Qualification_And_Suffixes
;
602 end Get_Unqualified_Name_String
;
608 function Hash
return Hash_Index_Type
is
609 subtype Int_1_12
is Int
range 1 .. 12;
610 -- Used to avoid when others on case jump below
612 Even_Name_Len
: Integer;
613 -- Last even numbered position (used for >12 case)
617 -- Special test for 12 (rather than counting on a when others for the
618 -- case statement below) avoids some Ada compilers converting the case
619 -- statement into successive jumps.
621 -- The case of a name longer than 12 characters is handled by taking
622 -- the first 6 odd numbered characters and the last 6 even numbered
625 if Name_Len
> 12 then
626 Even_Name_Len
:= (Name_Len
) / 2 * 2;
629 Character'Pos (Name_Buffer
(01))) * 2 +
630 Character'Pos (Name_Buffer
(Even_Name_Len
- 10))) * 2 +
631 Character'Pos (Name_Buffer
(03))) * 2 +
632 Character'Pos (Name_Buffer
(Even_Name_Len
- 08))) * 2 +
633 Character'Pos (Name_Buffer
(05))) * 2 +
634 Character'Pos (Name_Buffer
(Even_Name_Len
- 06))) * 2 +
635 Character'Pos (Name_Buffer
(07))) * 2 +
636 Character'Pos (Name_Buffer
(Even_Name_Len
- 04))) * 2 +
637 Character'Pos (Name_Buffer
(09))) * 2 +
638 Character'Pos (Name_Buffer
(Even_Name_Len
- 02))) * 2 +
639 Character'Pos (Name_Buffer
(11))) * 2 +
640 Character'Pos (Name_Buffer
(Even_Name_Len
))) mod Hash_Num
;
643 -- For the cases of 1-12 characters, all characters participate in the
644 -- hash. The positioning is randomized, with the bias that characters
645 -- later on participate fully (i.e. are added towards the right side).
647 case Int_1_12
(Name_Len
) is
651 Character'Pos (Name_Buffer
(1));
655 Character'Pos (Name_Buffer
(1))) * 64 +
656 Character'Pos (Name_Buffer
(2))) mod Hash_Num
;
660 Character'Pos (Name_Buffer
(1))) * 16 +
661 Character'Pos (Name_Buffer
(3))) * 16 +
662 Character'Pos (Name_Buffer
(2))) mod Hash_Num
;
666 Character'Pos (Name_Buffer
(1))) * 8 +
667 Character'Pos (Name_Buffer
(2))) * 8 +
668 Character'Pos (Name_Buffer
(3))) * 8 +
669 Character'Pos (Name_Buffer
(4))) mod Hash_Num
;
673 Character'Pos (Name_Buffer
(4))) * 8 +
674 Character'Pos (Name_Buffer
(1))) * 4 +
675 Character'Pos (Name_Buffer
(3))) * 4 +
676 Character'Pos (Name_Buffer
(5))) * 8 +
677 Character'Pos (Name_Buffer
(2))) mod Hash_Num
;
681 Character'Pos (Name_Buffer
(5))) * 4 +
682 Character'Pos (Name_Buffer
(1))) * 4 +
683 Character'Pos (Name_Buffer
(4))) * 4 +
684 Character'Pos (Name_Buffer
(2))) * 4 +
685 Character'Pos (Name_Buffer
(6))) * 4 +
686 Character'Pos (Name_Buffer
(3))) mod Hash_Num
;
690 Character'Pos (Name_Buffer
(4))) * 4 +
691 Character'Pos (Name_Buffer
(3))) * 4 +
692 Character'Pos (Name_Buffer
(1))) * 4 +
693 Character'Pos (Name_Buffer
(2))) * 2 +
694 Character'Pos (Name_Buffer
(5))) * 2 +
695 Character'Pos (Name_Buffer
(7))) * 2 +
696 Character'Pos (Name_Buffer
(6))) mod Hash_Num
;
700 Character'Pos (Name_Buffer
(2))) * 4 +
701 Character'Pos (Name_Buffer
(1))) * 4 +
702 Character'Pos (Name_Buffer
(3))) * 2 +
703 Character'Pos (Name_Buffer
(5))) * 2 +
704 Character'Pos (Name_Buffer
(7))) * 2 +
705 Character'Pos (Name_Buffer
(6))) * 2 +
706 Character'Pos (Name_Buffer
(4))) * 2 +
707 Character'Pos (Name_Buffer
(8))) mod Hash_Num
;
711 Character'Pos (Name_Buffer
(2))) * 4 +
712 Character'Pos (Name_Buffer
(1))) * 4 +
713 Character'Pos (Name_Buffer
(3))) * 4 +
714 Character'Pos (Name_Buffer
(4))) * 2 +
715 Character'Pos (Name_Buffer
(8))) * 2 +
716 Character'Pos (Name_Buffer
(7))) * 2 +
717 Character'Pos (Name_Buffer
(5))) * 2 +
718 Character'Pos (Name_Buffer
(6))) * 2 +
719 Character'Pos (Name_Buffer
(9))) mod Hash_Num
;
723 Character'Pos (Name_Buffer
(01))) * 2 +
724 Character'Pos (Name_Buffer
(02))) * 2 +
725 Character'Pos (Name_Buffer
(08))) * 2 +
726 Character'Pos (Name_Buffer
(03))) * 2 +
727 Character'Pos (Name_Buffer
(04))) * 2 +
728 Character'Pos (Name_Buffer
(09))) * 2 +
729 Character'Pos (Name_Buffer
(06))) * 2 +
730 Character'Pos (Name_Buffer
(05))) * 2 +
731 Character'Pos (Name_Buffer
(07))) * 2 +
732 Character'Pos (Name_Buffer
(10))) mod Hash_Num
;
736 Character'Pos (Name_Buffer
(05))) * 2 +
737 Character'Pos (Name_Buffer
(01))) * 2 +
738 Character'Pos (Name_Buffer
(06))) * 2 +
739 Character'Pos (Name_Buffer
(09))) * 2 +
740 Character'Pos (Name_Buffer
(07))) * 2 +
741 Character'Pos (Name_Buffer
(03))) * 2 +
742 Character'Pos (Name_Buffer
(08))) * 2 +
743 Character'Pos (Name_Buffer
(02))) * 2 +
744 Character'Pos (Name_Buffer
(10))) * 2 +
745 Character'Pos (Name_Buffer
(04))) * 2 +
746 Character'Pos (Name_Buffer
(11))) mod Hash_Num
;
750 Character'Pos (Name_Buffer
(03))) * 2 +
751 Character'Pos (Name_Buffer
(02))) * 2 +
752 Character'Pos (Name_Buffer
(05))) * 2 +
753 Character'Pos (Name_Buffer
(01))) * 2 +
754 Character'Pos (Name_Buffer
(06))) * 2 +
755 Character'Pos (Name_Buffer
(04))) * 2 +
756 Character'Pos (Name_Buffer
(08))) * 2 +
757 Character'Pos (Name_Buffer
(11))) * 2 +
758 Character'Pos (Name_Buffer
(07))) * 2 +
759 Character'Pos (Name_Buffer
(09))) * 2 +
760 Character'Pos (Name_Buffer
(10))) * 2 +
761 Character'Pos (Name_Buffer
(12))) mod Hash_Num
;
770 procedure Initialize
is
776 -- Initialize entries for one character names
778 for C
in Character loop
779 Name_Entries
.Increment_Last
;
780 Name_Entries
.Table
(Name_Entries
.Last
).Name_Chars_Index
:=
782 Name_Entries
.Table
(Name_Entries
.Last
).Name_Len
:= 1;
783 Name_Entries
.Table
(Name_Entries
.Last
).Hash_Link
:= No_Name
;
784 Name_Entries
.Table
(Name_Entries
.Last
).Int_Info
:= 0;
785 Name_Entries
.Table
(Name_Entries
.Last
).Byte_Info
:= 0;
786 Name_Chars
.Increment_Last
;
787 Name_Chars
.Table
(Name_Chars
.Last
) := C
;
788 Name_Chars
.Increment_Last
;
789 Name_Chars
.Table
(Name_Chars
.Last
) := ASCII
.NUL
;
794 for J
in Hash_Index_Type
loop
795 Hash_Table
(J
) := No_Name
;
799 ----------------------
800 -- Is_Internal_Name --
801 ----------------------
803 function Is_Internal_Name
(Id
: Name_Id
) return Boolean is
805 Get_Name_String
(Id
);
806 return Is_Internal_Name
;
807 end Is_Internal_Name
;
809 function Is_Internal_Name
return Boolean is
811 if Name_Buffer
(1) = '_'
812 or else Name_Buffer
(Name_Len
) = '_'
817 -- Test backwards, because we only want to test the last entity
818 -- name if the name we have is qualified with other entities.
820 for J
in reverse 1 .. Name_Len
loop
821 if Is_OK_Internal_Letter
(Name_Buffer
(J
)) then
824 -- Quit if we come to terminating double underscore (note that
825 -- if the current character is an underscore, we know that
826 -- there is a previous character present, since we already
827 -- filtered out the case of Name_Buffer (1) = '_' above.
829 elsif Name_Buffer
(J
) = '_'
830 and then Name_Buffer
(J
- 1) = '_'
831 and then Name_Buffer
(J
- 2) /= '_'
839 end Is_Internal_Name
;
841 ---------------------------
842 -- Is_OK_Internal_Letter --
843 ---------------------------
845 function Is_OK_Internal_Letter
(C
: Character) return Boolean is
847 return C
in 'A' .. 'Z'
853 end Is_OK_Internal_Letter
;
859 function Length_Of_Name
(Id
: Name_Id
) return Nat
is
861 return Int
(Name_Entries
.Table
(Id
).Name_Len
);
870 Name_Chars
.Set_Last
(Name_Chars
.Last
+ Name_Chars_Reserve
);
871 Name_Entries
.Set_Last
(Name_Entries
.Last
+ Name_Entries_Reserve
);
872 Name_Chars
.Locked
:= True;
873 Name_Entries
.Locked
:= True;
875 Name_Entries
.Release
;
878 ------------------------
879 -- Name_Chars_Address --
880 ------------------------
882 function Name_Chars_Address
return System
.Address
is
884 return Name_Chars
.Table
(0)'Address;
885 end Name_Chars_Address
;
891 function Name_Enter
return Name_Id
is
894 Name_Entries
.Increment_Last
;
895 Name_Entries
.Table
(Name_Entries
.Last
).Name_Chars_Index
:=
897 Name_Entries
.Table
(Name_Entries
.Last
).Name_Len
:= Short
(Name_Len
);
898 Name_Entries
.Table
(Name_Entries
.Last
).Hash_Link
:= No_Name
;
899 Name_Entries
.Table
(Name_Entries
.Last
).Int_Info
:= 0;
900 Name_Entries
.Table
(Name_Entries
.Last
).Byte_Info
:= 0;
902 -- Set corresponding string entry in the Name_Chars table
904 for J
in 1 .. Name_Len
loop
905 Name_Chars
.Increment_Last
;
906 Name_Chars
.Table
(Name_Chars
.Last
) := Name_Buffer
(J
);
909 Name_Chars
.Increment_Last
;
910 Name_Chars
.Table
(Name_Chars
.Last
) := ASCII
.NUL
;
912 return Name_Entries
.Last
;
915 --------------------------
916 -- Name_Entries_Address --
917 --------------------------
919 function Name_Entries_Address
return System
.Address
is
921 return Name_Entries
.Table
(First_Name_Id
)'Address;
922 end Name_Entries_Address
;
924 ------------------------
925 -- Name_Entries_Count --
926 ------------------------
928 function Name_Entries_Count
return Nat
is
930 return Int
(Name_Entries
.Last
- Name_Entries
.First
+ 1);
931 end Name_Entries_Count
;
937 function Name_Find
return Name_Id
is
939 -- Id of entry in hash search, and value to be returned
942 -- Pointer into string table
944 Hash_Index
: Hash_Index_Type
;
945 -- Computed hash index
948 -- Quick handling for one character names
951 return Name_Id
(First_Name_Id
+ Character'Pos (Name_Buffer
(1)));
953 -- Otherwise search hash table for existing matching entry
956 Hash_Index
:= Namet
.Hash
;
957 New_Id
:= Hash_Table
(Hash_Index
);
959 if New_Id
= No_Name
then
960 Hash_Table
(Hash_Index
) := Name_Entries
.Last
+ 1;
965 Integer (Name_Entries
.Table
(New_Id
).Name_Len
)
970 S
:= Name_Entries
.Table
(New_Id
).Name_Chars_Index
;
972 for I
in 1 .. Name_Len
loop
973 if Name_Chars
.Table
(S
+ Int
(I
)) /= Name_Buffer
(I
) then
980 -- Current entry in hash chain does not match
983 if Name_Entries
.Table
(New_Id
).Hash_Link
/= No_Name
then
984 New_Id
:= Name_Entries
.Table
(New_Id
).Hash_Link
;
986 Name_Entries
.Table
(New_Id
).Hash_Link
:=
987 Name_Entries
.Last
+ 1;
994 -- We fall through here only if a matching entry was not found in the
995 -- hash table. We now create a new entry in the names table. The hash
996 -- link pointing to the new entry (Name_Entries.Last+1) has been set.
998 Name_Entries
.Increment_Last
;
999 Name_Entries
.Table
(Name_Entries
.Last
).Name_Chars_Index
:=
1001 Name_Entries
.Table
(Name_Entries
.Last
).Name_Len
:= Short
(Name_Len
);
1002 Name_Entries
.Table
(Name_Entries
.Last
).Hash_Link
:= No_Name
;
1003 Name_Entries
.Table
(Name_Entries
.Last
).Int_Info
:= 0;
1004 Name_Entries
.Table
(Name_Entries
.Last
).Byte_Info
:= 0;
1006 -- Set corresponding string entry in the Name_Chars table
1008 for I
in 1 .. Name_Len
loop
1009 Name_Chars
.Increment_Last
;
1010 Name_Chars
.Table
(Name_Chars
.Last
) := Name_Buffer
(I
);
1013 Name_Chars
.Increment_Last
;
1014 Name_Chars
.Table
(Name_Chars
.Last
) := ASCII
.NUL
;
1016 return Name_Entries
.Last
;
1020 ----------------------
1021 -- Reset_Name_Table --
1022 ----------------------
1024 procedure Reset_Name_Table
is
1026 for J
in First_Name_Id
.. Name_Entries
.Last
loop
1027 Name_Entries
.Table
(J
).Int_Info
:= 0;
1028 Name_Entries
.Table
(J
).Byte_Info
:= 0;
1030 end Reset_Name_Table
;
1032 --------------------------------
1033 -- Set_Character_Literal_Name --
1034 --------------------------------
1036 procedure Set_Character_Literal_Name
(C
: Char_Code
) is
1038 Name_Buffer
(1) := 'Q';
1040 Store_Encoded_Character
(C
);
1041 end Set_Character_Literal_Name
;
1043 -------------------------
1044 -- Set_Name_Table_Byte --
1045 -------------------------
1047 procedure Set_Name_Table_Byte
(Id
: Name_Id
; Val
: Byte
) is
1049 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1050 Name_Entries
.Table
(Id
).Byte_Info
:= Val
;
1051 end Set_Name_Table_Byte
;
1053 -------------------------
1054 -- Set_Name_Table_Info --
1055 -------------------------
1057 procedure Set_Name_Table_Info
(Id
: Name_Id
; Val
: Int
) is
1059 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1060 Name_Entries
.Table
(Id
).Int_Info
:= Val
;
1061 end Set_Name_Table_Info
;
1063 -----------------------------
1064 -- Store_Encoded_Character --
1065 -----------------------------
1067 procedure Store_Encoded_Character
(C
: Char_Code
) is
1069 procedure Set_Hex_Chars
(N
: Natural);
1070 -- Stores given value, which is in the range 0 .. 255, as two hex
1071 -- digits (using lower case a-f) in Name_Buffer, incrementing Name_Len
1073 procedure Set_Hex_Chars
(N
: Natural) is
1074 Hexd
: constant String := "0123456789abcdef";
1077 Name_Buffer
(Name_Len
+ 1) := Hexd
(N
/ 16 + 1);
1078 Name_Buffer
(Name_Len
+ 2) := Hexd
(N
mod 16 + 1);
1079 Name_Len
:= Name_Len
+ 2;
1083 Name_Len
:= Name_Len
+ 1;
1085 if In_Character_Range
(C
) then
1087 CC
: constant Character := Get_Character
(C
);
1090 if CC
in 'a' .. 'z' or else CC
in '0' .. '9' then
1091 Name_Buffer
(Name_Len
) := CC
;
1094 Name_Buffer
(Name_Len
) := 'U';
1095 Set_Hex_Chars
(Natural (C
));
1100 Name_Buffer
(Name_Len
) := 'W';
1101 Set_Hex_Chars
(Natural (C
) / 256);
1102 Set_Hex_Chars
(Natural (C
) mod 256);
1105 end Store_Encoded_Character
;
1107 --------------------------------------
1108 -- Strip_Qualification_And_Suffixes --
1109 --------------------------------------
1111 procedure Strip_Qualification_And_Suffixes
is
1115 -- Strip package body qualification string off end
1117 for J
in reverse 2 .. Name_Len
loop
1118 if Name_Buffer
(J
) = 'X' then
1123 exit when Name_Buffer
(J
) /= 'b'
1124 and then Name_Buffer
(J
) /= 'n'
1125 and then Name_Buffer
(J
) /= 'p';
1128 -- Find rightmost __ or $ separator if one exists
1133 -- If $ separator, homonym separator, so strip it and keep looking
1135 if Name_Buffer
(J
) = '$' then
1139 -- Else check for __ found
1141 elsif Name_Buffer
(J
) = '_' and then Name_Buffer
(J
+ 1) = '_' then
1143 -- Found __ so see if digit follows, and if so, this is a
1144 -- homonym separator, so strip it and keep looking.
1146 if Name_Buffer
(J
+ 2) in '0' .. '9' then
1150 -- If not a homonym separator, then we simply strip the
1151 -- separator and everything that precedes it, and we are done
1154 Name_Buffer
(1 .. Name_Len
- J
- 1) :=
1155 Name_Buffer
(J
+ 2 .. Name_Len
);
1156 Name_Len
:= Name_Len
- J
- 1;
1164 end Strip_Qualification_And_Suffixes
;
1170 procedure Tree_Read
is
1172 Name_Chars
.Tree_Read
;
1173 Name_Entries
.Tree_Read
;
1176 (Hash_Table
'Address,
1177 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1184 procedure Tree_Write
is
1186 Name_Chars
.Tree_Write
;
1187 Name_Entries
.Tree_Write
;
1190 (Hash_Table
'Address,
1191 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1200 Name_Chars
.Set_Last
(Name_Chars
.Last
- Name_Chars_Reserve
);
1201 Name_Entries
.Set_Last
(Name_Entries
.Last
- Name_Entries_Reserve
);
1202 Name_Chars
.Locked
:= False;
1203 Name_Entries
.Locked
:= False;
1205 Name_Entries
.Release
;
1212 procedure wn
(Id
: Name_Id
) is
1222 procedure Write_Name
(Id
: Name_Id
) is
1224 if Id
>= First_Name_Id
then
1225 Get_Name_String
(Id
);
1226 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1230 ------------------------
1231 -- Write_Name_Decoded --
1232 ------------------------
1234 procedure Write_Name_Decoded
(Id
: Name_Id
) is
1236 if Id
>= First_Name_Id
then
1237 Get_Decoded_Name_String
(Id
);
1238 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1240 end Write_Name_Decoded
;