1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2014, 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 Get_Name_String
(Id
);
837 return Is_Internal_Name
;
838 end Is_Internal_Name
;
840 ----------------------
841 -- Is_Internal_Name --
842 ----------------------
844 -- Version taking its input from Name_Buffer
846 function Is_Internal_Name
return Boolean is
848 if Name_Buffer
(1) = '_'
849 or else Name_Buffer
(Name_Len
) = '_'
854 -- Test backwards, because we only want to test the last entity
855 -- name if the name we have is qualified with other entities.
857 for J
in reverse 1 .. Name_Len
loop
858 if Is_OK_Internal_Letter
(Name_Buffer
(J
)) then
861 -- Quit if we come to terminating double underscore (note that
862 -- if the current character is an underscore, we know that
863 -- there is a previous character present, since we already
864 -- filtered out the case of Name_Buffer (1) = '_' above.
866 elsif Name_Buffer
(J
) = '_'
867 and then Name_Buffer
(J
- 1) = '_'
868 and then Name_Buffer
(J
- 2) /= '_'
876 end Is_Internal_Name
;
878 ---------------------------
879 -- Is_OK_Internal_Letter --
880 ---------------------------
882 function Is_OK_Internal_Letter
(C
: Character) return Boolean is
884 return C
in 'A' .. 'Z'
890 end Is_OK_Internal_Letter
;
892 ----------------------
893 -- Is_Operator_Name --
894 ----------------------
896 function Is_Operator_Name
(Id
: Name_Id
) return Boolean is
899 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
900 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
901 return Name_Chars
.Table
(S
+ 1) = 'O';
902 end Is_Operator_Name
;
908 function Is_Valid_Name
(Id
: Name_Id
) return Boolean is
910 return Id
in Name_Entries
.First
.. Name_Entries
.Last
;
917 function Length_Of_Name
(Id
: Name_Id
) return Nat
is
919 return Int
(Name_Entries
.Table
(Id
).Name_Len
);
928 Name_Chars
.Set_Last
(Name_Chars
.Last
+ Name_Chars_Reserve
);
929 Name_Entries
.Set_Last
(Name_Entries
.Last
+ Name_Entries_Reserve
);
930 Name_Chars
.Locked
:= True;
931 Name_Entries
.Locked
:= True;
933 Name_Entries
.Release
;
936 ------------------------
937 -- Name_Chars_Address --
938 ------------------------
940 function Name_Chars_Address
return System
.Address
is
942 return Name_Chars
.Table
(0)'Address;
943 end Name_Chars_Address
;
949 function Name_Enter
return Name_Id
is
952 ((Name_Chars_Index
=> Name_Chars
.Last
,
953 Name_Len
=> Short
(Name_Len
),
956 Boolean1_Info
=> False,
957 Boolean2_Info
=> False,
958 Boolean3_Info
=> False,
959 Name_Has_No_Encodings
=> False,
960 Hash_Link
=> No_Name
));
962 -- Set corresponding string entry in the Name_Chars table
964 for J
in 1 .. Name_Len
loop
965 Name_Chars
.Append
(Name_Buffer
(J
));
968 Name_Chars
.Append
(ASCII
.NUL
);
970 return Name_Entries
.Last
;
973 --------------------------
974 -- Name_Entries_Address --
975 --------------------------
977 function Name_Entries_Address
return System
.Address
is
979 return Name_Entries
.Table
(First_Name_Id
)'Address;
980 end Name_Entries_Address
;
982 ------------------------
983 -- Name_Entries_Count --
984 ------------------------
986 function Name_Entries_Count
return Nat
is
988 return Int
(Name_Entries
.Last
- Name_Entries
.First
+ 1);
989 end Name_Entries_Count
;
995 function Name_Find
return Name_Id
is
997 -- Id of entry in hash search, and value to be returned
1000 -- Pointer into string table
1002 Hash_Index
: Hash_Index_Type
;
1003 -- Computed hash index
1006 -- Quick handling for one character names
1008 if Name_Len
= 1 then
1009 return Name_Id
(First_Name_Id
+ Character'Pos (Name_Buffer
(1)));
1011 -- Otherwise search hash table for existing matching entry
1014 Hash_Index
:= Namet
.Hash
;
1015 New_Id
:= Hash_Table
(Hash_Index
);
1017 if New_Id
= No_Name
then
1018 Hash_Table
(Hash_Index
) := Name_Entries
.Last
+ 1;
1023 Integer (Name_Entries
.Table
(New_Id
).Name_Len
)
1028 S
:= Name_Entries
.Table
(New_Id
).Name_Chars_Index
;
1030 for J
in 1 .. Name_Len
loop
1031 if Name_Chars
.Table
(S
+ Int
(J
)) /= Name_Buffer
(J
) then
1038 -- Current entry in hash chain does not match
1041 if Name_Entries
.Table
(New_Id
).Hash_Link
/= No_Name
then
1042 New_Id
:= Name_Entries
.Table
(New_Id
).Hash_Link
;
1044 Name_Entries
.Table
(New_Id
).Hash_Link
:=
1045 Name_Entries
.Last
+ 1;
1051 -- We fall through here only if a matching entry was not found in the
1052 -- hash table. We now create a new entry in the names table. The hash
1053 -- link pointing to the new entry (Name_Entries.Last+1) has been set.
1056 ((Name_Chars_Index
=> Name_Chars
.Last
,
1057 Name_Len
=> Short
(Name_Len
),
1058 Hash_Link
=> No_Name
,
1059 Name_Has_No_Encodings
=> False,
1062 Boolean1_Info
=> False,
1063 Boolean2_Info
=> False,
1064 Boolean3_Info
=> False));
1066 -- Set corresponding string entry in the Name_Chars table
1068 for J
in 1 .. Name_Len
loop
1069 Name_Chars
.Append
(Name_Buffer
(J
));
1072 Name_Chars
.Append
(ASCII
.NUL
);
1074 return Name_Entries
.Last
;
1085 V2
: Name_Id
) return Boolean
1088 return T
= V1
or else
1096 V3
: Name_Id
) return Boolean
1099 return T
= V1
or else
1109 V4
: Name_Id
) return Boolean
1112 return T
= V1
or else
1124 V5
: Name_Id
) return Boolean
1127 return T
= V1
or else
1141 V6
: Name_Id
) return Boolean
1144 return T
= V1
or else
1160 V7
: Name_Id
) return Boolean
1163 return T
= V1
or else
1181 V8
: Name_Id
) return Boolean
1184 return T
= V1
or else
1204 V9
: Name_Id
) return Boolean
1207 return T
= V1
or else
1229 V10
: Name_Id
) return Boolean
1232 return T
= V1
or else
1256 V11
: Name_Id
) return Boolean
1259 return T
= V1
or else
1276 procedure Reinitialize
is
1281 -- Initialize entries for one character names
1283 for C
in Character loop
1285 ((Name_Chars_Index
=> Name_Chars
.Last
,
1289 Boolean1_Info
=> False,
1290 Boolean2_Info
=> False,
1291 Boolean3_Info
=> False,
1292 Name_Has_No_Encodings
=> True,
1293 Hash_Link
=> No_Name
));
1295 Name_Chars
.Append
(C
);
1296 Name_Chars
.Append
(ASCII
.NUL
);
1301 for J
in Hash_Index_Type
loop
1302 Hash_Table
(J
) := No_Name
;
1306 ----------------------
1307 -- Reset_Name_Table --
1308 ----------------------
1310 procedure Reset_Name_Table
is
1312 for J
in First_Name_Id
.. Name_Entries
.Last
loop
1313 Name_Entries
.Table
(J
).Int_Info
:= 0;
1314 Name_Entries
.Table
(J
).Byte_Info
:= 0;
1316 end Reset_Name_Table
;
1318 --------------------------------
1319 -- Set_Character_Literal_Name --
1320 --------------------------------
1322 procedure Set_Character_Literal_Name
(C
: Char_Code
) is
1324 Name_Buffer
(1) := 'Q';
1326 Store_Encoded_Character
(C
);
1327 end Set_Character_Literal_Name
;
1329 -----------------------------
1330 -- Set_Name_Table_Boolean1 --
1331 -----------------------------
1333 procedure Set_Name_Table_Boolean1
(Id
: Name_Id
; Val
: Boolean) is
1335 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1336 Name_Entries
.Table
(Id
).Boolean1_Info
:= Val
;
1337 end Set_Name_Table_Boolean1
;
1339 -----------------------------
1340 -- Set_Name_Table_Boolean2 --
1341 -----------------------------
1343 procedure Set_Name_Table_Boolean2
(Id
: Name_Id
; Val
: Boolean) is
1345 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1346 Name_Entries
.Table
(Id
).Boolean2_Info
:= Val
;
1347 end Set_Name_Table_Boolean2
;
1349 -----------------------------
1350 -- Set_Name_Table_Boolean3 --
1351 -----------------------------
1353 procedure Set_Name_Table_Boolean3
(Id
: Name_Id
; Val
: Boolean) is
1355 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1356 Name_Entries
.Table
(Id
).Boolean3_Info
:= Val
;
1357 end Set_Name_Table_Boolean3
;
1359 -------------------------
1360 -- Set_Name_Table_Byte --
1361 -------------------------
1363 procedure Set_Name_Table_Byte
(Id
: Name_Id
; Val
: Byte
) is
1365 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1366 Name_Entries
.Table
(Id
).Byte_Info
:= Val
;
1367 end Set_Name_Table_Byte
;
1369 -------------------------
1370 -- Set_Name_Table_Int --
1371 -------------------------
1373 procedure Set_Name_Table_Int
(Id
: Name_Id
; Val
: Int
) is
1375 pragma Assert
(Id
in Name_Entries
.First
.. Name_Entries
.Last
);
1376 Name_Entries
.Table
(Id
).Int_Info
:= Val
;
1377 end Set_Name_Table_Int
;
1379 -----------------------------
1380 -- Store_Encoded_Character --
1381 -----------------------------
1383 procedure Store_Encoded_Character
(C
: Char_Code
) is
1385 procedure Set_Hex_Chars
(C
: Char_Code
);
1386 -- Stores given value, which is in the range 0 .. 255, as two hex
1387 -- digits (using lower case a-f) in Name_Buffer, incrementing Name_Len.
1393 procedure Set_Hex_Chars
(C
: Char_Code
) is
1394 Hexd
: constant String := "0123456789abcdef";
1395 N
: constant Natural := Natural (C
);
1397 Name_Buffer
(Name_Len
+ 1) := Hexd
(N
/ 16 + 1);
1398 Name_Buffer
(Name_Len
+ 2) := Hexd
(N
mod 16 + 1);
1399 Name_Len
:= Name_Len
+ 2;
1402 -- Start of processing for Store_Encoded_Character
1405 Name_Len
:= Name_Len
+ 1;
1407 if In_Character_Range
(C
) then
1409 CC
: constant Character := Get_Character
(C
);
1411 if CC
in 'a' .. 'z' or else CC
in '0' .. '9' then
1412 Name_Buffer
(Name_Len
) := CC
;
1414 Name_Buffer
(Name_Len
) := 'U';
1419 elsif In_Wide_Character_Range
(C
) then
1420 Name_Buffer
(Name_Len
) := 'W';
1421 Set_Hex_Chars
(C
/ 256);
1422 Set_Hex_Chars
(C
mod 256);
1425 Name_Buffer
(Name_Len
) := 'W';
1426 Name_Len
:= Name_Len
+ 1;
1427 Name_Buffer
(Name_Len
) := 'W';
1428 Set_Hex_Chars
(C
/ 2 ** 24);
1429 Set_Hex_Chars
((C
/ 2 ** 16) mod 256);
1430 Set_Hex_Chars
((C
/ 256) mod 256);
1431 Set_Hex_Chars
(C
mod 256);
1433 end Store_Encoded_Character
;
1435 --------------------------------------
1436 -- Strip_Qualification_And_Suffixes --
1437 --------------------------------------
1439 procedure Strip_Qualification_And_Suffixes
is
1443 -- Strip package body qualification string off end
1445 for J
in reverse 2 .. Name_Len
loop
1446 if Name_Buffer
(J
) = 'X' then
1451 exit when Name_Buffer
(J
) /= 'b'
1452 and then Name_Buffer
(J
) /= 'n'
1453 and then Name_Buffer
(J
) /= 'p';
1456 -- Find rightmost __ or $ separator if one exists. First we position
1457 -- to start the search. If we have a character constant, position
1458 -- just before it, otherwise position to last character but one
1460 if Name_Buffer
(Name_Len
) = ''' then
1462 while J
> 0 and then Name_Buffer
(J
) /= ''' loop
1470 -- Loop to search for rightmost __ or $ (homonym) separator
1474 -- If $ separator, homonym separator, so strip it and keep looking
1476 if Name_Buffer
(J
) = '$' then
1480 -- Else check for __ found
1482 elsif Name_Buffer
(J
) = '_' and then Name_Buffer
(J
+ 1) = '_' then
1484 -- Found __ so see if digit follows, and if so, this is a
1485 -- homonym separator, so strip it and keep looking.
1487 if Name_Buffer
(J
+ 2) in '0' .. '9' then
1491 -- If not a homonym separator, then we simply strip the
1492 -- separator and everything that precedes it, and we are done
1495 Name_Buffer
(1 .. Name_Len
- J
- 1) :=
1496 Name_Buffer
(J
+ 2 .. Name_Len
);
1497 Name_Len
:= Name_Len
- J
- 1;
1505 end Strip_Qualification_And_Suffixes
;
1511 procedure Tree_Read
is
1513 Name_Chars
.Tree_Read
;
1514 Name_Entries
.Tree_Read
;
1517 (Hash_Table
'Address,
1518 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1525 procedure Tree_Write
is
1527 Name_Chars
.Tree_Write
;
1528 Name_Entries
.Tree_Write
;
1531 (Hash_Table
'Address,
1532 Hash_Table
'Length * (Hash_Table
'Component_Size / Storage_Unit
));
1541 Name_Chars
.Set_Last
(Name_Chars
.Last
- Name_Chars_Reserve
);
1542 Name_Entries
.Set_Last
(Name_Entries
.Last
- Name_Entries_Reserve
);
1543 Name_Chars
.Locked
:= False;
1544 Name_Entries
.Locked
:= False;
1546 Name_Entries
.Release
;
1553 procedure wn
(Id
: Name_Id
) is
1557 if not Id
'Valid then
1558 Write_Str
("<invalid name_id>");
1560 elsif Id
= No_Name
then
1561 Write_Str
("<No_Name>");
1563 elsif Id
= Error_Name
then
1564 Write_Str
("<Error_Name>");
1567 S
:= Name_Entries
.Table
(Id
).Name_Chars_Index
;
1568 Name_Len
:= Natural (Name_Entries
.Table
(Id
).Name_Len
);
1570 for J
in 1 .. Name_Len
loop
1571 Write_Char
(Name_Chars
.Table
(S
+ Int
(J
)));
1582 procedure Write_Name
(Id
: Name_Id
) is
1584 if Id
>= First_Name_Id
then
1585 Get_Name_String
(Id
);
1586 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1590 ------------------------
1591 -- Write_Name_Decoded --
1592 ------------------------
1594 procedure Write_Name_Decoded
(Id
: Name_Id
) is
1596 if Id
>= First_Name_Id
then
1597 Get_Decoded_Name_String
(Id
);
1598 Write_Str
(Name_Buffer
(1 .. Name_Len
));
1600 end Write_Name_Decoded
;
1602 -- Package initialization, initialize tables