1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2015, 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_Boolean1 --
710 -----------------------------
712 function Get_Name_Table_Boolean1
(Id
: Name_Id
) return Boolean is
714 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
715 return Name_Entries
.Table
(Id
).Boolean1_Info
;
716 end Get_Name_Table_Boolean1
;
718 -----------------------------
719 -- Get_Name_Table_Boolean2 --
720 -----------------------------
722 function Get_Name_Table_Boolean2
(Id
: Name_Id
) return Boolean is
724 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
725 return Name_Entries
.Table
(Id
).Boolean2_Info
;
726 end Get_Name_Table_Boolean2
;
728 -----------------------------
729 -- Get_Name_Table_Boolean3 --
730 -----------------------------
732 function Get_Name_Table_Boolean3
(Id
: Name_Id
) return Boolean is
734 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
735 return Name_Entries
.Table
(Id
).Boolean3_Info
;
736 end Get_Name_Table_Boolean3
;
738 -------------------------
739 -- Get_Name_Table_Byte --
740 -------------------------
742 function Get_Name_Table_Byte
(Id
: Name_Id
) return Byte
is
744 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
745 return Name_Entries
.Table
(Id
).Byte_Info
;
746 end Get_Name_Table_Byte
;
748 -------------------------
749 -- Get_Name_Table_Int --
750 -------------------------
752 function Get_Name_Table_Int
(Id
: Name_Id
) return Int
is
754 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
755 return Name_Entries
.Table
(Id
).Int_Info
;
756 end Get_Name_Table_Int
;
758 -----------------------------------------
759 -- Get_Unqualified_Decoded_Name_String --
760 -----------------------------------------
762 procedure Get_Unqualified_Decoded_Name_String
(Id
: Name_Id
) is
764 Get_Decoded_Name_String
(Id
);
765 Strip_Qualification_And_Suffixes
;
766 end Get_Unqualified_Decoded_Name_String
;
768 ---------------------------------
769 -- Get_Unqualified_Name_String --
770 ---------------------------------
772 procedure Get_Unqualified_Name_String
(Id
: Name_Id
) is
774 Get_Name_String
(Id
);
775 Strip_Qualification_And_Suffixes
;
776 end Get_Unqualified_Name_String
;
782 function Hash
return Hash_Index_Type
is
784 -- This hash function looks at every character, in order to make it
785 -- likely that similar strings get different hash values. The rotate by
786 -- 7 bits has been determined empirically to be good, and it doesn't
787 -- lose bits like a shift would. The final conversion can't overflow,
788 -- because the table is 2**16 in size. This function probably needs to
789 -- be changed if the hash table size is changed.
791 -- Note that we could get some speed improvement by aligning the string
792 -- to 32 or 64 bits, and doing word-wise xor's. We could also implement
793 -- a growable table. It doesn't seem worth the trouble to do those
796 Result
: Unsigned_16
:= 0;
799 for J
in 1 .. Name_Len
loop
800 Result
:= Rotate_Left
(Result
, 7) xor Character'Pos (Name_Buffer
(J
));
803 return Hash_Index_Type
(Result
);
810 procedure Initialize
is
815 -------------------------------
816 -- Insert_Str_In_Name_Buffer --
817 -------------------------------
819 procedure Insert_Str_In_Name_Buffer
(S
: String; Index
: Positive) is
820 SL
: constant Natural := S
'Length;
822 Name_Buffer
(Index
+ SL
.. Name_Len
+ SL
) :=
823 Name_Buffer
(Index
.. Name_Len
);
824 Name_Buffer
(Index
.. Index
+ SL
- 1) := S
;
825 Name_Len
:= Name_Len
+ SL
;
826 end Insert_Str_In_Name_Buffer
;
828 ----------------------
829 -- Is_Internal_Name --
830 ----------------------
832 -- Version taking an argument
834 function Is_Internal_Name
(Id
: Name_Id
) return Boolean is
836 if Id
in Error_Name_Or_No_Name
then
839 Get_Name_String
(Id
);
840 return Is_Internal_Name
;
842 end Is_Internal_Name
;
844 ----------------------
845 -- Is_Internal_Name --
846 ----------------------
848 -- Version taking its input from Name_Buffer
850 function Is_Internal_Name
return Boolean is
854 -- AAny name starting with underscore is internal
856 if Name_Buffer
(1) = '_'
857 or else Name_Buffer
(Name_Len
) = '_'
861 -- Allow quoted character
863 elsif Name_Buffer
(1) = ''' then
866 -- All other cases, scan name
869 -- Test backwards, because we only want to test the last entity
870 -- name if the name we have is qualified with other entities.
875 -- Skip stuff between brackets (A-F OK there)
877 if Name_Buffer
(J
) = ']' then
880 exit when J
= 1 or else Name_Buffer
(J
) = '[';
883 -- Test for internal letter
885 elsif Is_OK_Internal_Letter
(Name_Buffer
(J
)) then
888 -- Quit if we come to terminating double underscore (note that
889 -- if the current character is an underscore, we know that
890 -- there is a previous character present, since we already
891 -- filtered out the case of Name_Buffer (1) = '_' above.
893 elsif Name_Buffer
(J
) = '_'
894 and then Name_Buffer
(J
- 1) = '_'
895 and then Name_Buffer
(J
- 2) /= '_'
905 end Is_Internal_Name
;
907 ---------------------------
908 -- Is_OK_Internal_Letter --
909 ---------------------------
911 function Is_OK_Internal_Letter
(C
: Character) return Boolean is
913 return C
in 'A' .. 'Z'
919 end Is_OK_Internal_Letter
;
921 ----------------------
922 -- Is_Operator_Name --
923 ----------------------
925 function Is_Operator_Name
(Id
: Name_Id
) return Boolean is
928 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
929 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
930 return Name_Chars
.Table
(S
+ 1) = 'O';
931 end Is_Operator_Name
;
937 function Is_Valid_Name
(Id
: Name_Id
) return Boolean is
939 return Id
in Name_Entries
.First
.. Name_Entries
.Last
;
946 function Length_Of_Name
(Id
: Name_Id
) return Nat
is
948 return Int
(Name_Entries
.Table
(Id
).Name_Len
);
957 Name_Chars
.Set_Last
(Name_Chars
.Last
+ Name_Chars_Reserve
);
958 Name_Entries
.Set_Last
(Name_Entries
.Last
+ Name_Entries_Reserve
);
959 Name_Chars
.Locked
:= True;
960 Name_Entries
.Locked
:= True;
962 Name_Entries
.Release
;
965 ------------------------
966 -- Name_Chars_Address --
967 ------------------------
969 function Name_Chars_Address
return System
.Address
is
971 return Name_Chars
.Table
(0)'Address;
972 end Name_Chars_Address
;
978 function Name_Enter
return Name_Id
is
981 ((Name_Chars_Index
=> Name_Chars
.Last
,
982 Name_Len
=> Short
(Name_Len
),
985 Boolean1_Info
=> False,
986 Boolean2_Info
=> False,
987 Boolean3_Info
=> False,
988 Name_Has_No_Encodings
=> False,
989 Hash_Link
=> No_Name
));
991 -- Set corresponding string entry in the Name_Chars table
993 for J
in 1 .. Name_Len
loop
994 Name_Chars
.Append
(Name_Buffer
(J
));
997 Name_Chars
.Append
(ASCII
.NUL
);
999 return Name_Entries
.Last
;
1002 --------------------------
1003 -- Name_Entries_Address --
1004 --------------------------
1006 function Name_Entries_Address
return System
.Address
is
1008 return Name_Entries
.Table
(First_Name_Id
)'Address;
1009 end Name_Entries_Address
;
1011 ------------------------
1012 -- Name_Entries_Count --
1013 ------------------------
1015 function Name_Entries_Count
return Nat
is
1017 return Int
(Name_Entries
.Last
- Name_Entries
.First
+ 1);
1018 end Name_Entries_Count
;
1024 function Name_Find
return Name_Id
is
1026 -- Id of entry in hash search, and value to be returned
1029 -- Pointer into string table
1031 Hash_Index
: Hash_Index_Type
;
1032 -- Computed hash index
1035 -- Quick handling for one character names
1037 if Name_Len
= 1 then
1038 return Name_Id
(First_Name_Id
+ Character'Pos (Name_Buffer
(1)));
1040 -- Otherwise search hash table for existing matching entry
1043 Hash_Index
:= Namet
.Hash
;
1044 New_Id
:= Hash_Table
(Hash_Index
);
1046 if New_Id
= No_Name
then
1047 Hash_Table
(Hash_Index
) := Name_Entries
.Last
+ 1;
1052 Integer (Name_Entries
.Table
(New_Id
).Name_Len
)
1057 S
:= Name_Entries
.Table
(New_Id
).Name_Chars_Index
;
1059 for J
in 1 .. Name_Len
loop
1060 if Name_Chars
.Table
(S
+ Int
(J
)) /= Name_Buffer
(J
) then
1067 -- Current entry in hash chain does not match
1070 if Name_Entries
.Table
(New_Id
).Hash_Link
/= No_Name
then
1071 New_Id
:= Name_Entries
.Table
(New_Id
).Hash_Link
;
1073 Name_Entries
.Table
(New_Id
).Hash_Link
:=
1074 Name_Entries
.Last
+ 1;
1080 -- We fall through here only if a matching entry was not found in the
1081 -- hash table. We now create a new entry in the names table. The hash
1082 -- link pointing to the new entry (Name_Entries.Last+1) has been set.
1085 ((Name_Chars_Index
=> Name_Chars
.Last
,
1086 Name_Len
=> Short
(Name_Len
),
1087 Hash_Link
=> No_Name
,
1088 Name_Has_No_Encodings
=> False,
1091 Boolean1_Info
=> False,
1092 Boolean2_Info
=> False,
1093 Boolean3_Info
=> False));
1095 -- Set corresponding string entry in the Name_Chars table
1097 for J
in 1 .. Name_Len
loop
1098 Name_Chars
.Append
(Name_Buffer
(J
));
1101 Name_Chars
.Append
(ASCII
.NUL
);
1103 return Name_Entries
.Last
;
1111 function Name_Find_Str
(S
: String) return Name_Id
is
1113 Name_Len
:= S
'Length;
1114 Name_Buffer
(1 .. Name_Len
) := S
;
1125 V2
: Name_Id
) return Boolean
1128 return T
= V1
or else
1136 V3
: Name_Id
) return Boolean
1139 return T
= V1
or else
1149 V4
: Name_Id
) return Boolean
1152 return T
= V1
or else
1164 V5
: Name_Id
) return Boolean
1167 return T
= V1
or else
1181 V6
: Name_Id
) return Boolean
1184 return T
= V1
or else
1200 V7
: Name_Id
) return Boolean
1203 return T
= V1
or else
1221 V8
: Name_Id
) return Boolean
1224 return T
= V1
or else
1244 V9
: Name_Id
) return Boolean
1247 return T
= V1
or else
1269 V10
: Name_Id
) return Boolean
1272 return T
= V1
or else
1296 V11
: Name_Id
) return Boolean
1299 return T
= V1
or else
1316 procedure Reinitialize
is
1321 -- Initialize entries for one character names
1323 for C
in Character loop
1325 ((Name_Chars_Index
=> Name_Chars
.Last
,
1329 Boolean1_Info
=> False,
1330 Boolean2_Info
=> False,
1331 Boolean3_Info
=> False,
1332 Name_Has_No_Encodings
=> True,
1333 Hash_Link
=> No_Name
));
1335 Name_Chars
.Append
(C
);
1336 Name_Chars
.Append
(ASCII
.NUL
);
1341 for J
in Hash_Index_Type
loop
1342 Hash_Table
(J
) := No_Name
;
1346 ----------------------
1347 -- Reset_Name_Table --
1348 ----------------------
1350 procedure Reset_Name_Table
is
1352 for J
in First_Name_Id
.. Name_Entries
.Last
loop
1353 Name_Entries
.Table
(J
).Int_Info
:= 0;
1354 Name_Entries
.Table
(J
).Byte_Info
:= 0;
1356 end Reset_Name_Table
;
1358 --------------------------------
1359 -- Set_Character_Literal_Name --
1360 --------------------------------
1362 procedure Set_Character_Literal_Name
(C
: Char_Code
) is
1364 Name_Buffer
(1) := 'Q';
1366 Store_Encoded_Character
(C
);
1367 end Set_Character_Literal_Name
;
1369 -----------------------------
1370 -- Set_Name_Table_Boolean1 --
1371 -----------------------------
1373 procedure Set_Name_Table_Boolean1
(Id
: Name_Id
; Val
: Boolean) is
1375 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1376 Name_Entries
.Table
(Id
).Boolean1_Info
:= Val
;
1377 end Set_Name_Table_Boolean1
;
1379 -----------------------------
1380 -- Set_Name_Table_Boolean2 --
1381 -----------------------------
1383 procedure Set_Name_Table_Boolean2
(Id
: Name_Id
; Val
: Boolean) is
1385 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1386 Name_Entries
.Table
(Id
).Boolean2_Info
:= Val
;
1387 end Set_Name_Table_Boolean2
;
1389 -----------------------------
1390 -- Set_Name_Table_Boolean3 --
1391 -----------------------------
1393 procedure Set_Name_Table_Boolean3
(Id
: Name_Id
; Val
: Boolean) is
1395 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1396 Name_Entries
.Table
(Id
).Boolean3_Info
:= Val
;
1397 end Set_Name_Table_Boolean3
;
1399 -------------------------
1400 -- Set_Name_Table_Byte --
1401 -------------------------
1403 procedure Set_Name_Table_Byte
(Id
: Name_Id
; Val
: Byte
) is
1405 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1406 Name_Entries
.Table
(Id
).Byte_Info
:= Val
;
1407 end Set_Name_Table_Byte
;
1409 -------------------------
1410 -- Set_Name_Table_Int --
1411 -------------------------
1413 procedure Set_Name_Table_Int
(Id
: Name_Id
; Val
: Int
) is
1415 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1416 Name_Entries
.Table
(Id
).Int_Info
:= Val
;
1417 end Set_Name_Table_Int
;
1419 -----------------------------
1420 -- Store_Encoded_Character --
1421 -----------------------------
1423 procedure Store_Encoded_Character
(C
: Char_Code
) is
1425 procedure Set_Hex_Chars
(C
: Char_Code
);
1426 -- Stores given value, which is in the range 0 .. 255, as two hex
1427 -- digits (using lower case a-f) in Name_Buffer, incrementing Name_Len.
1433 procedure Set_Hex_Chars
(C
: Char_Code
) is
1434 Hexd
: constant String := "0123456789abcdef";
1435 N
: constant Natural := Natural (C
);
1437 Name_Buffer
(Name_Len
+ 1) := Hexd
(N
/ 16 + 1);
1438 Name_Buffer
(Name_Len
+ 2) := Hexd
(N
mod 16 + 1);
1439 Name_Len
:= Name_Len
+ 2;
1442 -- Start of processing for Store_Encoded_Character
1445 Name_Len
:= Name_Len
+ 1;
1447 if In_Character_Range
(C
) then
1449 CC
: constant Character := Get_Character
(C
);
1451 if CC
in 'a' .. 'z' or else CC
in '0' .. '9' then
1452 Name_Buffer
(Name_Len
) := CC
;
1454 Name_Buffer
(Name_Len
) := 'U';
1459 elsif In_Wide_Character_Range
(C
) then
1460 Name_Buffer
(Name_Len
) := 'W';
1461 Set_Hex_Chars
(C
/ 256);
1462 Set_Hex_Chars
(C
mod 256);
1465 Name_Buffer
(Name_Len
) := 'W';
1466 Name_Len
:= Name_Len
+ 1;
1467 Name_Buffer
(Name_Len
) := 'W';
1468 Set_Hex_Chars
(C
/ 2 ** 24);
1469 Set_Hex_Chars
((C
/ 2 ** 16) mod 256);
1470 Set_Hex_Chars
((C
/ 256) mod 256);
1471 Set_Hex_Chars
(C
mod 256);
1473 end Store_Encoded_Character
;
1475 --------------------------------------
1476 -- Strip_Qualification_And_Suffixes --
1477 --------------------------------------
1479 procedure Strip_Qualification_And_Suffixes
is
1483 -- Strip package body qualification string off end
1485 for J
in reverse 2 .. Name_Len
loop
1486 if Name_Buffer
(J
) = 'X' then
1491 exit when Name_Buffer
(J
) /= 'b'
1492 and then Name_Buffer
(J
) /= 'n'
1493 and then Name_Buffer
(J
) /= 'p';
1496 -- Find rightmost __ or $ separator if one exists. First we position
1497 -- to start the search. If we have a character constant, position
1498 -- just before it, otherwise position to last character but one
1500 if Name_Buffer
(Name_Len
) = ''' then
1502 while J
> 0 and then Name_Buffer
(J
) /= ''' loop
1510 -- Loop to search for rightmost __ or $ (homonym) separator
1514 -- If $ separator, homonym separator, so strip it and keep looking
1516 if Name_Buffer
(J
) = '$' then
1520 -- Else check for __ found
1522 elsif Name_Buffer
(J
) = '_' and then Name_Buffer
(J
+ 1) = '_' then
1524 -- Found __ so see if digit follows, and if so, this is a
1525 -- homonym separator, so strip it and keep looking.
1527 if Name_Buffer
(J
+ 2) in '0' .. '9' then
1531 -- If not a homonym separator, then we simply strip the
1532 -- separator and everything that precedes it, and we are done
1535 Name_Buffer
(1 .. Name_Len
- J
- 1) :=
1536 Name_Buffer
(J
+ 2 .. Name_Len
);
1537 Name_Len
:= Name_Len
- J
- 1;
1545 end Strip_Qualification_And_Suffixes
;
1551 procedure Tree_Read
is
1553 Name_Chars
.Tree_Read
;
1554 Name_Entries
.Tree_Read
;
1557 (Hash_Table
'Address,
1558 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1565 procedure Tree_Write
is
1567 Name_Chars
.Tree_Write
;
1568 Name_Entries
.Tree_Write
;
1571 (Hash_Table
'Address,
1572 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1581 Name_Chars
.Set_Last
(Name_Chars
.Last
- Name_Chars_Reserve
);
1582 Name_Entries
.Set_Last
(Name_Entries
.Last
- Name_Entries_Reserve
);
1583 Name_Chars
.Locked
:= False;
1584 Name_Entries
.Locked
:= False;
1586 Name_Entries
.Release
;
1593 procedure wn
(Id
: Name_Id
) is
1597 if not Id
'Valid then
1598 Write_Str
("<invalid name_id>");
1600 elsif Id
= No_Name
then
1601 Write_Str
("<No_Name>");
1603 elsif Id
= Error_Name
then
1604 Write_Str
("<Error_Name>");
1607 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
1608 Name_Len
:= Natural (Name_Entries
.Table
(Id
).Name_Len
);
1610 for J
in 1 .. Name_Len
loop
1611 Write_Char
(Name_Chars
.Table
(S
+ Int
(J
)));
1622 procedure Write_Name
(Id
: Name_Id
) is
1624 if Id
>= First_Name_Id
then
1625 Get_Name_String
(Id
);
1626 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1630 ------------------------
1631 -- Write_Name_Decoded --
1632 ------------------------
1634 procedure Write_Name_Decoded
(Id
: Name_Id
) is
1636 if Id
>= First_Name_Id
then
1637 Get_Decoded_Name_String
(Id
);
1638 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1640 end Write_Name_Decoded
;
1642 -- Package initialization, initialize tables