OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [ada/] [namet.adb] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                                N A M E T                                 --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2005 Free Software Foundation, Inc.          --
10
--                                                                          --
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 2,  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.  See the GNU General Public License --
17
-- for  more details.  You should have  received  a copy of the GNU General --
18
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20
-- Boston, MA 02110-1301, USA.                                              --
21
--                                                                          --
22
-- As a special exception,  if other files  instantiate  generics from this --
23
-- unit, or you link  this unit with other files  to produce an executable, --
24
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
25
-- covered  by the  GNU  General  Public  License.  This exception does not --
26
-- however invalidate  any other reasons why  the executable file  might be --
27
-- covered by the  GNU Public License.                                      --
28
--                                                                          --
29
-- GNAT was originally developed  by the GNAT team at  New York University. --
30
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
31
--                                                                          --
32
------------------------------------------------------------------------------
33
 
34
--  WARNING: There is a C version of this package. Any changes to this
35
--  source file must be properly reflected in the C header file a-namet.h
36
--  which is created manually from namet.ads and namet.adb.
37
 
38
with Debug;    use Debug;
39
with Opt;      use Opt;
40
with Output;   use Output;
41
with Tree_IO;  use Tree_IO;
42
with Widechar; use Widechar;
43
 
44
package body Namet is
45
 
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.
54
 
55
   Hash_Num : constant Int := 2**12;
56
   --  Number of headers in the hash table. Current hash algorithm is closely
57
   --  tailored to this choice, so it can only be changed if a corresponding
58
   --  change is made to the hash alogorithm.
59
 
60
   Hash_Max : constant Int := Hash_Num - 1;
61
   --  Indexes in the hash header table run from 0 to Hash_Num - 1
62
 
63
   subtype Hash_Index_Type is Int range 0 .. Hash_Max;
64
   --  Range of hash index values
65
 
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.
71
 
72
   -----------------------
73
   -- Local Subprograms --
74
   -----------------------
75
 
76
   function Hash return Hash_Index_Type;
77
   pragma Inline (Hash);
78
   --  Compute hash code for name stored in Name_Buffer (length in Name_Len)
79
 
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.
86
 
87
   -----------------------------
88
   -- Add_Char_To_Name_Buffer --
89
   -----------------------------
90
 
91
   procedure Add_Char_To_Name_Buffer (C : Character) is
92
   begin
93
      if Name_Len < Name_Buffer'Last then
94
         Name_Len := Name_Len + 1;
95
         Name_Buffer (Name_Len) := C;
96
      end if;
97
   end Add_Char_To_Name_Buffer;
98
 
99
   ----------------------------
100
   -- Add_Nat_To_Name_Buffer --
101
   ----------------------------
102
 
103
   procedure Add_Nat_To_Name_Buffer (V : Nat) is
104
   begin
105
      if V >= 10 then
106
         Add_Nat_To_Name_Buffer (V / 10);
107
      end if;
108
 
109
      Add_Char_To_Name_Buffer (Character'Val (Character'Pos ('0') + V rem 10));
110
   end Add_Nat_To_Name_Buffer;
111
 
112
   ----------------------------
113
   -- Add_Str_To_Name_Buffer --
114
   ----------------------------
115
 
116
   procedure Add_Str_To_Name_Buffer (S : String) is
117
   begin
118
      for J in S'Range loop
119
         Add_Char_To_Name_Buffer (S (J));
120
      end loop;
121
   end Add_Str_To_Name_Buffer;
122
 
123
   --------------
124
   -- Finalize --
125
   --------------
126
 
127
   procedure Finalize is
128
      Max_Chain_Length : constant := 50;
129
      --  Max length of chains for which specific information is output
130
 
131
      F : array (Int range 0 .. Max_Chain_Length) of Int;
132
      --  N'th entry is number of chains of length N
133
 
134
      Probes : Int := 0;
135
      --  Used to compute average number of probes
136
 
137
      Nsyms : Int := 0;
138
      --  Number of symbols in table
139
 
140
   begin
141
      if Debug_Flag_H then
142
         for J in F'Range loop
143
            F (J) := 0;
144
         end loop;
145
 
146
         for J in Hash_Index_Type loop
147
            if Hash_Table (J) = No_Name then
148
               F (0) := F (0) + 1;
149
 
150
            else
151
               Write_Str ("Hash_Table (");
152
               Write_Int (Int (J));
153
               Write_Str (") has ");
154
 
155
               declare
156
                  C : Int := 1;
157
                  N : Name_Id;
158
                  S : Int;
159
 
160
               begin
161
                  C := 0;
162
                  N := Hash_Table (J);
163
 
164
                  while N /= No_Name loop
165
                     N := Name_Entries.Table (N).Hash_Link;
166
                     C := C + 1;
167
                  end loop;
168
 
169
                  Write_Int (C);
170
                  Write_Str (" entries");
171
                  Write_Eol;
172
 
173
                  if C < Max_Chain_Length then
174
                     F (C) := F (C) + 1;
175
                  else
176
                     F (Max_Chain_Length) := F (Max_Chain_Length) + 1;
177
                  end if;
178
 
179
                  N := Hash_Table (J);
180
 
181
                  while N /= No_Name loop
182
                     S := Name_Entries.Table (N).Name_Chars_Index;
183
                     Write_Str ("      ");
184
 
185
                     for J in 1 .. Name_Entries.Table (N).Name_Len loop
186
                        Write_Char (Name_Chars.Table (S + Int (J)));
187
                     end loop;
188
 
189
                     Write_Eol;
190
                     N := Name_Entries.Table (N).Hash_Link;
191
                  end loop;
192
               end;
193
            end if;
194
         end loop;
195
 
196
         Write_Eol;
197
 
198
         for J in Int range 0 .. Max_Chain_Length loop
199
            if F (J) /= 0 then
200
               Write_Str ("Number of hash chains of length ");
201
 
202
               if J < 10 then
203
                  Write_Char (' ');
204
               end if;
205
 
206
               Write_Int (J);
207
 
208
               if J = Max_Chain_Length then
209
                  Write_Str (" or greater");
210
               end if;
211
 
212
               Write_Str (" = ");
213
               Write_Int (F (J));
214
               Write_Eol;
215
 
216
               if J /= 0 then
