1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2013, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
32 -- WARNING: There is a C version of this package. Any changes to this
33 -- source file must be properly reflected in the C header file namet.h
34 -- which is created manually from namet.ads and namet.adb.
36 with Debug
; use Debug
;
38 with Output
; use Output
;
39 with Tree_IO
; use Tree_IO
;
40 with Widechar
; use Widechar
;
42 with Interfaces
; use Interfaces
;
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**16;
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 algorithm.
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 F
: array (Int
range 0 .. 50) of Int
;
129 -- N'th entry is the number of chains of length N, except last entry,
130 -- which is the number of chains of length F'Last or more.
132 Max_Chain_Length
: Int
:= 0;
133 -- Maximum length of all chains
136 -- Used to compute average number of probes
139 -- Number of symbols in table
141 Verbosity
: constant Int
range 1 .. 3 := 1;
142 pragma Warnings
(Off
, Verbosity
);
143 -- This constant indicates the level of verbosity in the output from
144 -- this procedure. Currently this can only be changed by editing the
145 -- declaration above and recompiling. That's good enough in practice,
146 -- since we very rarely need to use this debug option. Settings are:
148 -- 1 => print basic summary information
149 -- 2 => in addition print number of entries per hash chain
150 -- 3 => in addition print content of entries
152 Zero
: constant Int
:= Character'Pos ('0');
155 if not Debug_Flag_H
then
159 for J
in F
'Range loop
163 for J
in Hash_Index_Type
loop
164 if Hash_Table
(J
) = No_Name
then
177 while N
/= No_Name
loop
178 N
:= Name_Entries
.Table
(N
).Hash_Link
;
183 Probes
:= Probes
+ (1 + C
) * 100;
185 if C
> Max_Chain_Length
then
186 Max_Chain_Length
:= C
;
189 if Verbosity
>= 2 then
190 Write_Str
("Hash_Table (");
192 Write_Str
(") has ");
194 Write_Str
(" entries");
201 F
(F
'Last) := F
(F
'Last) + 1;
204 if Verbosity
>= 3 then
206 while N
/= No_Name
loop
207 S
:= Name_Entries
.Table
(N
).Name_Chars_Index
;
211 for J
in 1 .. Name_Entries
.Table
(N
).Name_Len
loop
212 Write_Char
(Name_Chars
.Table
(S
+ Int
(J
)));
217 N
:= Name_Entries
.Table
(N
).Hash_Link
;
226 for J
in F
'Range loop
228 Write_Str
("Number of hash chains of length ");
237 Write_Str
(" or greater");
246 -- Print out average number of probes, in the case where Name_Find is
247 -- called for a string that is already in the table.
250 Write_Str
("Average number of probes for lookup = ");
251 Probes
:= Probes
/ Nsyms
;
252 Write_Int
(Probes
/ 200);
254 Probes
:= (Probes
mod 200) / 2;
255 Write_Char
(Character'Val (Zero
+ Probes
/ 10));
256 Write_Char
(Character'Val (Zero
+ Probes
mod 10));
259 Write_Str
("Max_Chain_Length = ");
260 Write_Int
(Max_Chain_Length
);
262 Write_Str
("Name_Chars'Length = ");
263 Write_Int
(Name_Chars
.Last
- Name_Chars
.First
+ 1);
265 Write_Str
("Name_Entries'Length = ");
266 Write_Int
(Int
(Name_Entries
.Last
- Name_Entries
.First
+ 1));
268 Write_Str
("Nsyms = ");
273 -----------------------------
274 -- Get_Decoded_Name_String --
275 -----------------------------
277 procedure Get_Decoded_Name_String
(Id
: Name_Id
) is
282 Get_Name_String
(Id
);
284 -- Skip scan if we already know there are no encodings
286 if Name_Entries
.Table
(Id
).Name_Has_No_Encodings
then
290 -- Quick loop to see if there is anything special to do
295 Name_Entries
.Table
(Id
).Name_Has_No_Encodings
:= True;
299 C
:= Name_Buffer
(P
);
311 -- Here we have at least some encoding that we must decode
316 New_Buf
: String (1 .. Name_Buffer
'Last);
318 procedure Copy_One_Character
;
319 -- Copy a character from Name_Buffer to New_Buf. Includes case
320 -- of copying a Uhh,Whhhh,WWhhhhhhhh sequence and decoding it.
322 function Hex
(N
: Natural) return Word
;
323 -- Scans past N digits using Old pointer and returns hex value
325 procedure Insert_Character
(C
: Character);
326 -- Insert a new character into output decoded name
328 ------------------------
329 -- Copy_One_Character --
330 ------------------------
332 procedure Copy_One_Character
is
336 C
:= Name_Buffer
(Old
);
338 -- U (upper half insertion case)
341 and then Old
< Name_Len
342 and then Name_Buffer
(Old
+ 1) not in 'A' .. 'Z'
343 and then Name_Buffer
(Old
+ 1) /= '_'
347 -- If we have upper half encoding, then we have to set an
348 -- appropriate wide character sequence for this character.
350 if Upper_Half_Encoding
then
351 Widechar
.Set_Wide
(Char_Code
(Hex
(2)), New_Buf
, New_Len
);
353 -- For other encoding methods, upper half characters can
354 -- simply use their normal representation.
357 Insert_Character
(Character'Val (Hex
(2)));
360 -- WW (wide wide character insertion)
363 and then Old
< Name_Len
364 and then Name_Buffer
(Old
+ 1) = 'W'
367 Widechar
.Set_Wide
(Char_Code
(Hex
(8)), New_Buf
, New_Len
);
369 -- W (wide character insertion)
372 and then Old
< Name_Len
373 and then Name_Buffer
(Old
+ 1) not in 'A' .. 'Z'
374 and then Name_Buffer
(Old
+ 1) /= '_'
377 Widechar
.Set_Wide
(Char_Code
(Hex
(4)), New_Buf
, New_Len
);
379 -- Any other character is copied unchanged
382 Insert_Character
(C
);
385 end Copy_One_Character
;
391 function Hex
(N
: Natural) return Word
is
397 C
:= Name_Buffer
(Old
);
400 pragma Assert
(C
in '0' .. '9' or else C
in 'a' .. 'f');
403 T
:= 16 * T
+ Character'Pos (C
) - Character'Pos ('0');
404 else -- C in 'a' .. 'f'
405 T
:= 16 * T
+ Character'Pos (C
) - (Character'Pos ('a') - 10);
412 ----------------------
413 -- Insert_Character --
414 ----------------------
416 procedure Insert_Character
(C
: Character) is
418 New_Len
:= New_Len
+ 1;
419 New_Buf
(New_Len
) := C
;
420 end Insert_Character
;
422 -- Start of processing for Decode
428 -- Loop through characters of name
430 while Old
<= Name_Len
loop
432 -- Case of character literal, put apostrophes around character
434 if Name_Buffer
(Old
) = 'Q'
435 and then Old
< Name_Len
438 Insert_Character
(''');
440 Insert_Character
(''');
442 -- Case of operator name
444 elsif Name_Buffer
(Old
) = 'O'
445 and then Old
< Name_Len
446 and then Name_Buffer
(Old
+ 1) not in 'A' .. 'Z'
447 and then Name_Buffer
(Old
+ 1) /= '_'
452 -- This table maps the 2nd and 3rd characters of the name
453 -- into the required output. Two blanks means leave the
456 Map
: constant String :=
457 "ab " & -- Oabs => "abs"
458 "ad+ " & -- Oadd => "+"
459 "an " & -- Oand => "and"
460 "co& " & -- Oconcat => "&"
461 "di/ " & -- Odivide => "/"
462 "eq= " & -- Oeq => "="
463 "ex**" & -- Oexpon => "**"
464 "gt> " & -- Ogt => ">"
465 "ge>=" & -- Oge => ">="
466 "le<=" & -- Ole => "<="
467 "lt< " & -- Olt => "<"
468 "mo " & -- Omod => "mod"
469 "mu* " & -- Omutliply => "*"
470 "ne/=" & -- One => "/="
471 "no " & -- Onot => "not"
472 "or " & -- Oor => "or"
473 "re " & -- Orem => "rem"
474 "su- " & -- Osubtract => "-"
475 "xo "; -- Oxor => "xor"
480 Insert_Character
('"');
482 -- Search the map. Note that this loop must terminate, if
483 -- not we have some kind of internal error, and a constraint
484 -- error may be raised.
488 exit when Name_Buffer
(Old
) = Map
(J
)
489 and then Name_Buffer
(Old
+ 1) = Map
(J
+ 1);
493 -- Special operator name
495 if Map
(J
+ 2) /= ' ' then
496 Insert_Character
(Map
(J
+ 2));
498 if Map
(J
+ 3) /= ' ' then
499 Insert_Character
(Map
(J
+ 3));
502 Insert_Character
('"');
504 -- Skip past original operator name in input
506 while Old
<= Name_Len
507 and then Name_Buffer
(Old
) in 'a' .. 'z'
512 -- For other operator names, leave them in lower case,
513 -- surrounded by apostrophes
516 -- Copy original operator name from input to output
518 while Old
<= Name_Len
519 and then Name_Buffer
(Old
) in 'a' .. 'z'
524 Insert_Character
('"');
528 -- Else copy one character and keep going
535 -- Copy new buffer as result
538 Name_Buffer
(1 .. New_Len
) := New_Buf
(1 .. New_Len
);
540 end Get_Decoded_Name_String
;
542 -------------------------------------------
543 -- Get_Decoded_Name_String_With_Brackets --
544 -------------------------------------------
546 procedure Get_Decoded_Name_String_With_Brackets
(Id
: Name_Id
) is
550 -- Case of operator name, normal decoding is fine
552 if Name_Buffer
(1) = 'O' then
553 Get_Decoded_Name_String
(Id
);
555 -- For character literals, normal decoding is fine
557 elsif Name_Buffer
(1) = 'Q' then
558 Get_Decoded_Name_String
(Id
);
560 -- Only remaining issue is U/W/WW sequences
563 Get_Name_String
(Id
);
566 while P
< Name_Len
loop
567 if Name_Buffer
(P
+ 1) in 'A' .. 'Z' then
572 elsif Name_Buffer
(P
) = 'U' then
573 for J
in reverse P
+ 3 .. P
+ Name_Len
loop
574 Name_Buffer
(J
+ 3) := Name_Buffer
(J
);
577 Name_Len
:= Name_Len
+ 3;
578 Name_Buffer
(P
+ 3) := Name_Buffer
(P
+ 2);
579 Name_Buffer
(P
+ 2) := Name_Buffer
(P
+ 1);
580 Name_Buffer
(P
) := '[';
581 Name_Buffer
(P
+ 1) := '"';
582 Name_Buffer
(P
+ 4) := '"';
583 Name_Buffer
(P
+ 5) := ']';
586 -- WWhhhhhhhh encoding
588 elsif Name_Buffer
(P
) = 'W'
589 and then P
+ 9 <= Name_Len
590 and then Name_Buffer
(P
+ 1) = 'W'
591 and then Name_Buffer
(P
+ 2) not in 'A' .. 'Z'
592 and then Name_Buffer
(P
+ 2) /= '_'
594 Name_Buffer
(P
+ 12 .. Name_Len
+ 2) :=
595 Name_Buffer
(P
+ 10 .. Name_Len
);
596 Name_Buffer
(P
) := '[';
597 Name_Buffer
(P
+ 1) := '"';
598 Name_Buffer
(P
+ 10) := '"';
599 Name_Buffer
(P
+ 11) := ']';
600 Name_Len
:= Name_Len
+ 2;
605 elsif Name_Buffer
(P
) = 'W'
606 and then P
< Name_Len
607 and then Name_Buffer
(P
+ 1) not in 'A' .. 'Z'
608 and then Name_Buffer
(P
+ 1) /= '_'
610 Name_Buffer
(P
+ 8 .. P
+ Name_Len
+ 3) :=
611 Name_Buffer
(P
+ 5 .. Name_Len
);
612 Name_Buffer
(P
+ 2 .. P
+ 5) := Name_Buffer
(P
+ 1 .. P
+ 4);
613 Name_Buffer
(P
) := '[';
614 Name_Buffer
(P
+ 1) := '"';
615 Name_Buffer
(P
+ 6) := '"';
616 Name_Buffer
(P
+ 7) := ']';
617 Name_Len
:= Name_Len
+ 3;
625 end Get_Decoded_Name_String_With_Brackets
;
627 ------------------------
628 -- Get_Last_Two_Chars --
629 ------------------------
631 procedure Get_Last_Two_Chars
(N
: Name_Id
; C1
, C2
: out Character) is
632 NE
: Name_Entry
renames Name_Entries
.Table
(N
);
633 NEL
: constant Int
:= Int
(NE
.Name_Len
);
637 C1
:= Name_Chars
.Table
(NE
.Name_Chars_Index
+ NEL
- 1);
638 C2
:= Name_Chars
.Table
(NE
.Name_Chars_Index
+ NEL
- 0);
643 end Get_Last_Two_Chars
;
645 ---------------------
646 -- Get_Name_String --
647 ---------------------
649 -- Procedure version leaving result in Name_Buffer, length in Name_Len
651 procedure Get_Name_String
(Id
: Name_Id
) is
655 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
657 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
658 Name_Len
:= Natural (Name_Entries
.Table
(Id
).Name_Len
);
660 for J
in 1 .. Name_Len
loop
661 Name_Buffer
(J
) := Name_Chars
.Table
(S
+ Int
(J
));
665 ---------------------
666 -- Get_Name_String --
667 ---------------------
669 -- Function version returning a string
671 function Get_Name_String
(Id
: Name_Id
) return String is
675 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
676 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
679 R
: String (1 .. Natural (Name_Entries
.Table
(Id
).Name_Len
));
682 for J
in R
'Range loop
683 R
(J
) := Name_Chars
.Table
(S
+ Int
(J
));
690 --------------------------------
691 -- Get_Name_String_And_Append --
692 --------------------------------
694 procedure Get_Name_String_And_Append
(Id
: Name_Id
) is
698 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
700 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
702 for J
in 1 .. Natural (Name_Entries
.Table
(Id
).Name_Len
) loop
703 Name_Len
:= Name_Len
+ 1;
704 Name_Buffer
(Name_Len
) := Name_Chars
.Table
(S
+ Int
(J
));
706 end Get_Name_String_And_Append
;
708 -------------------------
709 -- Get_Name_Table_Byte --
710 -------------------------
712 function Get_Name_Table_Byte
(Id
: Name_Id
) return Byte
is
714 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
715 return Name_Entries
.Table
(Id
).Byte_Info
;
716 end Get_Name_Table_Byte
;
718 -------------------------
719 -- Get_Name_Table_Info --
720 -------------------------
722 function Get_Name_Table_Info
(Id
: Name_Id
) return Int
is
724 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
725 return Name_Entries
.Table
(Id
).Int_Info
;
726 end Get_Name_Table_Info
;
728 -----------------------------------------
729 -- Get_Unqualified_Decoded_Name_String --
730 -----------------------------------------
732 procedure Get_Unqualified_Decoded_Name_String
(Id
: Name_Id
) is
734 Get_Decoded_Name_String
(Id
);
735 Strip_Qualification_And_Suffixes
;
736 end Get_Unqualified_Decoded_Name_String
;
738 ---------------------------------
739 -- Get_Unqualified_Name_String --
740 ---------------------------------
742 procedure Get_Unqualified_Name_String
(Id
: Name_Id
) is
744 Get_Name_String
(Id
);
745 Strip_Qualification_And_Suffixes
;
746 end Get_Unqualified_Name_String
;
752 function Hash
return Hash_Index_Type
is
754 -- This hash function looks at every character, in order to make it
755 -- likely that similar strings get different hash values. The rotate by
756 -- 7 bits has been determined empirically to be good, and it doesn't
757 -- lose bits like a shift would. The final conversion can't overflow,
758 -- because the table is 2**16 in size. This function probably needs to
759 -- be changed if the hash table size is changed.
761 -- Note that we could get some speed improvement by aligning the string
762 -- to 32 or 64 bits, and doing word-wise xor's. We could also implement
763 -- a growable table. It doesn't seem worth the trouble to do those
766 Result
: Unsigned_16
:= 0;
769 for J
in 1 .. Name_Len
loop
770 Result
:= Rotate_Left
(Result
, 7) xor Character'Pos (Name_Buffer
(J
));
773 return Hash_Index_Type
(Result
);
780 procedure Initialize
is
785 -------------------------------
786 -- Insert_Str_In_Name_Buffer --
787 -------------------------------
789 procedure Insert_Str_In_Name_Buffer
(S
: String; Index
: Positive) is
790 SL
: constant Natural := S
'Length;
792 Name_Buffer
(Index
+ SL
.. Name_Len
+ SL
) :=
793 Name_Buffer
(Index
.. Name_Len
);
794 Name_Buffer
(Index
.. Index
+ SL
- 1) := S
;
795 Name_Len
:= Name_Len
+ SL
;
796 end Insert_Str_In_Name_Buffer
;
798 ----------------------
799 -- Is_Internal_Name --
800 ----------------------
802 -- Version taking an argument
804 function Is_Internal_Name
(Id
: Name_Id
) return Boolean is
806 Get_Name_String
(Id
);
807 return Is_Internal_Name
;
808 end Is_Internal_Name
;
810 ----------------------
811 -- Is_Internal_Name --
812 ----------------------
814 -- Version taking its input from Name_Buffer
816 function Is_Internal_Name
return Boolean is
818 if Name_Buffer
(1) = '_'
819 or else Name_Buffer
(Name_Len
) = '_'
824 -- Test backwards, because we only want to test the last entity
825 -- name if the name we have is qualified with other entities.
827 for J
in reverse 1 .. Name_Len
loop
828 if Is_OK_Internal_Letter
(Name_Buffer
(J
)) then
831 -- Quit if we come to terminating double underscore (note that
832 -- if the current character is an underscore, we know that
833 -- there is a previous character present, since we already
834 -- filtered out the case of Name_Buffer (1) = '_' above.
836 elsif Name_Buffer
(J
) = '_'
837 and then Name_Buffer
(J
- 1) = '_'
838 and then Name_Buffer
(J
- 2) /= '_'
846 end Is_Internal_Name
;
848 ---------------------------
849 -- Is_OK_Internal_Letter --
850 ---------------------------
852 function Is_OK_Internal_Letter
(C
: Character) return Boolean is
854 return C
in 'A' .. 'Z'
860 end Is_OK_Internal_Letter
;
862 ----------------------
863 -- Is_Operator_Name --
864 ----------------------
866 function Is_Operator_Name
(Id
: Name_Id
) return Boolean is
869 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
870 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
871 return Name_Chars
.Table
(S
+ 1) = 'O';
872 end Is_Operator_Name
;
878 function Is_Valid_Name
(Id
: Name_Id
) return Boolean is
880 return Id
in Name_Entries
.First
.. Name_Entries
.Last
;
887 function Length_Of_Name
(Id
: Name_Id
) return Nat
is
889 return Int
(Name_Entries
.Table
(Id
).Name_Len
);
898 Name_Chars
.Set_Last
(Name_Chars
.Last
+ Name_Chars_Reserve
);
899 Name_Entries
.Set_Last
(Name_Entries
.Last
+ Name_Entries_Reserve
);
900 Name_Chars
.Locked
:= True;
901 Name_Entries
.Locked
:= True;
903 Name_Entries
.Release
;
906 ------------------------
907 -- Name_Chars_Address --
908 ------------------------
910 function Name_Chars_Address
return System
.Address
is
912 return Name_Chars
.Table
(0)'Address;
913 end Name_Chars_Address
;
919 function Name_Enter
return Name_Id
is
922 ((Name_Chars_Index
=> Name_Chars
.Last
,
923 Name_Len
=> Short
(Name_Len
),
926 Name_Has_No_Encodings
=> False,
927 Hash_Link
=> No_Name
));
929 -- Set corresponding string entry in the Name_Chars table
931 for J
in 1 .. Name_Len
loop
932 Name_Chars
.Append
(Name_Buffer
(J
));
935 Name_Chars
.Append
(ASCII
.NUL
);
937 return Name_Entries
.Last
;
940 --------------------------
941 -- Name_Entries_Address --
942 --------------------------
944 function Name_Entries_Address
return System
.Address
is
946 return Name_Entries
.Table
(First_Name_Id
)'Address;
947 end Name_Entries_Address
;
949 ------------------------
950 -- Name_Entries_Count --
951 ------------------------
953 function Name_Entries_Count
return Nat
is
955 return Int
(Name_Entries
.Last
- Name_Entries
.First
+ 1);
956 end Name_Entries_Count
;
962 function Name_Find
return Name_Id
is
964 -- Id of entry in hash search, and value to be returned
967 -- Pointer into string table
969 Hash_Index
: Hash_Index_Type
;
970 -- Computed hash index
973 -- Quick handling for one character names
976 return Name_Id
(First_Name_Id
+ Character'Pos (Name_Buffer
(1)));
978 -- Otherwise search hash table for existing matching entry
981 Hash_Index
:= Namet
.Hash
;
982 New_Id
:= Hash_Table
(Hash_Index
);
984 if New_Id
= No_Name
then
985 Hash_Table
(Hash_Index
) := Name_Entries
.Last
+ 1;
990 Integer (Name_Entries
.Table
(New_Id
).Name_Len
)
995 S
:= Name_Entries
.Table
(New_Id
).Name_Chars_Index
;
997 for J
in 1 .. Name_Len
loop
998 if Name_Chars
.Table
(S
+ Int
(J
)) /= Name_Buffer
(J
) then
1005 -- Current entry in hash chain does not match
1008 if Name_Entries
.Table
(New_Id
).Hash_Link
/= No_Name
then
1009 New_Id
:= Name_Entries
.Table
(New_Id
).Hash_Link
;
1011 Name_Entries
.Table
(New_Id
).Hash_Link
:=
1012 Name_Entries
.Last
+ 1;
1018 -- We fall through here only if a matching entry was not found in the
1019 -- hash table. We now create a new entry in the names table. The hash
1020 -- link pointing to the new entry (Name_Entries.Last+1) has been set.
1023 ((Name_Chars_Index
=> Name_Chars
.Last
,
1024 Name_Len
=> Short
(Name_Len
),
1025 Hash_Link
=> No_Name
,
1026 Name_Has_No_Encodings
=> False,
1030 -- Set corresponding string entry in the Name_Chars table
1032 for J
in 1 .. Name_Len
loop
1033 Name_Chars
.Append
(Name_Buffer
(J
));
1036 Name_Chars
.Append
(ASCII
.NUL
);
1038 return Name_Entries
.Last
;
1049 V2
: Name_Id
) return Boolean
1052 return T
= V1
or else
1060 V3
: Name_Id
) return Boolean
1063 return T
= V1
or else
1073 V4
: Name_Id
) return Boolean
1076 return T
= V1
or else
1088 V5
: Name_Id
) return Boolean
1091 return T
= V1
or else
1105 V6
: Name_Id
) return Boolean
1108 return T
= V1
or else
1124 V7
: Name_Id
) return Boolean
1127 return T
= V1
or else
1140 procedure Reinitialize
is
1145 -- Initialize entries for one character names
1147 for C
in Character loop
1149 ((Name_Chars_Index
=> Name_Chars
.Last
,
1153 Name_Has_No_Encodings
=> True,
1154 Hash_Link
=> No_Name
));
1156 Name_Chars
.Append
(C
);
1157 Name_Chars
.Append
(ASCII
.NUL
);
1162 for J
in Hash_Index_Type
loop
1163 Hash_Table
(J
) := No_Name
;
1167 ----------------------
1168 -- Reset_Name_Table --
1169 ----------------------
1171 procedure Reset_Name_Table
is
1173 for J
in First_Name_Id
.. Name_Entries
.Last
loop
1174 Name_Entries
.Table
(J
).Int_Info
:= 0;
1175 Name_Entries
.Table
(J
).Byte_Info
:= 0;
1177 end Reset_Name_Table
;
1179 --------------------------------
1180 -- Set_Character_Literal_Name --
1181 --------------------------------
1183 procedure Set_Character_Literal_Name
(C
: Char_Code
) is
1185 Name_Buffer
(1) := 'Q';
1187 Store_Encoded_Character
(C
);
1188 end Set_Character_Literal_Name
;
1190 -------------------------
1191 -- Set_Name_Table_Byte --
1192 -------------------------
1194 procedure Set_Name_Table_Byte
(Id
: Name_Id
; Val
: Byte
) is
1196 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1197 Name_Entries
.Table
(Id
).Byte_Info
:= Val
;
1198 end Set_Name_Table_Byte
;
1200 -------------------------
1201 -- Set_Name_Table_Info --
1202 -------------------------
1204 procedure Set_Name_Table_Info
(Id
: Name_Id
; Val
: Int
) is
1206 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1207 Name_Entries
.Table
(Id
).Int_Info
:= Val
;
1208 end Set_Name_Table_Info
;
1210 -----------------------------
1211 -- Store_Encoded_Character --
1212 -----------------------------
1214 procedure Store_Encoded_Character
(C
: Char_Code
) is
1216 procedure Set_Hex_Chars
(C
: Char_Code
);
1217 -- Stores given value, which is in the range 0 .. 255, as two hex
1218 -- digits (using lower case a-f) in Name_Buffer, incrementing Name_Len.
1224 procedure Set_Hex_Chars
(C
: Char_Code
) is
1225 Hexd
: constant String := "0123456789abcdef";
1226 N
: constant Natural := Natural (C
);
1228 Name_Buffer
(Name_Len
+ 1) := Hexd
(N
/ 16 + 1);
1229 Name_Buffer
(Name_Len
+ 2) := Hexd
(N
mod 16 + 1);
1230 Name_Len
:= Name_Len
+ 2;
1233 -- Start of processing for Store_Encoded_Character
1236 Name_Len
:= Name_Len
+ 1;
1238 if In_Character_Range
(C
) then
1240 CC
: constant Character := Get_Character
(C
);
1242 if CC
in 'a' .. 'z' or else CC
in '0' .. '9' then
1243 Name_Buffer
(Name_Len
) := CC
;
1245 Name_Buffer
(Name_Len
) := 'U';
1250 elsif In_Wide_Character_Range
(C
) then
1251 Name_Buffer
(Name_Len
) := 'W';
1252 Set_Hex_Chars
(C
/ 256);
1253 Set_Hex_Chars
(C
mod 256);
1256 Name_Buffer
(Name_Len
) := 'W';
1257 Name_Len
:= Name_Len
+ 1;
1258 Name_Buffer
(Name_Len
) := 'W';
1259 Set_Hex_Chars
(C
/ 2 ** 24);
1260 Set_Hex_Chars
((C
/ 2 ** 16) mod 256);
1261 Set_Hex_Chars
((C
/ 256) mod 256);
1262 Set_Hex_Chars
(C
mod 256);
1264 end Store_Encoded_Character
;
1266 --------------------------------------
1267 -- Strip_Qualification_And_Suffixes --
1268 --------------------------------------
1270 procedure Strip_Qualification_And_Suffixes
is
1274 -- Strip package body qualification string off end
1276 for J
in reverse 2 .. Name_Len
loop
1277 if Name_Buffer
(J
) = 'X' then
1282 exit when Name_Buffer
(J
) /= 'b'
1283 and then Name_Buffer
(J
) /= 'n'
1284 and then Name_Buffer
(J
) /= 'p';
1287 -- Find rightmost __ or $ separator if one exists. First we position
1288 -- to start the search. If we have a character constant, position
1289 -- just before it, otherwise position to last character but one
1291 if Name_Buffer
(Name_Len
) = ''' then
1293 while J
> 0 and then Name_Buffer
(J
) /= ''' loop
1301 -- Loop to search for rightmost __ or $ (homonym) separator
1305 -- If $ separator, homonym separator, so strip it and keep looking
1307 if Name_Buffer
(J
) = '$' then
1311 -- Else check for __ found
1313 elsif Name_Buffer
(J
) = '_' and then Name_Buffer
(J
+ 1) = '_' then
1315 -- Found __ so see if digit follows, and if so, this is a
1316 -- homonym separator, so strip it and keep looking.
1318 if Name_Buffer
(J
+ 2) in '0' .. '9' then
1322 -- If not a homonym separator, then we simply strip the
1323 -- separator and everything that precedes it, and we are done
1326 Name_Buffer
(1 .. Name_Len
- J
- 1) :=
1327 Name_Buffer
(J
+ 2 .. Name_Len
);
1328 Name_Len
:= Name_Len
- J
- 1;
1336 end Strip_Qualification_And_Suffixes
;
1342 procedure Tree_Read
is
1344 Name_Chars
.Tree_Read
;
1345 Name_Entries
.Tree_Read
;
1348 (Hash_Table
'Address,
1349 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1356 procedure Tree_Write
is
1358 Name_Chars
.Tree_Write
;
1359 Name_Entries
.Tree_Write
;
1362 (Hash_Table
'Address,
1363 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1372 Name_Chars
.Set_Last
(Name_Chars
.Last
- Name_Chars_Reserve
);
1373 Name_Entries
.Set_Last
(Name_Entries
.Last
- Name_Entries_Reserve
);
1374 Name_Chars
.Locked
:= False;
1375 Name_Entries
.Locked
:= False;
1377 Name_Entries
.Release
;
1384 procedure wn
(Id
: Name_Id
) is
1388 if not Id
'Valid then
1389 Write_Str
("<invalid name_id>");
1391 elsif Id
= No_Name
then
1392 Write_Str
("<No_Name>");
1394 elsif Id
= Error_Name
then
1395 Write_Str
("<Error_Name>");
1398 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
1399 Name_Len
:= Natural (Name_Entries
.Table
(Id
).Name_Len
);
1401 for J
in 1 .. Name_Len
loop
1402 Write_Char
(Name_Chars
.Table
(S
+ Int
(J
)));
1413 procedure Write_Name
(Id
: Name_Id
) is
1415 if Id
>= First_Name_Id
then
1416 Get_Name_String
(Id
);
1417 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1421 ------------------------
1422 -- Write_Name_Decoded --
1423 ------------------------
1425 procedure Write_Name_Decoded
(Id
: Name_Id
) is
1427 if Id
>= First_Name_Id
then
1428 Get_Decoded_Name_String
(Id
);
1429 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1431 end Write_Name_Decoded
;
1433 -- Package initialization, initialize tables