1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2017, 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 pragma Style_Checks
(All_Checks
);
33 -- Subprograms not all in alpha order
35 with Atree
; use Atree
;
36 with Debug
; use Debug
;
38 with Output
; use Output
;
39 with Scans
; use Scans
;
40 with Tree_IO
; use Tree_IO
;
41 with Widechar
; use Widechar
;
43 with GNAT
.Byte_Order_Mark
; use GNAT
.Byte_Order_Mark
;
45 with System
.Storage_Elements
;
47 with System
.WCh_Con
; use System
.WCh_Con
;
49 with Unchecked_Conversion
;
50 with Unchecked_Deallocation
;
52 package body Sinput
is
56 -- Routines to support conversion between types Lines_Table_Ptr,
57 -- Logical_Lines_Table_Ptr and System.Address.
59 pragma Warnings
(Off
);
60 -- These unchecked conversions are aliasing safe, since they are never
61 -- used to construct improperly aliased pointer values.
63 function To_Address
is
64 new Unchecked_Conversion
(Lines_Table_Ptr
, Address
);
66 function To_Address
is
67 new Unchecked_Conversion
(Logical_Lines_Table_Ptr
, Address
);
69 function To_Pointer
is
70 new Unchecked_Conversion
(Address
, Lines_Table_Ptr
);
72 function To_Pointer
is
73 new Unchecked_Conversion
(Address
, Logical_Lines_Table_Ptr
);
77 -----------------------------
78 -- Source_File_Index_Table --
79 -----------------------------
81 -- The Get_Source_File_Index function is called very frequently. Earlier
82 -- versions cached a single entry, but then reverted to a serial search,
83 -- and this proved to be a significant source of inefficiency. We then
84 -- switched to using a table with a start point followed by a serial
85 -- search. Now we make sure source buffers are on a reasonable boundary
86 -- (see Types.Source_Align), and we can just use a direct look up in the
89 -- Note that this array is pretty large, but in most operating systems
90 -- it will not be allocated in physical memory unless it is actually used.
92 Source_File_Index_Table
:
93 array (Int
range 0 .. 1 + (Int
'Last / Source_Align
)) of Source_File_Index
;
95 ---------------------------
96 -- Add_Line_Tables_Entry --
97 ---------------------------
99 procedure Add_Line_Tables_Entry
100 (S
: in out Source_File_Record
;
103 LL
: Physical_Line_Number
;
106 -- Reallocate the lines tables if necessary
108 -- Note: the reason we do not use the normal Table package
109 -- mechanism is that we have several of these tables. We could
110 -- use the new GNAT.Dynamic_Tables package and that would probably
111 -- be a good idea ???
113 if S
.Last_Source_Line
= S
.Lines_Table_Max
then
116 Int
(S
.Last_Source_Line
) *
117 ((100 + Alloc
.Lines_Increment
) / 100));
120 Write_Str
("--> Reallocating lines table, size = ");
121 Write_Int
(Int
(S
.Lines_Table_Max
));
126 S
.Last_Source_Line
:= S
.Last_Source_Line
+ 1;
127 LL
:= S
.Last_Source_Line
;
129 S
.Lines_Table
(LL
) := P
;
131 -- Deal with setting new entry in logical lines table if one is
132 -- present. Note that there is always space (because the call to
133 -- Alloc_Line_Tables makes sure both tables are the same length),
135 if S
.Logical_Lines_Table
/= null then
137 -- We can always set the entry from the previous one, because
138 -- the processing for a Source_Reference pragma ensures that
139 -- at least one entry following the pragma is set up correctly.
141 S
.Logical_Lines_Table
(LL
) := S
.Logical_Lines_Table
(LL
- 1) + 1;
143 end Add_Line_Tables_Entry
;
145 -----------------------
146 -- Alloc_Line_Tables --
147 -----------------------
149 procedure Alloc_Line_Tables
150 (S
: in out Source_File_Record
;
153 subtype size_t
is Memory
.size_t
;
155 New_Table
: Lines_Table_Ptr
;
157 New_Logical_Table
: Logical_Lines_Table_Ptr
;
159 New_Size
: constant size_t
:=
160 size_t
(New_Max
* Lines_Table_Type
'Component_Size /
164 if S
.Lines_Table
= null then
165 New_Table
:= To_Pointer
(Memory
.Alloc
(New_Size
));
169 To_Pointer
(Memory
.Realloc
(To_Address
(S
.Lines_Table
), New_Size
));
172 if New_Table
= null then
175 S
.Lines_Table
:= New_Table
;
176 S
.Lines_Table_Max
:= Physical_Line_Number
(New_Max
);
179 if S
.Num_SRef_Pragmas
/= 0 then
180 if S
.Logical_Lines_Table
= null then
181 New_Logical_Table
:= To_Pointer
(Memory
.Alloc
(New_Size
));
183 New_Logical_Table
:= To_Pointer
184 (Memory
.Realloc
(To_Address
(S
.Logical_Lines_Table
), New_Size
));
187 if New_Logical_Table
= null then
190 S
.Logical_Lines_Table
:= New_Logical_Table
;
193 end Alloc_Line_Tables
;
199 procedure Backup_Line
(P
: in out Source_Ptr
) is
200 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(P
);
201 Src
: constant Source_Buffer_Ptr
:=
202 Source_File
.Table
(Sindex
).Source_Text
;
203 Sfirst
: constant Source_Ptr
:=
204 Source_File
.Table
(Sindex
).Source_First
;
214 if Src
(P
- 1) = LF
then
219 if Src
(P
- 1) = CR
then
224 -- Now find first character of the previous line
227 and then Src
(P
- 1) /= LF
228 and then Src
(P
- 1) /= CR
234 ---------------------------
235 -- Build_Location_String --
236 ---------------------------
238 procedure Build_Location_String
239 (Buf
: in out Bounded_String
;
242 Ptr
: Source_Ptr
:= Loc
;
245 -- Loop through instantiations
248 Append
(Buf
, Reference_Name
(Get_Source_File_Index
(Ptr
)));
250 Append
(Buf
, Nat
(Get_Logical_Line_Number
(Ptr
)));
252 Ptr
:= Instantiation_Location
(Ptr
);
253 exit when Ptr
= No_Location
;
254 Append
(Buf
, " instantiated at ");
256 end Build_Location_String
;
258 function Build_Location_String
(Loc
: Source_Ptr
) return String is
259 Buf
: Bounded_String
;
261 Build_Location_String
(Buf
, Loc
);
263 end Build_Location_String
;
269 procedure Check_For_BOM
is
272 Tst
: String (1 .. 5);
277 C
:= Source
(Scan_Ptr
+ Source_Ptr
(J
) - 1);
279 -- Definitely no BOM if EOF character marks either end of file, or
280 -- an illegal non-BOM character if not at the end of file.
289 Read_BOM
(Tst
, Len
, BOM
, XML_Support
=> False);
293 Scan_Ptr
:= Scan_Ptr
+ Source_Ptr
(Len
);
294 First_Non_Blank_Location
:= Scan_Ptr
;
295 Current_Line_Start
:= Scan_Ptr
;
296 Wide_Character_Encoding_Method
:= WCEM_UTF8
;
297 Upper_Half_Encoding
:= True;
303 Write_Line
("UTF-16 encoding format not recognized");
305 raise Unrecoverable_Error
;
311 Write_Line
("UTF-32 encoding format not recognized");
313 raise Unrecoverable_Error
;
323 ---------------------------------
324 -- Comes_From_Inherited_Pragma --
325 ---------------------------------
327 function Comes_From_Inherited_Pragma
(S
: Source_Ptr
) return Boolean is
328 SIE
: Source_File_Record
renames
329 Source_File
.Table
(Get_Source_File_Index
(S
));
331 return SIE
.Inherited_Pragma
;
332 end Comes_From_Inherited_Pragma
;
334 -----------------------------
335 -- Comes_From_Inlined_Body --
336 -----------------------------
338 function Comes_From_Inlined_Body
(S
: Source_Ptr
) return Boolean is
339 SIE
: Source_File_Record
renames
340 Source_File
.Table
(Get_Source_File_Index
(S
));
342 return SIE
.Inlined_Body
;
343 end Comes_From_Inlined_Body
;
345 ------------------------
346 -- Free_Source_Buffer --
347 ------------------------
349 procedure Free_Source_Buffer
(Src
: in out Source_Buffer_Ptr
) is
350 -- Unchecked_Deallocation doesn't work for access-to-constant; we need
351 -- to first Unchecked_Convert to access-to-variable.
353 function To_Source_Buffer_Ptr_Var
is new
354 Unchecked_Conversion
(Source_Buffer_Ptr
, Source_Buffer_Ptr_Var
);
356 Temp
: Source_Buffer_Ptr_Var
:= To_Source_Buffer_Ptr_Var
(Src
);
358 procedure Free_Ptr
is new
359 Unchecked_Deallocation
(Source_Buffer
, Source_Buffer_Ptr_Var
);
363 end Free_Source_Buffer
;
365 -----------------------
366 -- Get_Column_Number --
367 -----------------------
369 function Get_Column_Number
(P
: Source_Ptr
) return Column_Number
is
372 Sindex
: Source_File_Index
;
373 Src
: Source_Buffer_Ptr
;
376 -- If the input source pointer is not a meaningful value then return
377 -- at once with column number 1. This can happen for a file not found
378 -- condition for a file loaded indirectly by RTE, and also perhaps on
379 -- some unknown internal error conditions. In either case we certainly
380 -- don't want to blow up.
386 Sindex
:= Get_Source_File_Index
(P
);
387 Src
:= Source_File
.Table
(Sindex
).Source_Text
;
393 C
:= (C
- 1) / 8 * 8 + (8 + 1);
396 -- Deal with wide character case, but don't include brackets
397 -- notation in this circuit, since we know that this will
398 -- display unencoded (no one encodes brackets notation).
400 elsif Src
(S
) /= '[' and then Is_Start_Of_Wide_Char
(Src
, S
) then
404 -- Normal (non-wide) character case or brackets sequence
414 end Get_Column_Number
;
416 -----------------------------
417 -- Get_Logical_Line_Number --
418 -----------------------------
420 function Get_Logical_Line_Number
421 (P
: Source_Ptr
) return Logical_Line_Number
423 SFR
: Source_File_Record
424 renames Source_File
.Table
(Get_Source_File_Index
(P
));
426 L
: constant Physical_Line_Number
:= Get_Physical_Line_Number
(P
);
429 if SFR
.Num_SRef_Pragmas
= 0 then
430 return Logical_Line_Number
(L
);
432 return SFR
.Logical_Lines_Table
(L
);
434 end Get_Logical_Line_Number
;
436 ---------------------------------
437 -- Get_Logical_Line_Number_Img --
438 ---------------------------------
440 function Get_Logical_Line_Number_Img
441 (P
: Source_Ptr
) return String
445 Add_Nat_To_Name_Buffer
(Nat
(Get_Logical_Line_Number
(P
)));
446 return Name_Buffer
(1 .. Name_Len
);
447 end Get_Logical_Line_Number_Img
;
449 ------------------------------
450 -- Get_Physical_Line_Number --
451 ------------------------------
453 function Get_Physical_Line_Number
454 (P
: Source_Ptr
) return Physical_Line_Number
456 Sfile
: Source_File_Index
;
457 Table
: Lines_Table_Ptr
;
458 Lo
: Physical_Line_Number
;
459 Hi
: Physical_Line_Number
;
460 Mid
: Physical_Line_Number
;
464 -- If the input source pointer is not a meaningful value then return
465 -- at once with line number 1. This can happen for a file not found
466 -- condition for a file loaded indirectly by RTE, and also perhaps on
467 -- some unknown internal error conditions. In either case we certainly
468 -- don't want to blow up.
473 -- Otherwise we can do the binary search
476 Sfile
:= Get_Source_File_Index
(P
);
477 Loc
:= P
+ Source_File
.Table
(Sfile
).Sloc_Adjust
;
478 Table
:= Source_File
.Table
(Sfile
).Lines_Table
;
480 Hi
:= Source_File
.Table
(Sfile
).Last_Source_Line
;
483 Mid
:= (Lo
+ Hi
) / 2;
485 if Loc
< Table
(Mid
) then
488 else -- Loc >= Table (Mid)
491 Loc
< Table
(Mid
+ 1)
502 end Get_Physical_Line_Number
;
504 ---------------------------
505 -- Get_Source_File_Index --
506 ---------------------------
508 function Get_Source_File_Index
(S
: Source_Ptr
) return Source_File_Index
is
509 Result
: Source_File_Index
;
511 procedure Assertions
;
512 -- Assert various properties of the result
514 procedure Assertions
is
516 -- ???The old version using zero-origin array indexing without array
517 -- bounds checks returned 1 (i.e. system.ads) for these special
518 -- locations, presumably by accident. We are mimicing that here.
520 Special
: constant Boolean :=
522 or else S
= Standard_Location
523 or else S
= Standard_ASCII_Location
524 or else S
= System_Location
;
526 pragma Assert
((S
> No_Location
) xor Special
);
527 pragma Assert
(Result
in Source_File
.First
.. Source_File
.Last
);
529 SFR
: Source_File_Record
renames Source_File
.Table
(Result
);
532 -- SFR.Source_Text = null if and only if this is the SFR for a debug
533 -- output file (*.dg), and that file is under construction. S can be
534 -- slightly past Source_Last in that case because we haven't updated
537 if Null_Source_Buffer_Ptr
(SFR
.Source_Text
) then
538 pragma Assert
(S
>= SFR
.Source_First
); null;
540 pragma Assert
(SFR
.Source_Text
'First = SFR
.Source_First
);
541 pragma Assert
(SFR
.Source_Text
'Last = SFR
.Source_Last
);
544 pragma Assert
(S
in SFR
.Source_First
.. SFR
.Source_Last
);
550 -- Start of processing for Get_Source_File_Index
553 if S
> No_Location
then
554 Result
:= Source_File_Index_Table
(Int
(S
) / Source_Align
);
559 pragma Debug
(Assertions
);
562 end Get_Source_File_Index
;
568 procedure Initialize
is
570 Source_gnat_adc
:= No_Source_File
;
573 Instances
.Append
(No_Location
);
574 pragma Assert
(Instances
.Last
= No_Instance_Id
);
581 function Instantiation
(S
: SFI
) return Source_Ptr
is
582 SIE
: Source_File_Record
renames Source_File
.Table
(S
);
584 if SIE
.Inlined_Body
or SIE
.Inherited_Pragma
then
585 return SIE
.Inlined_Call
;
587 return Instances
.Table
(SIE
.Instance
);
591 -------------------------
592 -- Instantiation_Depth --
593 -------------------------
595 function Instantiation_Depth
(S
: Source_Ptr
) return Nat
is
596 Sind
: Source_File_Index
;
605 Sind
:= Get_Source_File_Index
(Sval
);
606 Sval
:= Instantiation
(Sind
);
607 exit when Sval
= No_Location
;
612 end Instantiation_Depth
;
614 ----------------------------
615 -- Instantiation_Location --
616 ----------------------------
618 function Instantiation_Location
(S
: Source_Ptr
) return Source_Ptr
is
620 return Instantiation
(Get_Source_File_Index
(S
));
621 end Instantiation_Location
;
623 --------------------------
624 -- Iterate_On_Instances --
625 --------------------------
627 procedure Iterate_On_Instances
is
629 for J
in 1 .. Instances
.Last
loop
630 Process
(J
, Instances
.Table
(J
));
632 end Iterate_On_Instances
;
634 ----------------------
635 -- Last_Source_File --
636 ----------------------
638 function Last_Source_File
return Source_File_Index
is
640 return Source_File
.Last
;
641 end Last_Source_File
;
647 function Line_Start
(P
: Source_Ptr
) return Source_Ptr
is
648 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(P
);
649 Src
: constant Source_Buffer_Ptr
:=
650 Source_File
.Table
(Sindex
).Source_Text
;
651 Sfirst
: constant Source_Ptr
:=
652 Source_File
.Table
(Sindex
).Source_First
;
658 and then Src
(S
- 1) /= CR
659 and then Src
(S
- 1) /= LF
668 (L
: Physical_Line_Number
;
669 S
: Source_File_Index
) return Source_Ptr
672 return Source_File
.Table
(S
).Lines_Table
(L
);
682 Source_File
.Locked
:= True;
685 ----------------------
686 -- Num_Source_Files --
687 ----------------------
689 function Num_Source_Files
return Nat
is
691 return Int
(Source_File
.Last
) - Int
(Source_File
.First
) + 1;
692 end Num_Source_Files
;
694 ----------------------
695 -- Num_Source_Lines --
696 ----------------------
698 function Num_Source_Lines
(S
: Source_File_Index
) return Nat
is
700 return Nat
(Source_File
.Table
(S
).Last_Source_Line
);
701 end Num_Source_Lines
;
703 -----------------------
704 -- Original_Location --
705 -----------------------
707 function Original_Location
(S
: Source_Ptr
) return Source_Ptr
is
708 Sindex
: Source_File_Index
;
709 Tindex
: Source_File_Index
;
712 if S
<= No_Location
then
716 Sindex
:= Get_Source_File_Index
(S
);
718 if Instantiation
(Sindex
) = No_Location
then
722 Tindex
:= Template
(Sindex
);
723 while Instantiation
(Tindex
) /= No_Location
loop
724 Tindex
:= Template
(Tindex
);
727 return S
- Source_First
(Sindex
) + Source_First
(Tindex
);
730 end Original_Location
;
732 -------------------------
733 -- Physical_To_Logical --
734 -------------------------
736 function Physical_To_Logical
737 (Line
: Physical_Line_Number
;
738 S
: Source_File_Index
) return Logical_Line_Number
740 SFR
: Source_File_Record
renames Source_File
.Table
(S
);
743 if SFR
.Num_SRef_Pragmas
= 0 then
744 return Logical_Line_Number
(Line
);
746 return SFR
.Logical_Lines_Table
(Line
);
748 end Physical_To_Logical
;
750 --------------------------------
751 -- Register_Source_Ref_Pragma --
752 --------------------------------
754 procedure Register_Source_Ref_Pragma
755 (File_Name
: File_Name_Type
;
756 Stripped_File_Name
: File_Name_Type
;
758 Line_After_Pragma
: Physical_Line_Number
)
760 subtype size_t
is Memory
.size_t
;
762 SFR
: Source_File_Record
renames Source_File
.Table
(Current_Source_File
);
764 ML
: Logical_Line_Number
;
767 if File_Name
/= No_File
then
768 SFR
.Reference_Name
:= Stripped_File_Name
;
769 SFR
.Full_Ref_Name
:= File_Name
;
771 if not Debug_Generated_Code
then
772 SFR
.Debug_Source_Name
:= Stripped_File_Name
;
773 SFR
.Full_Debug_Name
:= File_Name
;
776 SFR
.Num_SRef_Pragmas
:= SFR
.Num_SRef_Pragmas
+ 1;
779 if SFR
.Num_SRef_Pragmas
= 1 then
780 SFR
.First_Mapped_Line
:= Logical_Line_Number
(Mapped_Line
);
783 if SFR
.Logical_Lines_Table
= null then
784 SFR
.Logical_Lines_Table
:= To_Pointer
786 (size_t
(SFR
.Lines_Table_Max
*
787 Logical_Lines_Table_Type
'Component_Size /
791 SFR
.Logical_Lines_Table
(Line_After_Pragma
- 1) := No_Line_Number
;
793 ML
:= Logical_Line_Number
(Mapped_Line
);
794 for J
in Line_After_Pragma
.. SFR
.Last_Source_Line
loop
795 SFR
.Logical_Lines_Table
(J
) := ML
;
798 end Register_Source_Ref_Pragma
;
800 ---------------------------------
801 -- Set_Source_File_Index_Table --
802 ---------------------------------
804 procedure Set_Source_File_Index_Table
(Xnew
: Source_File_Index
) is
807 SL
: constant Source_Ptr
:= Source_File
.Table
(Xnew
).Source_Last
;
809 SP
:= Source_File
.Table
(Xnew
).Source_First
;
810 pragma Assert
(SP
mod Source_Align
= 0);
811 Ind
:= Int
(SP
) / Source_Align
;
813 Source_File_Index_Table
(Ind
) := Xnew
;
814 SP
:= SP
+ Source_Align
;
817 end Set_Source_File_Index_Table
;
819 ---------------------------
820 -- Skip_Line_Terminators --
821 ---------------------------
823 procedure Skip_Line_Terminators
824 (P
: in out Source_Ptr
;
825 Physical
: out Boolean)
827 Chr
: constant Character := Source
(P
);
831 if Source
(P
+ 1) = LF
then
840 elsif Chr
= FF
or else Chr
= VT
then
845 -- Otherwise we have a wide character
848 Skip_Wide
(Source
, P
);
851 -- Fall through in the physical line terminator case. First deal with
852 -- making a possible entry into the lines table if one is needed.
854 -- Note: we are dealing with a real source file here, this cannot be
855 -- the instantiation case, so we need not worry about Sloc adjustment.
858 S
: Source_File_Record
859 renames Source_File
.Table
(Current_Source_File
);
864 -- Make entry in lines table if not already made (in some scan backup
865 -- cases, we will be rescanning previously scanned source, so the
866 -- entry may have already been made on the previous forward scan).
869 and then P
> S
.Lines_Table
(S
.Last_Source_Line
)
871 Add_Line_Tables_Entry
(S
, P
);
874 end Skip_Line_Terminators
;
881 (Src
: System
.Address
; New_Dope
: Dope_Ptr
)
883 -- A fat pointer is a pair consisting of data pointer and dope pointer,
884 -- in that order. So we want to overwrite the second word.
885 Dope
: System
.Address
;
886 pragma Import
(Ada
, Dope
);
887 use System
.Storage_Elements
;
888 for Dope
'Address use Src
+ System
.Address
'Size / 8;
890 Dope
:= New_Dope
.all'Address;
893 procedure Free_Dope
(Src
: System
.Address
) is
895 pragma Import
(Ada
, Dope
);
896 use System
.Storage_Elements
;
897 for Dope
'Address use Src
+ System
.Address
'Size / 8;
898 procedure Free
is new Unchecked_Deallocation
(Dope_Rec
, Dope_Ptr
);
907 procedure Sloc_Range
(N
: Node_Id
; Min
, Max
: out Source_Ptr
) is
909 function Process
(N
: Node_Id
) return Traverse_Result
;
910 -- Process function for traversing the node tree
912 procedure Traverse
is new Traverse_Proc
(Process
);
918 function Process
(N
: Node_Id
) return Traverse_Result
is
919 Orig
: constant Node_Id
:= Original_Node
(N
);
922 if Sloc
(Orig
) < Min
then
923 if Sloc
(Orig
) > No_Location
then
927 elsif Sloc
(Orig
) > Max
then
928 if Sloc
(Orig
) > No_Location
then
936 -- Start of processing for Sloc_Range
948 function Source_Offset
(S
: Source_Ptr
) return Nat
is
949 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(S
);
950 Sfirst
: constant Source_Ptr
:=
951 Source_File
.Table
(Sindex
).Source_First
;
953 return Nat
(S
- Sfirst
);
956 ------------------------
957 -- Top_Level_Location --
958 ------------------------
960 function Top_Level_Location
(S
: Source_Ptr
) return Source_Ptr
is
968 Newloc
:= Instantiation_Location
(Oldloc
);
969 exit when Newloc
= No_Location
;
973 end Top_Level_Location
;
979 procedure Tree_Read
is
981 -- First we must free any old source buffer pointers
983 for J
in Source_File
.First
.. Source_File
.Last
loop
985 S
: Source_File_Record
renames Source_File
.Table
(J
);
987 if S
.Instance
= No_Instance_Id
then
988 Free_Source_Buffer
(S
.Source_Text
);
990 if S
.Lines_Table
/= null then
991 Memory
.Free
(To_Address
(S
.Lines_Table
));
992 S
.Lines_Table
:= null;
995 if S
.Logical_Lines_Table
/= null then
996 Memory
.Free
(To_Address
(S
.Logical_Lines_Table
));
997 S
.Logical_Lines_Table
:= null;
1001 Free_Dope
(S
.Source_Text
'Address);
1002 S
.Source_Text
:= null;
1007 -- Read in source file table and instance table
1009 Source_File
.Tree_Read
;
1010 Instances
.Tree_Read
;
1012 -- The pointers we read in there for the source buffer and lines table
1013 -- pointers are junk. We now read in the actual data that is referenced
1014 -- by these two fields.
1016 for J
in Source_File
.First
.. Source_File
.Last
loop
1018 S
: Source_File_Record
renames Source_File
.Table
(J
);
1020 -- Normal case (non-instantiation)
1022 if S
.Instance
= No_Instance_Id
then
1023 S
.Lines_Table
:= null;
1024 S
.Logical_Lines_Table
:= null;
1025 Alloc_Line_Tables
(S
, Int
(S
.Last_Source_Line
));
1027 for J
in 1 .. S
.Last_Source_Line
loop
1028 Tree_Read_Int
(Int
(S
.Lines_Table
(J
)));
1031 if S
.Num_SRef_Pragmas
/= 0 then
1032 for J
in 1 .. S
.Last_Source_Line
loop
1033 Tree_Read_Int
(Int
(S
.Logical_Lines_Table
(J
)));
1037 -- Allocate source buffer and read in the data
1040 T
: constant Source_Buffer_Ptr_Var
:=
1041 new Source_Buffer
(S
.Source_First
.. S
.Source_Last
);
1043 Tree_Read_Data
(T
(S
.Source_First
)'Address,
1044 Int
(S
.Source_Last
) - Int
(S
.Source_First
) + 1);
1045 S
.Source_Text
:= T
.all'Access;
1048 -- For the instantiation case, we do not read in any data. Instead
1049 -- we share the data for the generic template entry. Since the
1050 -- template always occurs first, we can safely refer to its data.
1054 ST
: Source_File_Record
renames
1055 Source_File
.Table
(S
.Template
);
1058 -- The lines tables are copied from the template entry
1060 S
.Lines_Table
:= ST
.Lines_Table
;
1061 S
.Logical_Lines_Table
:= ST
.Logical_Lines_Table
;
1063 -- The Source_Text of the instance is the same data as that
1064 -- of the template, but with different bounds.
1067 Dope
: constant Dope_Ptr
:=
1068 new Dope_Rec
'(S.Source_First, S.Source_Last);
1070 S.Source_Text := ST.Source_Text;
1071 Set_Dope (S.Source_Text'Address, Dope);
1077 Set_Source_File_Index_Table (J);
1085 procedure Tree_Write is
1087 Source_File.Tree_Write;
1088 Instances.Tree_Write;
1090 -- The pointers we wrote out there for the source buffer and lines
1091 -- table pointers are junk, we now write out the actual data that
1092 -- is referenced by these two fields.
1094 for J in Source_File.First .. Source_File.Last loop
1096 S : Source_File_Record renames Source_File.Table (J);
1099 -- For instantiations, there is nothing to do, since the data is
1100 -- shared with the generic template. When the tree is read, the
1101 -- pointers must be set, but no extra data needs to be written.
1102 -- For the normal case, write out the data of the tables.
1104 if S.Instance = No_Instance_Id then
1107 for J in 1 .. S.Last_Source_Line loop
1108 Tree_Write_Int (Int (S.Lines_Table (J)));
1111 -- Logical lines table if present
1113 if S.Num_SRef_Pragmas /= 0 then
1114 for J in 1 .. S.Last_Source_Line loop
1115 Tree_Write_Int (Int (S.Logical_Lines_Table (J)));
1122 (S.Source_Text (S.Source_First)'Address,
1123 Int (S.Source_Last) - Int (S.Source_First) + 1);
1129 --------------------
1130 -- Write_Location --
1131 --------------------
1133 procedure Write_Location (P : Source_Ptr) is
1135 if P = No_Location then
1136 Write_Str ("<no location>");
1138 elsif P <= Standard_Location then
1139 Write_Str ("<standard location>");
1143 SI : constant Source_File_Index := Get_Source_File_Index (P);
1146 Write_Name (Debug_Source_Name (SI));
1148 Write_Int (Int (Get_Logical_Line_Number (P)));
1150 Write_Int (Int (Get_Column_Number (P)));
1152 if Instantiation (SI) /= No_Location then
1154 Write_Location (Instantiation (SI));
1161 ----------------------
1162 -- Write_Time_Stamp --
1163 ----------------------
1165 procedure Write_Time_Stamp (S : Source_File_Index) is
1166 T : constant Time_Stamp_Type := Time_Stamp (S);
1179 Write_Char (T (P + 1));
1180 Write_Char (T (P + 2));
1183 Write_Char (T (P + 3));
1184 Write_Char (T (P + 4));
1187 Write_Char (T (P + 5));
1188 Write_Char (T (P + 6));
1191 Write_Char (T (P + 7));
1192 Write_Char (T (P + 8));
1195 Write_Char (T (P + 9));
1196 Write_Char (T (P + 10));
1199 Write_Char (T (P + 11));
1200 Write_Char (T (P + 12));
1201 end Write_Time_Stamp;
1203 ----------------------------------------------
1204 -- Access Subprograms for Source File Table --
1205 ----------------------------------------------
1207 function Debug_Source_Name (S : SFI) return File_Name_Type is
1209 return Source_File.Table (S).Debug_Source_Name;
1210 end Debug_Source_Name;
1212 function Instance (S : SFI) return Instance_Id is
1214 return Source_File.Table (S).Instance;
1217 function File_Name (S : SFI) return File_Name_Type is
1219 return Source_File.Table (S).File_Name;
1222 function File_Type (S : SFI) return Type_Of_File is
1224 return Source_File.Table (S).File_Type;
1227 function First_Mapped_Line (S : SFI) return Logical_Line_Number is
1229 return Source_File.Table (S).First_Mapped_Line;
1230 end First_Mapped_Line;
1232 function Full_Debug_Name (S : SFI) return File_Name_Type is
1234 return Source_File.Table (S).Full_Debug_Name;
1235 end Full_Debug_Name;
1237 function Full_File_Name (S : SFI) return File_Name_Type is
1239 return Source_File.Table (S).Full_File_Name;
1242 function Full_Ref_Name (S : SFI) return File_Name_Type is
1244 return Source_File.Table (S).Full_Ref_Name;
1247 function Identifier_Casing (S : SFI) return Casing_Type is
1249 return Source_File.Table (S).Identifier_Casing;
1250 end Identifier_Casing;
1252 function Inherited_Pragma (S : SFI) return Boolean is
1254 return Source_File.Table (S).Inherited_Pragma;
1255 end Inherited_Pragma;
1257 function Inlined_Body (S : SFI) return Boolean is
1259 return Source_File.Table (S).Inlined_Body;
1262 function Inlined_Call (S : SFI) return Source_Ptr is
1264 return Source_File.Table (S).Inlined_Call;
1267 function Keyword_Casing (S : SFI) return Casing_Type is
1269 return Source_File.Table (S).Keyword_Casing;
1272 function Last_Source_Line (S : SFI) return Physical_Line_Number is
1274 return Source_File.Table (S).Last_Source_Line;
1275 end Last_Source_Line;
1277 function License (S : SFI) return License_Type is
1279 return Source_File.Table (S).License;
1282 function Num_SRef_Pragmas (S : SFI) return Nat is
1284 return Source_File.Table (S).Num_SRef_Pragmas;
1285 end Num_SRef_Pragmas;
1287 function Reference_Name (S : SFI) return File_Name_Type is
1289 return Source_File.Table (S).Reference_Name;
1292 function Source_Checksum (S : SFI) return Word is
1294 return Source_File.Table (S).Source_Checksum;
1295 end Source_Checksum;
1297 function Source_First (S : SFI) return Source_Ptr is
1299 return Source_File.Table (S).Source_First;
1302 function Source_Last (S : SFI) return Source_Ptr is
1304 return Source_File.Table (S).Source_Last;
1307 function Source_Text (S : SFI) return Source_Buffer_Ptr is
1309 return Source_File.Table (S).Source_Text;
1312 function Template (S : SFI) return SFI is
1314 return Source_File.Table (S).Template;
1317 function Time_Stamp (S : SFI) return Time_Stamp_Type is
1319 return Source_File.Table (S).Time_Stamp;
1322 function Unit (S : SFI) return Unit_Number_Type is
1324 return Source_File.Table (S).Unit;
1327 ------------------------------------------
1328 -- Set Procedures for Source File Table --
1329 ------------------------------------------
1331 procedure Set_Identifier_Casing (S : SFI; C : Casing_Type) is
1333 Source_File.Table (S).Identifier_Casing := C;
1334 end Set_Identifier_Casing;
1336 procedure Set_Keyword_Casing (S : SFI; C : Casing_Type) is
1338 Source_File.Table (S).Keyword_Casing := C;
1339 end Set_Keyword_Casing;
1341 procedure Set_License (S : SFI; L : License_Type) is
1343 Source_File.Table (S).License := L;
1346 procedure Set_Unit (S : SFI; U : Unit_Number_Type) is
1348 Source_File.Table (S).Unit := U;
1351 ----------------------
1352 -- Trim_Lines_Table --
1353 ----------------------
1355 procedure Trim_Lines_Table (S : Source_File_Index) is
1356 Max : constant Nat := Nat (Source_File.Table (S).Last_Source_Line);
1359 -- Release allocated storage that is no longer needed
1361 Source_File.Table (S).Lines_Table := To_Pointer
1363 (To_Address (Source_File.Table (S).Lines_Table),
1365 (Max * (Lines_Table_Type'Component_Size / System.Storage_Unit))));
1366 Source_File.Table (S).Lines_Table_Max := Physical_Line_Number (Max);
1367 end Trim_Lines_Table;
1375 Source_File.Locked := False;
1376 Source_File.Release;
1383 procedure wl (P : Source_Ptr) is