217
                  Nsyms := Nsyms + F (J);
218
                  Probes := Probes + F (J) * (1 + J) * 100;
219
               end if;
220
            end if;
221
         end loop;
222
 
223
         Write_Eol;
224
         Write_Str ("Average number of probes for lookup = ");
225
         Probes := Probes / Nsyms;
226
         Write_Int (Probes / 200);
227
         Write_Char ('.');
228
         Probes := (Probes mod 200) / 2;
229
         Write_Char (Character'Val (48 + Probes / 10));
230
         Write_Char (Character'Val (48 + Probes mod 10));
231
         Write_Eol;
232
         Write_Eol;
233
      end if;
234
   end Finalize;
235
 
236
   -----------------------------
237
   -- Get_Decoded_Name_String --
238
   -----------------------------
239
 
240
   procedure Get_Decoded_Name_String (Id : Name_Id) is
241
      C : Character;
242
      P : Natural;
243
 
244
   begin
245
      Get_Name_String (Id);
246
 
247
      --  Quick loop to see if there is anything special to do
248
 
249
      P := 1;
250
      loop
251
         if P = Name_Len then
252
            return;
253
 
254
         else
255
            C := Name_Buffer (P);
256
 
257
            exit when
258
              C = 'U' or else
259
              C = 'W' or else
260
              C = 'Q' or else
261
              C = 'O';
262
 
263
            P := P + 1;
264
         end if;
265
      end loop;
266
 
267
      --  Here we have at least some encoding that we must decode
268
 
269
      Decode : declare
270
         New_Len : Natural;
271
         Old     : Positive;
272
         New_Buf : String (1 .. Name_Buffer'Last);
273
 
274
         procedure Copy_One_Character;
275
         --  Copy a character from Name_Buffer to New_Buf. Includes case
276
         --  of copying a Uhh,Whhhh,WWhhhhhhhh sequence and decoding it.
277
 
278
         function Hex (N : Natural) return Word;
279
         --  Scans past N digits using Old pointer and returns hex value
280
 
281
         procedure Insert_Character (C : Character);
282
         --  Insert a new character into output decoded name
283
 
284
         ------------------------
285
         -- Copy_One_Character --
286
         ------------------------
287
 
288
         procedure Copy_One_Character is
289
            C : Character;
290
 
291
         begin
292
            C := Name_Buffer (Old);
293
 
294
            --  U (upper half insertion case)
295
 
296
            if C = 'U'
297
              and then Old < Name_Len
298
              and then Name_Buffer (Old + 1) not in 'A' .. 'Z'
299
              and then Name_Buffer (Old + 1) /= '_'
300
            then
301
               Old := Old + 1;
302
 
303
               --  If we have upper half encoding, then we have to set an
304
               --  appropriate wide character sequence for this character.
305
 
306
               if Upper_Half_Encoding then
307
                  Widechar.Set_Wide (Char_Code (Hex (2)), New_Buf, New_Len);
308
 
309
                  --  For other encoding methods, upper half characters can
310
                  --  simply use their normal representation.
311
 
312
               else
313
                  Insert_Character (Character'Val (Hex (2)));
314
               end if;
315
 
316
            --  WW (wide wide character insertion)
317
 
318
            elsif C = 'W'
319
              and then Old < Name_Len
320
              and then Name_Buffer (Old + 1) = 'W'
321
            then
322
               Old := Old + 2;
323
               Widechar.Set_Wide (Char_Code (Hex (8)), New_Buf, New_Len);
324
 
325
            --  W (wide character insertion)
326
 
327
            elsif C = 'W'
328
              and then Old < Name_Len
329
              and then Name_Buffer (Old + 1) not in 'A' .. 'Z'
330
              and then Name_Buffer (Old + 1) /= '_'
331
            then
332
               Old := Old + 1;
333
               Widechar.Set_Wide (Char_Code (Hex (4)), New_Buf, New_Len);
334
 
335
            --  Any other character is copied unchanged
336
 
337
            else
338
               Insert_Character (C);
339
               Old := Old + 1;
340
            end if;
341
         end Copy_One_Character;
342
 
343
         ---------
344
         -- Hex --
345
         ---------
346
 
347
         function Hex (N : Natural) return Word is
348
            T : Word := 0;
349
            C : Character;
350
 
351
         begin
352
            for J in 1 .. N loop
353
               C := Name_Buffer (Old);
354
               Old := Old + 1;
355
 
356
               pragma Assert (C in '0' .. '9' or else C in 'a' .. 'f');
357
 
358
               if C <= '9' then
359
                  T := 16 * T + Character'Pos (C) - Character'Pos ('0');
360
               else -- C in 'a' .. 'f'
361
                  T := 16 * T + Character'Pos (C) - (Character'Pos ('a') - 10);
362
               end if;
363
            end loop;
364
 
365
            return T;
366
         end Hex;
367
 
368
         ----------------------
369
         -- Insert_Character --
370
         ----------------------
371
 
372
         procedure Insert_Character (C : Character) is
373
         begin
374
            New_Len := New_Len + 1;
375
            New_Buf (New_Len) := C;
376
         end Insert_Character;
377
 
378
      --  Start of processing for Decode
379
 
380
      begin
381
         New_Len := 0;
382
         Old := 1;
383
 
384
         --  Loop through characters of name
385
 
386
         while Old <= Name_Len loop
387
 
388
            --  Case of character literal, put apostrophes around character
389
 
390
            if Name_Buffer (Old) = 'Q'
391
              and then Old < Name_Len
392
            then
393
               Old := Old + 1;
394
               Insert_Character (''');
395
               Copy_One_Character;
396
               Insert_Character (''');
397
 
398
            --  Case of operator name
399
 
400
            elsif Name_Buffer (Old) = 'O'
401
              and then Old < Name_Len
402
              and then Name_Buffer (Old + 1) not in 'A' .. 'Z'
403
              and then Name_Buffer (Old + 1) /= '_'
404
            then
405
               Old := Old + 1;
406
 
407
               declare
408
                  --  This table maps the 2nd and 3rd characters of the name
409
                  --  into the required output. Two blanks means leave the
410
                  --  name alone
411
 
412
                  Map : constant String :=
413
                     "ab  " &               --  Oabs         => "abs"
414
                     "ad+ " &               --  Oadd         => "+"
415
                     "an  " &               --  Oand         => "and"
416
                     "co& " &               --  Oconcat      => "&"
417
                     "di/ " &               --  Odivide      => "/"
418
                     "eq= " &               --  Oeq          => "="
419
                     "ex**" &               --  Oexpon       => "**"
420
                     "gt> " &               --  Ogt          => ">"
421
                     "ge>=" &               --  Oge          => ">="
422
                     "le<=" &               --  Ole          => "<="
423
                     "lt< " &               --  Olt          => "<"
424
                     "mo  " &               --  Omod         => "mod"
425
                     "mu* " &               --  Omutliply    => "*"
426
                     "ne/=" &               --  One          => "/="
427
                     "no  " &               --  Onot         => "not"
428
                     "or  " &               --  Oor          => "or"
429
                     "re  " &               --  Orem         => "rem"
430
                     "su- " &               --  Osubtract    => "-"
431
                     "xo  ";                --  Oxor         => "xor"
432
 
433
                  J : Integer;
434
 
435
               begin
436
                  Insert_Character ('"');
437
 
438
                  --  Search the map. Note that this loop must terminate, if
439
                  --  not we have some kind of internal error, and a constraint
440
                  --  constraint error may be raised.
441
 
442
                  J := Map'First;
443
                  loop
444
                     exit when Name_Buffer (Old) = Map (J)
445
                       and then Name_Buffer (Old + 1) = Map (J + 1);
446
                     J := J + 4;
447
                  end loop;
448
 
449
                  --  Special operator name
450
 
451
                  if Map (J + 2) /= ' ' then
452
                     Insert_Character (Map (J + 2));
453
 
454
                     if Map (J + 3) /= ' ' then
455
                        Insert_Character (Map (J + 3));
456
                     end if;
457
 
458
                     Insert_Character ('"');
459
 
460
                     --  Skip past original operator name in input
461
 
462
                     while Old <= Name_Len
463
                       and then Name_Buffer (Old) in 'a' .. 'z'
464
                     loop
465
                        Old := Old + 1;
466
                     end loop;
467
 
468
                  --  For other operator names, leave them in lower case,
469
                  --  surrounded by apostrophes
470
 
471
                  else
472
                     --  Copy original operator name from input to output
473
 
474
                     while Old <= Name_Len
475
                        and then Name_Buffer (Old) in 'a' .. 'z'
476
                     loop
477
                        Copy_One_Character;
478
                     end loop;
479
 
480
                     Insert_Character ('"');
481
                  end if;
482
               end;
483
 
484
            --  Else copy one character and keep going
485
 
486
            else
487
               Copy_One_Character;
488
            end if;
489
         end loop;
490
 
491
         --  Copy new buffer as result
492
 
493
         Name_Len := New_Len;
494
         Name_Buffer (1 .. New_Len) := New_Buf (1 .. New_Len);
495
      end Decode;
496
   end Get_Decoded_Name_String;
497
 
498
   -------------------------------------------
499
   -- Get_Decoded_Name_String_With_Brackets --
500
   -------------------------------------------
501
 
502
   procedure Get_Decoded_Name_String_With_Brackets (Id : Name_Id) is
503
      P : Natural;
504
 
505
   begin
506
      --  Case of operator name, normal decoding is fine
507
 
508
      if Name_Buffer (1) = 'O' then
509
         Get_Decoded_Name_String (Id);
510
 
511
      --  For character literals, normal decoding is fine
512
 
513
      elsif Name_Buffer (1) = 'Q' then
514
         Get_Decoded_Name_String (Id);
515
 
516
      --  Only remaining issue is U/W/WW sequences
517
 
518
      else
519
         Get_Name_String (Id);
520
 
521
         P := 1;
522
         while P < Name_Len loop
523
            if Name_Buffer (P + 1) in 'A' .. 'Z' then
524
               P := P + 1;
525
 
526
            --  Uhh encoding
527
 
528
            elsif Name_Buffer (P) = 'U' then
529
               for J in reverse P + 3 .. P + Name_Len loop
530
                  Name_Buffer (J + 3) := Name_Buffer (J);
531
               end loop;
532
 
533
               Name_Len := Name_Len + 3;
534
               Name_Buffer (P + 3) := Name_Buffer (P + 2);
535
               Name_Buffer (P + 2) := Name_Buffer (P + 1);
536
               Name_Buffer (P)     := '[';
537
               Name_Buffer (P + 1) := '"';
538
               Name_Buffer (P + 4) := '"';
539
               Name_Buffer (P + 5) := ']';
540
               P := P + 6;
541
 
542
            --  WWhhhhhhhh encoding
543
 
544
            elsif Name_Buffer (P) = 'W'
545
              and then P + 9 <= Name_Len
546
              and then Name_Buffer (P + 1) = 'W'
547
              and then Name_Buffer (P + 2) not in 'A' .. 'Z'
548
              and then Name_Buffer (P + 2) /= '_'
549
            then
550
               Name_Buffer (P + 12 .. Name_Len + 2) :=
551
                 Name_Buffer (P + 10 .. Name_Len);
552
               Name_Buffer (P)     := '[';
553
               Name_Buffer (P + 1) := '"';
554
               Name_Buffer (P + 10) := '"';
555
               Name_Buffer (P + 11) := ']';
556
               Name_Len := Name_Len + 2;
557
               P := P + 12;
558
 
559
            --  Whhhh encoding
560
 
561
            elsif Name_Buffer (P) = 'W'
562
              and then P < Name_Len
563
              and then Name_Buffer (P + 1) not in 'A' .. 'Z'
564
              and then Name_Buffer (P + 1) /= '_'
565
            then
566
               Name_Buffer (P + 8 .. P + Name_Len + 3) :=
567
                 Name_Buffer (P + 5 .. Name_Len);
568
               Name_Buffer (P + 2 .. P + 5) := Name_Buffer (P + 1 .. P + 4);
569
               Name_Buffer (P)     := '[';
570
               Name_Buffer (P + 1) := '"';
571
               Name_Buffer (P + 6) := '"';
572
               Name_Buffer (P + 7) := ']';
573
               Name_Len := Name_Len + 3;
574
               P := P + 8;
575
 
576
            else
577
               P := P + 1;
578
            end if;
579
         end loop;
580
      end if;
581
   end Get_Decoded_Name_String_With_Brackets;
582
 
583
   ------------------------
584
   -- Get_Last_Two_Chars --
585
   ------------------------
586
 
587
   procedure Get_Last_Two_Chars (N : Name_Id; C1, C2 : out Character) is
588
      NE  : Name_Entry renames Name_Entries.Table (N);
589
      NEL : constant Int := Int (NE.Name_Len);
590
 
591
   begin
592
      if NEL >= 2 then
593
         C1 := Name_Chars.Table (NE.Name_Chars_Index + NEL - 1);
594
         C2 := Name_Chars.Table (NE.Name_Chars_Index + NEL - 0);
595
      else
596
         C1 := ASCII.NUL;
597
         C2 := ASCII.NUL;
598
      end if;
599
   end Get_Last_Two_Chars;
600
 
601
   ---------------------
602
   -- Get_Name_String --
603
   ---------------------
604
 
605
   --  Procedure version leaving result in Name_Buffer, length in Name_Len
606
 
607
   procedure Get_Name_String (Id : Name_Id) is
608
      S : Int;
609
 
610
   begin
611
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
612
 
613
      S := Name_Entries.Table (Id).Name_Chars_Index;
614
      Name_Len := Natural (Name_Entries.Table (Id).Name_Len);
615
 
616
      for J in 1 .. Name_Len loop
617
         Name_Buffer (J) := Name_Chars.Table (S + Int (J));
618
      end loop;
619
   end Get_Name_String;
620
 
621
   ---------------------
622
   -- Get_Name_String --
623
   ---------------------
624
 
625
   --  Function version returning a string
626
 
627
   function Get_Name_String (Id : Name_Id) return String is
628
      S : Int;
629
 
630
   begin
631
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
632
      S := Name_Entries.Table (Id).Name_Chars_Index;
633
 
634
      declare
635
         R : String (1 .. Natural (Name_Entries.Table (Id).Name_Len));
636
 
637
      begin
638
         for J in R'Range loop
639
            R (J) := Name_Chars.Table (S + Int (J));
640
         end loop;
641
 
642
         return R;
643
      end;
644
   end Get_Name_String;
645
 
646
   --------------------------------
647
   -- Get_Name_String_And_Append --
648
   --------------------------------
649
 
650
   procedure Get_Name_String_And_Append (Id : Name_Id) is
651
      S : Int;
652
 
653
   begin
654
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
655
 
656
      S := Name_Entries.Table (Id).Name_Chars_Index;
657
 
658
      for J in 1 .. Natural (Name_Entries.Table (Id).Name_Len) loop
659
         Name_Len := Name_Len + 1;
660
         Name_Buffer (Name_Len) := Name_Chars.Table (S + Int (J));
661
      end loop;
662
   end Get_Name_String_And_Append;
663
 
664
   -------------------------
665
   -- Get_Name_Table_Byte --
666
   -------------------------
667
 
668
   function Get_Name_Table_Byte (Id : Name_Id) return Byte is
669
   begin
670
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
671
      return Name_Entries.Table (Id).Byte_Info;
672
   end Get_Name_Table_Byte;
673
 
674
   -------------------------
675
   -- Get_Name_Table_Info --
676
   -------------------------
677
 
678
   function Get_Name_Table_Info (Id : Name_Id) return Int is
679
   begin
680
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
681
      return Name_Entries.Table (Id).Int_Info;
682
   end Get_Name_Table_Info;
683
 
684
   -----------------------------------------
685
   -- Get_Unqualified_Decoded_Name_String --
686
   -----------------------------------------
687
 
688
   procedure Get_Unqualified_Decoded_Name_String (Id : Name_Id) is
689
   begin
690
      Get_Decoded_Name_String (Id);
691
      Strip_Qualification_And_Suffixes;
692
   end Get_Unqualified_Decoded_Name_String;
693
 
694
   ---------------------------------
695
   -- Get_Unqualified_Name_String --
696
   ---------------------------------
697
 
698
   procedure Get_Unqualified_Name_String (Id : Name_Id) is
699
   begin
700
      Get_Name_String (Id);
701
      Strip_Qualification_And_Suffixes;
702
   end Get_Unqualified_Name_String;
703
 
704
   ----------
705
   -- Hash --
706
   ----------
707
 
708
   function Hash return Hash_Index_Type is
709
   begin
710
      --  For the cases of 1-12 characters, all characters participate in the
711
      --  hash. The positioning is randomized, with the bias that characters
712
      --  later on participate fully (i.e. are added towards the right side).
713
 
714
      case Name_Len is
715
 
716
         when 0 =>
717
            return 0;
718
 
719
         when 1 =>
720
            return
721
               Character'Pos (Name_Buffer (1));
722
 
723
         when 2 =>
724
            return ((
725
              Character'Pos (Name_Buffer (1))) * 64 +
726
              Character'Pos (Name_Buffer (2))) mod Hash_Num;
727
 
728
         when 3 =>
729
            return (((
730
              Character'Pos (Name_Buffer (1))) * 16 +
731
              Character'Pos (Name_Buffer (3))) * 16 +
732
              Character'Pos (Name_Buffer (2))) mod Hash_Num;
733
 
734
         when 4 =>
735
            return ((((
736
              Character'Pos (Name_Buffer (1))) * 8 +
737
              Character'Pos (Name_Buffer (2))) * 8 +
738
              Character'Pos (Name_Buffer (3))) * 8 +
739
              Character'Pos (Name_Buffer (4))) mod Hash_Num;
740
 
741
         when 5 =>
742
            return (((((
743
              Character'Pos (Name_Buffer (4))) * 8 +
744
              Character'Pos (Name_Buffer (1))) * 4 +
745
              Character'Pos (Name_Buffer (3))) * 4 +
746
              Character'Pos (Name_Buffer (5))) * 8 +
747
              Character'Pos (Name_Buffer (2))) mod Hash_Num;
748
 
749
         when 6 =>
750
            return ((((((
751
              Character'Pos (Name_Buffer (5))) * 4 +
752
              Character'Pos (Name_Buffer (1))) * 4 +
753
              Character'Pos (Name_Buffer (4))) * 4 +
754
              Character'Pos (Name_Buffer (2))) * 4 +
755
              Character'Pos (Name_Buffer (6))) * 4 +
756
              Character'Pos (Name_Buffer (3))) mod Hash_Num;
757
 
758
         when 7 =>
759
            return (((((((
760
              Character'Pos (Name_Buffer (4))) * 4 +
761
              Character'Pos (Name_Buffer (3))) * 4 +
762
              Character'Pos (Name_Buffer (1))) * 4 +
763
              Character'Pos (Name_Buffer (2))) * 2 +
764
              Character'Pos (Name_Buffer (5))) * 2 +
765
              Character'Pos (Name_Buffer (7))) * 2 +
766
              Character'Pos (Name_Buffer (6))) mod Hash_Num;
767
 
768
         when 8 =>
769
            return ((((((((
770
              Character'Pos (Name_Buffer (2))) * 4 +
771
              Character'Pos (Name_Buffer (1))) * 4 +
772
              Character'Pos (Name_Buffer (3))) * 2 +
773
              Character'Pos (Name_Buffer (5))) * 2 +
774
              Character'Pos (Name_Buffer (7))) * 2 +
775
              Character'Pos (Name_Buffer (6))) * 2 +
776
              Character'Pos (Name_Buffer (4))) * 2 +
777
              Character'Pos (Name_Buffer (8))) mod Hash_Num;
778
 
779
         when 9 =>
780
            return (((((((((
781
              Character'Pos (Name_Buffer (2))) * 4 +
782
              Character'Pos (Name_Buffer (1))) * 4 +
783
              Character'Pos (Name_Buffer (3))) * 4 +
784
              Character'Pos (Name_Buffer (4))) * 2 +
785
              Character'Pos (Name_Buffer (8))) * 2 +
786
              Character'Pos (Name_Buffer (7))) * 2 +
787
              Character'Pos (Name_Buffer (5))) * 2 +
788
              Character'Pos (Name_Buffer (6))) * 2 +
789
              Character'Pos (Name_Buffer (9))) mod Hash_Num;
790
 
791
         when 10 =>
792
            return ((((((((((
793
              Character'Pos (Name_Buffer (01))) * 2 +
794
              Character'Pos (Name_Buffer (02))) * 2 +
795
              Character'Pos (Name_Buffer (08))) * 2 +
796
              Character'Pos (Name_Buffer (03))) * 2 +
797
              Character'Pos (Name_Buffer (04))) * 2 +
798
              Character'Pos (Name_Buffer (09))) * 2 +
799
              Character'Pos (Name_Buffer (06))) * 2 +
800
              Character'Pos (Name_Buffer (05))) * 2 +
801
              Character'Pos (Name_Buffer (07))) * 2 +
802
              Character'Pos (Name_Buffer (10))) mod Hash_Num;
803
 
804
         when 11 =>
805
            return (((((((((((
806
              Character'Pos (Name_Buffer (05))) * 2 +
807
              Character'Pos (Name_Buffer (01))) * 2 +
808
              Character'Pos (Name_Buffer (06))) * 2 +
809
              Character'Pos (Name_Buffer (09))) * 2 +
810
              Character'Pos (Name_Buffer (07))) * 2 +
811
              Character'Pos (Name_Buffer (03))) * 2 +
812
              Character'Pos (Name_Buffer (08))) * 2 +
813
              Character'Pos (Name_Buffer (02))) * 2 +
814
              Character'Pos (Name_Buffer (10))) * 2 +
815
              Character'Pos (Name_Buffer (04))) * 2 +
816
              Character'Pos (Name_Buffer (11))) mod Hash_Num;
817
 
818
         when 12 =>
819
            return ((((((((((((
820
              Character'Pos (Name_Buffer (03))) * 2 +
821
              Character'Pos (Name_Buffer (02))) * 2 +
822
              Character'Pos (Name_Buffer (05))) * 2 +
823
              Character'Pos (Name_Buffer (01))) * 2 +
824
              Character'Pos (Name_Buffer (06))) * 2 +
825
              Character'Pos (Name_Buffer (04))) * 2 +
826
              Character'Pos (Name_Buffer (08))) * 2 +
827
              Character'Pos (Name_Buffer (11))) * 2 +
828
              Character'Pos (Name_Buffer (07))) * 2 +
829
              Character'Pos (Name_Buffer (09))) * 2 +
830
              Character'Pos (Name_Buffer (10))) * 2 +
831
              Character'Pos (Name_Buffer (12))) mod Hash_Num;
832
 
833
         --  Names longer than 12 characters are handled by taking the first
834
         --  6 odd numbered characters and the last 6 even numbered characters.
835
 
836
         when others => declare
837
               Even_Name_Len : constant Integer := (Name_Len) / 2 * 2;
838
         begin
839
            return ((((((((((((
840
              Character'Pos (Name_Buffer (01))) * 2 +
841
              Character'Pos (Name_Buffer (Even_Name_Len - 10))) * 2 +
842
              Character'Pos (Name_Buffer (03))) * 2 +
843
              Character'Pos (Name_Buffer (Even_Name_Len - 08))) * 2 +
844
              Character'Pos (Name_Buffer (05))) * 2 +
845
              Character'Pos (Name_Buffer (Even_Name_Len - 06))) * 2 +
846
              Character'Pos (Name_Buffer (07))) * 2 +
847
              Character'Pos (Name_Buffer (Even_Name_Len - 04))) * 2 +
848
              Character'Pos (Name_Buffer (09))) * 2 +
849
              Character'Pos (Name_Buffer (Even_Name_Len - 02))) * 2 +
850
              Character'Pos (Name_Buffer (11))) * 2 +
851
              Character'Pos (Name_Buffer (Even_Name_Len))) mod Hash_Num;
852
         end;
853
      end case;
854
   end Hash;
855
 
856
   ----------------
857
   -- Initialize --
858
   ----------------
859
 
860
   procedure Initialize is
861
   begin
862
      Name_Chars.Init;
863
      Name_Entries.Init;
864
 
865
      --  Initialize entries for one character names
866
 
867
      for C in Character loop
868
         Name_Entries.Increment_Last;
869
         Name_Entries.Table (Name_Entries.Last).Name_Chars_Index :=
870
           Name_Chars.Last;
871
         Name_Entries.Table (Name_Entries.Last).Name_Len  := 1;
872
         Name_Entries.Table (Name_Entries.Last).Hash_Link := No_Name;
873
         Name_Entries.Table (Name_Entries.Last).Int_Info  := 0;
874
         Name_Entries.Table (Name_Entries.Last).Byte_Info := 0;
875
         Name_Chars.Increment_Last;
876
         Name_Chars.Table (Name_Chars.Last) := C;
877
         Name_Chars.Increment_Last;
878
         Name_Chars.Table (Name_Chars.Last) := ASCII.NUL;
879
      end loop;
880
 
881
      --  Clear hash table
882
 
883
      for J in Hash_Index_Type loop
884
         Hash_Table (J) := No_Name;
885
      end loop;
886
   end Initialize;
887
 
888
   ----------------------
889
   -- Is_Internal_Name --
890
   ----------------------
891
 
892
   --  Version taking an argument
893
 
894
   function Is_Internal_Name (Id : Name_Id) return Boolean is
895
   begin
896
      Get_Name_String (Id);
897
      return Is_Internal_Name;
898
   end Is_Internal_Name;
899
 
900
   ----------------------
901
   -- Is_Internal_Name --
902
   ----------------------
903
 
904
   --  Version taking its input from Name_Buffer
905
 
906
   function Is_Internal_Name return Boolean is
907
   begin
908
      if Name_Buffer (1) = '_'
909
        or else Name_Buffer (Name_Len) = '_'
910
      then
911
         return True;
912
 
913
      else
914
         --  Test backwards, because we only want to test the last entity
915
         --  name if the name we have is qualified with other entities.
916
 
917
         for J in reverse 1 .. Name_Len loop
918
            if Is_OK_Internal_Letter (Name_Buffer (J)) then
919
               return True;
920
 
921
            --  Quit if we come to terminating double underscore (note that
922
            --  if the current character is an underscore, we know that
923
            --  there is a previous character present, since we already
924
            --  filtered out the case of Name_Buffer (1) = '_' above.
925
 
926
            elsif Name_Buffer (J) = '_'
927
              and then Name_Buffer (J - 1) = '_'
928
              and then Name_Buffer (J - 2) /= '_'
929
            then
930
               return False;
931
            end if;
932
         end loop;
933
      end if;
934
 
935
      return False;
936
   end Is_Internal_Name;
937
 
938
   ---------------------------
939
   -- Is_OK_Internal_Letter --
940
   ---------------------------
941
 
942
   function Is_OK_Internal_Letter (C : Character) return Boolean is
943
   begin
944
      return C in 'A' .. 'Z'
945
        and then C /= 'O'
946
        and then C /= 'Q'
947
        and then C /= 'U'
948
        and then C /= 'W'
949
        and then C /= 'X';
950
   end Is_OK_Internal_Letter;
951
 
952
   ----------------------
953
   -- Is_Operator_Name --
954
   ----------------------
955
 
956
   function Is_Operator_Name (Id : Name_Id) return Boolean is
957
      S : Int;
958
   begin
959
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
960
      S := Name_Entries.Table (Id).Name_Chars_Index;
961
      return Name_Chars.Table (S + 1) = 'O';
962
   end Is_Operator_Name;
963
 
964
   --------------------
965
   -- Length_Of_Name --
966
   --------------------
967
 
968
   function Length_Of_Name (Id : Name_Id) return Nat is
969
   begin
970
      return Int (Name_Entries.Table (Id).Name_Len);
971
   end Length_Of_Name;
972
 
973
   ----------
974
   -- Lock --
975
   ----------
976
 
977
   procedure Lock is
978
   begin
979
      Name_Chars.Set_Last (Name_Chars.Last + Name_Chars_Reserve);
980
      Name_Entries.Set_Last (Name_Entries.Last + Name_Entries_Reserve);
981
      Name_Chars.Locked := True;
982
      Name_Entries.Locked := True;
983
      Name_Chars.Release;
984
      Name_Entries.Release;
985
   end Lock;
986
 
987
   ------------------------
988
   -- Name_Chars_Address --
989
   ------------------------
990
 
991
   function Name_Chars_Address return System.Address is
992
   begin
993
      return Name_Chars.Table (0)'Address;
994
   end Name_Chars_Address;
995
 
996
   ----------------
997
   -- Name_Enter --
998
   ----------------
999
 
1000
   function Name_Enter return Name_Id is
1001
   begin
1002
      Name_Entries.Increment_Last;
1003
      Name_Entries.Table (Name_Entries.Last).Name_Chars_Index :=
1004
        Name_Chars.Last;
1005
      Name_Entries.Table (Name_Entries.Last).Name_Len  := Short (Name_Len);
1006
      Name_Entries.Table (Name_Entries.Last).Hash_Link := No_Name;
1007
      Name_Entries.Table (Name_Entries.Last).Int_Info  := 0;
1008
      Name_Entries.Table (Name_Entries.Last).Byte_Info := 0;
1009
 
1010
      --  Set corresponding string entry in the Name_Chars table
1011
 
1012
      for J in 1 .. Name_Len loop
1013
         Name_Chars.Increment_Last;
1014
         Name_Chars.Table (Name_Chars.Last) := Name_Buffer (J);
1015
      end loop;
1016
 
1017
      Name_Chars.Increment_Last;
1018
      Name_Chars.Table (Name_Chars.Last) := ASCII.NUL;
1019
 
1020
      return Name_Entries.Last;
1021
   end Name_Enter;
1022
 
1023
   --------------------------
1024
   -- Name_Entries_Address --
1025
   --------------------------
1026
 
1027
   function Name_Entries_Address return System.Address is
1028
   begin
1029
      return Name_Entries.Table (First_Name_Id)'Address;
1030
   end Name_Entries_Address;
1031
 
1032
   ------------------------
1033
   -- Name_Entries_Count --
1034
   ------------------------
1035
 
1036
   function Name_Entries_Count return Nat is
1037
   begin
1038
      return Int (Name_Entries.Last - Name_Entries.First + 1);
1039
   end Name_Entries_Count;
1040
 
1041
   ---------------
1042
   -- Name_Find --
1043
   ---------------
1044
 
1045
   function Name_Find return Name_Id is
1046
      New_Id : Name_Id;
1047
      --  Id of entry in hash search, and value to be returned
1048
 
1049
      S : Int;
1050
      --  Pointer into string table
1051
 
1052
      Hash_Index : Hash_Index_Type;
1053
      --  Computed hash index
1054
 
1055
   begin
1056
      --  Quick handling for one character names
1057
 
1058
      if Name_Len = 1 then
1059
         return Name_Id (First_Name_Id + Character'Pos (Name_Buffer (1)));
1060
 
1061
      --  Otherwise search hash table for existing matching entry
1062
 
1063
      else
1064
         Hash_Index := Namet.Hash;
1065
         New_Id := Hash_Table (Hash_Index);
1066
 
1067
         if New_Id = No_Name then
1068
            Hash_Table (Hash_Index) := Name_Entries.Last + 1;
1069
 
1070
         else
1071
            Search : loop
1072
               if Name_Len /=
1073
                 Integer (Name_Entries.Table (New_Id).Name_Len)
1074
               then
1075
                  goto No_Match;
1076
               end if;
1077
 
1078
               S := Name_Entries.Table (New_Id).Name_Chars_Index;
1079
 
1080
               for J in 1 .. Name_Len loop
1081
                  if Name_Chars.Table (S + Int (J)) /= Name_Buffer (J) then
1082
                     goto No_Match;
1083
                  end if;
1084
               end loop;
1085
 
1086
               return New_Id;
1087
 
1088
               --  Current entry in hash chain does not match
1089
 
1090
               <<No_Match>>
1091
                  if Name_Entries.Table (New_Id).Hash_Link /= No_Name then
1092
                     New_Id := Name_Entries.Table (New_Id).Hash_Link;
1093
                  else
1094
                     Name_Entries.Table (New_Id).Hash_Link :=
1095
                       Name_Entries.Last + 1;
1096
                     exit Search;
1097
                  end if;
1098
 
1099
            end loop Search;
1100
         end if;
1101
 
1102
         --  We fall through here only if a matching entry was not found in the
1103
         --  hash table. We now create a new entry in the names table. The hash
1104
         --  link pointing to the new entry (Name_Entries.Last+1) has been set.
1105
 
1106
         Name_Entries.Increment_Last;
1107
         Name_Entries.Table (Name_Entries.Last).Name_Chars_Index :=
1108
           Name_Chars.Last;
1109
         Name_Entries.Table (Name_Entries.Last).Name_Len  := Short (Name_Len);
1110
         Name_Entries.Table (Name_Entries.Last).Hash_Link := No_Name;
1111
         Name_Entries.Table (Name_Entries.Last).Int_Info  := 0;
1112
         Name_Entries.Table (Name_Entries.Last).Byte_Info := 0;
1113
 
1114
         --  Set corresponding string entry in the Name_Chars table
1115
 
1116
         for J in 1 .. Name_Len loop
1117
            Name_Chars.Increment_Last;
1118
            Name_Chars.Table (Name_Chars.Last) := Name_Buffer (J);
1119
         end loop;
1120
 
1121
         Name_Chars.Increment_Last;
1122
         Name_Chars.Table (Name_Chars.Last) := ASCII.NUL;
1123
 
1124
         return Name_Entries.Last;
1125
      end if;
1126
   end Name_Find;
1127
 
1128
   ----------------------
1129
   -- Reset_Name_Table --
1130
   ----------------------
1131
 
1132
   procedure Reset_Name_Table is
1133
   begin
1134
      for J in First_Name_Id .. Name_Entries.Last loop
1135
         Name_Entries.Table (J).Int_Info  := 0;
1136
         Name_Entries.Table (J).Byte_Info := 0;
1137
      end loop;
1138
   end Reset_Name_Table;
1139
 
1140
   --------------------------------
1141
   -- Set_Character_Literal_Name --
1142
   --------------------------------
1143
 
1144
   procedure Set_Character_Literal_Name (C : Char_Code) is
1145
   begin
1146
      Name_Buffer (1) := 'Q';
1147
      Name_Len := 1;
1148
      Store_Encoded_Character (C);
1149
   end Set_Character_Literal_Name;
1150
 
1151
   -------------------------
1152
   -- Set_Name_Table_Byte --
1153
   -------------------------
1154
 
1155
   procedure Set_Name_Table_Byte (Id : Name_Id; Val : Byte) is
1156
   begin
1157
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
1158
      Name_Entries.Table (Id).Byte_Info := Val;
1159
   end Set_Name_Table_Byte;
1160
 
1161
   -------------------------
1162
   -- Set_Name_Table_Info --
1163
   -------------------------
1164
 
1165
   procedure Set_Name_Table_Info (Id : Name_Id; Val : Int) is
1166
   begin
1167
      pragma Assert (Id in Name_Entries.First .. Name_Entries.Last);
1168
      Name_Entries.Table (Id).Int_Info := Val;
1169
   end Set_Name_Table_Info;
1170
 
1171
   -----------------------------
1172
   -- Store_Encoded_Character --
1173
   -----------------------------
1174
 
1175
   procedure Store_Encoded_Character (C : Char_Code) is
1176
 
1177
      procedure Set_Hex_Chars (C : Char_Code);
1178
      --  Stores given value, which is in the range 0 .. 255, as two hex
1179
      --  digits (using lower case a-f) in Name_Buffer, incrementing Name_Len.
1180
 
1181
      -------------------
1182
      -- Set_Hex_Chars --
1183
      -------------------
1184
 
1185
      procedure Set_Hex_Chars (C : Char_Code) is
1186
         Hexd : constant String := "0123456789abcdef";
1187
         N    : constant Natural := Natural (C);
1188
      begin
1189
         Name_Buffer (Name_Len + 1) := Hexd (N / 16 + 1);
1190
         Name_Buffer (Name_Len + 2) := Hexd (N mod 16 + 1);
1191
         Name_Len := Name_Len + 2;
1192
      end Set_Hex_Chars;
1193
 
1194
   --  Start of processing for Store_Encoded_Character
1195
 
1196
   begin
1197
      Name_Len := Name_Len + 1;
1198
 
1199
      if In_Character_Range (C) then
1200
         declare
1201
            CC : constant Character := Get_Character (C);
1202
         begin
1203
            if CC in 'a' .. 'z' or else CC in '0' .. '9' then
1204
               Name_Buffer (Name_Len) := CC;
1205
            else
1206
               Name_Buffer (Name_Len) := 'U';
1207
               Set_Hex_Chars (C);
1208
            end if;
1209
         end;
1210
 
1211
      elsif In_Wide_Character_Range (C) then
1212
         Name_Buffer (Name_Len) := 'W';
1213
         Set_Hex_Chars (C / 256);
1214
         Set_Hex_Chars (C mod 256);
1215
 
1216
      else
1217
         Name_Buffer (Name_Len) := 'W';
1218
         Name_Len := Name_Len + 1;
1219
         Name_Buffer (Name_Len) := 'W';
1220
         Set_Hex_Chars (C / 2 ** 24);
1221
         Set_Hex_Chars ((C / 2 ** 16) mod 256);
1222
         Set_Hex_Chars ((C / 256) mod 256);
1223
         Set_Hex_Chars (C mod 256);
1224
      end if;
1225
   end Store_Encoded_Character;
1226
 
1227
   --------------------------------------
1228
   -- Strip_Qualification_And_Suffixes --
1229
   --------------------------------------
1230
 
1231
   procedure Strip_Qualification_And_Suffixes is
1232
      J : Integer;
1233
 
1234
   begin
1235
      --  Strip package body qualification string off end
1236
 
1237
      for J in reverse 2 .. Name_Len loop
1238
         if Name_Buffer (J) = 'X' then
1239
            Name_Len := J - 1;
1240
            exit;
1241
         end if;
1242
 
1243
         exit when Name_Buffer (J) /= 'b'
1244
           and then Name_Buffer (J) /= 'n'
1245
           and then Name_Buffer (J) /= 'p';
1246
      end loop;
1247
 
1248
      --  Find rightmost __ or $ separator if one exists. First we position
1249
      --  to start the search. If we have a character constant, position
1250
      --  just before it, otherwise position to last character but one
1251
 
1252
      if Name_Buffer (Name_Len) = ''' then
1253
         J := Name_Len - 2;
1254
         while J > 0 and then Name_Buffer (J) /= ''' loop
1255
            J := J - 1;
1256
         end loop;
1257
 
1258
      else
1259
         J := Name_Len - 1;
1260
      end if;
1261
 
1262
      --  Loop to search for rightmost __ or $ (homonym) separator
1263
 
1264
      while J > 1 loop
1265
 
1266
         --  If $ separator, homonym separator, so strip it and keep looking
1267
 
1268
         if Name_Buffer (J) = '$' then
1269
            Name_Len := J - 1;
1270
            J := Name_Len - 1;
1271
 
1272
         --  Else check for __ found
1273
 
1274
         elsif Name_Buffer (J) = '_' and then Name_Buffer (J + 1) = '_' then
1275
 
1276
            --  Found __ so see if digit follows, and if so, this is a
1277
            --  homonym separator, so strip it and keep looking.
1278
 
1279
            if Name_Buffer (J + 2) in '0' .. '9' then
1280
               Name_Len := J - 1;
1281
               J := Name_Len - 1;
1282
 
1283
            --  If not a homonym separator, then we simply strip the
1284
            --  separator and everything that precedes it, and we are done
1285
 
1286
            else
1287
               Name_Buffer (1 .. Name_Len - J - 1) :=
1288
                 Name_Buffer (J + 2 .. Name_Len);
1289
               Name_Len := Name_Len - J - 1;
1290
               exit;
1291
            end if;
1292
 
1293
         else
1294
            J := J - 1;
1295
         end if;
1296
      end loop;
1297
   end Strip_Qualification_And_Suffixes;
1298
 
1299
   ---------------
1300
   -- Tree_Read --
1301
   ---------------
1302
 
1303
   procedure Tree_Read is
1304
   begin
1305
      Name_Chars.Tree_Read;
1306
      Name_Entries.Tree_Read;
1307
 
1308
      Tree_Read_Data
1309
        (Hash_Table'Address,
1310
         Hash_Table'Length * (Hash_Table'Component_Size / Storage_Unit));
1311
   end Tree_Read;
1312
 
1313
   ----------------
1314
   -- Tree_Write --
1315
   ----------------
1316
 
1317
   procedure Tree_Write is
1318
   begin
1319
      Name_Chars.Tree_Write;
1320
      Name_Entries.Tree_Write;
1321
 
1322
      Tree_Write_Data
1323
        (Hash_Table'Address,
1324
         Hash_Table'Length * (Hash_Table'Component_Size / Storage_Unit));
1325
   end Tree_Write;
1326
 
1327
   ------------
1328
   -- Unlock --
1329
   ------------
1330
 
1331
   procedure Unlock is
1332
   begin
1333
      Name_Chars.Set_Last (Name_Chars.Last - Name_Chars_Reserve);
1334
      Name_Entries.Set_Last (Name_Entries.Last - Name_Entries_Reserve);
1335
      Name_Chars.Locked := False;
1336
      Name_Entries.Locked := False;
1337
      Name_Chars.Release;
1338
      Name_Entries.Release;
1339
   end Unlock;
1340
 
1341
   --------
1342
   -- wn --
1343
   --------
1344
 
1345
   procedure wn (Id : Name_Id) is
1346
   begin
1347
      Write_Name (Id);
1348
      Write_Eol;
1349
   end wn;
1350
 
1351
   ----------------
1352
   -- Write_Name --
1353
   ----------------
1354
 
1355
   procedure Write_Name (Id : Name_Id) is
1356
   begin
1357
      if Id >= First_Name_Id then
1358
         Get_Name_String (Id);
1359
         Write_Str (Name_Buffer (1 .. Name_Len));
1360
      end if;
1361
   end Write_Name;
1362
 
1363
   ------------------------
1364
   -- Write_Name_Decoded --
1365
   ------------------------
1366
 
1367
   procedure Write_Name_Decoded (Id : Name_Id) is
1368
   begin
1369
      if Id >= First_Name_Id then
1370
         Get_Decoded_Name_String (Id);
1371
         Write_Str (Name_Buffer (1 .. Name_Len));
1372
      end if;
1373
   end Write_Name_Decoded;
1374
 
1375
end Namet;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.