1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2023, 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. 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 pragma Style_Checks
(All_Checks
);
27 -- Subprograms not all in alpha order
29 with Atree
; use Atree
;
30 with Debug
; use Debug
;
32 with Output
; use Output
;
33 with Scans
; use Scans
;
34 with Sinfo
; use Sinfo
;
35 with Sinfo
.Nodes
; use Sinfo
.Nodes
;
36 with Widechar
; use Widechar
;
38 with GNAT
.Byte_Order_Mark
; use GNAT
.Byte_Order_Mark
;
40 with System
.Storage_Elements
;
42 with System
.WCh_Con
; use System
.WCh_Con
;
44 with Ada
.Unchecked_Conversion
;
45 with Ada
.Unchecked_Deallocation
;
47 package body Sinput
is
51 -- Routines to support conversion between types Lines_Table_Ptr,
52 -- Logical_Lines_Table_Ptr and System.Address.
54 pragma Warnings
(Off
);
55 -- These unchecked conversions are aliasing safe, since they are never
56 -- used to construct improperly aliased pointer values.
58 function To_Address
is
59 new Ada
.Unchecked_Conversion
(Lines_Table_Ptr
, Address
);
61 function To_Address
is
62 new Ada
.Unchecked_Conversion
(Logical_Lines_Table_Ptr
, Address
);
64 function To_Pointer
is
65 new Ada
.Unchecked_Conversion
(Address
, Lines_Table_Ptr
);
67 function To_Pointer
is
68 new Ada
.Unchecked_Conversion
(Address
, Logical_Lines_Table_Ptr
);
72 -----------------------------
73 -- Source_File_Index_Table --
74 -----------------------------
76 -- The Get_Source_File_Index function is called very frequently. Earlier
77 -- versions cached a single entry, but then reverted to a serial search,
78 -- and this proved to be a significant source of inefficiency. We then
79 -- switched to using a table with a start point followed by a serial
80 -- search. Now we make sure source buffers are on a reasonable boundary
81 -- (see Types.Source_Align), and we can just use a direct look up in the
84 -- Note that this array is pretty large, but in most operating systems
85 -- it will not be allocated in physical memory unless it is actually used.
87 Source_File_Index_Table
:
88 array (Int
range 0 .. 1 + (Int
'Last / Source_Align
)) of Source_File_Index
;
90 ---------------------------
91 -- Add_Line_Tables_Entry --
92 ---------------------------
94 procedure Add_Line_Tables_Entry
95 (S
: in out Source_File_Record
;
98 LL
: Physical_Line_Number
;
101 -- Reallocate the lines tables if necessary
103 -- Note: the reason we do not use the normal Table package
104 -- mechanism is that we have several of these tables. We could
105 -- use the new GNAT.Dynamic_Tables package and that would probably
106 -- be a good idea ???
108 if S
.Last_Source_Line
= S
.Lines_Table_Max
then
111 Int
(S
.Last_Source_Line
) *
112 ((100 + Alloc
.Lines_Increment
) / 100));
115 Write_Str
("--> Reallocating lines table, size = ");
116 Write_Int
(Int
(S
.Lines_Table_Max
));
121 S
.Last_Source_Line
:= S
.Last_Source_Line
+ 1;
122 LL
:= S
.Last_Source_Line
;
124 S
.Lines_Table
(LL
) := P
;
126 -- Deal with setting new entry in logical lines table if one is
127 -- present. Note that there is always space (because the call to
128 -- Alloc_Line_Tables makes sure both tables are the same length),
130 if S
.Logical_Lines_Table
/= null then
132 -- We can always set the entry from the previous one, because
133 -- the processing for a Source_Reference pragma ensures that
134 -- at least one entry following the pragma is set up correctly.
136 S
.Logical_Lines_Table
(LL
) := S
.Logical_Lines_Table
(LL
- 1) + 1;
138 end Add_Line_Tables_Entry
;
140 -----------------------
141 -- Alloc_Line_Tables --
142 -----------------------
144 procedure Alloc_Line_Tables
145 (S
: in out Source_File_Record
;
148 subtype size_t
is Memory
.size_t
;
150 New_Table
: Lines_Table_Ptr
;
152 New_Logical_Table
: Logical_Lines_Table_Ptr
;
154 New_Size
: constant size_t
:=
155 size_t
(New_Max
* Lines_Table_Type
'Component_Size /
159 if S
.Lines_Table
= null then
160 New_Table
:= To_Pointer
(Memory
.Alloc
(New_Size
));
164 To_Pointer
(Memory
.Realloc
(To_Address
(S
.Lines_Table
), New_Size
));
167 if New_Table
= null then
170 S
.Lines_Table
:= New_Table
;
171 S
.Lines_Table_Max
:= Physical_Line_Number
(New_Max
);
174 if S
.Num_SRef_Pragmas
/= 0 then
175 if S
.Logical_Lines_Table
= null then
176 New_Logical_Table
:= To_Pointer
(Memory
.Alloc
(New_Size
));
178 New_Logical_Table
:= To_Pointer
179 (Memory
.Realloc
(To_Address
(S
.Logical_Lines_Table
), New_Size
));
182 if New_Logical_Table
= null then
185 S
.Logical_Lines_Table
:= New_Logical_Table
;
188 end Alloc_Line_Tables
;
194 procedure Backup_Line
(P
: in out Source_Ptr
) is
195 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(P
);
196 Src
: constant Source_Buffer_Ptr
:=
197 Source_File
.Table
(Sindex
).Source_Text
;
198 Sfirst
: constant Source_Ptr
:=
199 Source_File
.Table
(Sindex
).Source_First
;
209 if Src
(P
- 1) = LF
then
214 if Src
(P
- 1) = CR
then
219 -- Now find first character of the previous line
222 and then Src
(P
- 1) /= LF
223 and then Src
(P
- 1) /= CR
229 ---------------------------
230 -- Build_Location_String --
231 ---------------------------
233 procedure Build_Location_String
234 (Buf
: in out Bounded_String
;
237 Ptr
: Source_Ptr
:= Loc
;
240 -- Loop through instantiations
243 Append
(Buf
, Reference_Name
(Get_Source_File_Index
(Ptr
)));
245 Append
(Buf
, Nat
(Get_Logical_Line_Number
(Ptr
)));
247 Ptr
:= Instantiation_Location
(Ptr
);
248 exit when Ptr
= No_Location
;
249 Append
(Buf
, " instantiated at ");
251 end Build_Location_String
;
253 function Build_Location_String
(Loc
: Source_Ptr
) return String is
254 Buf
: Bounded_String
;
256 Build_Location_String
(Buf
, Loc
);
258 end Build_Location_String
;
264 procedure Check_For_BOM
is
267 Tst
: String (1 .. 5);
272 C
:= Source
(Scan_Ptr
+ Source_Ptr
(J
) - 1);
274 -- Definitely no BOM if EOF character marks either end of file, or
275 -- an illegal non-BOM character if not at the end of file.
284 Read_BOM
(Tst
, Len
, BOM
, XML_Support
=> False);
288 Scan_Ptr
:= Scan_Ptr
+ Source_Ptr
(Len
);
289 First_Non_Blank_Location
:= Scan_Ptr
;
290 Current_Line_Start
:= Scan_Ptr
;
291 Wide_Character_Encoding_Method
:= WCEM_UTF8
;
292 Upper_Half_Encoding
:= True;
298 Write_Line
("UTF-16 encoding format not recognized");
300 raise Unrecoverable_Error
;
306 Write_Line
("UTF-32 encoding format not recognized");
308 raise Unrecoverable_Error
;
318 -----------------------------
319 -- Clear_Source_File_Table --
320 -----------------------------
322 procedure Free
is new Ada
.Unchecked_Deallocation
323 (Lines_Table_Type
, Lines_Table_Ptr
);
325 procedure Free
is new Ada
.Unchecked_Deallocation
326 (Logical_Lines_Table_Type
, Logical_Lines_Table_Ptr
);
328 procedure Clear_Source_File_Table
is
330 for X
in 1 .. Source_File
.Last
loop
332 S
: Source_File_Record
renames Source_File
.Table
(X
);
334 if S
.Instance
= No_Instance_Id
then
335 Free_Source_Buffer
(S
.Source_Text
);
337 Free_Dope
(S
.Source_Text
'Address);
338 S
.Source_Text
:= null;
341 Free
(S
.Lines_Table
);
342 Free
(S
.Logical_Lines_Table
);
348 end Clear_Source_File_Table
;
350 ---------------------------------
351 -- Comes_From_Inherited_Pragma --
352 ---------------------------------
354 function Comes_From_Inherited_Pragma
(S
: Source_Ptr
) return Boolean is
355 SIE
: Source_File_Record
renames
356 Source_File
.Table
(Get_Source_File_Index
(S
));
358 return SIE
.Inherited_Pragma
;
359 end Comes_From_Inherited_Pragma
;
361 -----------------------------
362 -- Comes_From_Inlined_Body --
363 -----------------------------
365 function Comes_From_Inlined_Body
(S
: Source_Ptr
) return Boolean is
366 SIE
: Source_File_Record
renames
367 Source_File
.Table
(Get_Source_File_Index
(S
));
369 return SIE
.Inlined_Body
;
370 end Comes_From_Inlined_Body
;
372 ------------------------
373 -- Free_Source_Buffer --
374 ------------------------
376 procedure Free_Source_Buffer
(Src
: in out Source_Buffer_Ptr
) is
377 -- Unchecked_Deallocation doesn't work for access-to-constant; we need
378 -- to first Unchecked_Convert to access-to-variable.
380 function To_Source_Buffer_Ptr_Var
is new
381 Ada
.Unchecked_Conversion
(Source_Buffer_Ptr
, Source_Buffer_Ptr_Var
);
383 Temp
: Source_Buffer_Ptr_Var
:= To_Source_Buffer_Ptr_Var
(Src
);
385 procedure Free_Ptr
is new
386 Ada
.Unchecked_Deallocation
(Source_Buffer
, Source_Buffer_Ptr_Var
);
390 end Free_Source_Buffer
;
392 -----------------------
393 -- Get_Column_Number --
394 -----------------------
396 function Get_Column_Number
(P
: Source_Ptr
) return Column_Number
is
399 Sindex
: Source_File_Index
;
400 Src
: Source_Buffer_Ptr
;
403 -- If the input source pointer is not a meaningful value then return
404 -- at once with column number 1. This can happen for a file not found
405 -- condition for a file loaded indirectly by RTE, and also perhaps on
406 -- some unknown internal error conditions. In either case we certainly
407 -- don't want to blow up.
413 Sindex
:= Get_Source_File_Index
(P
);
414 Src
:= Source_File
.Table
(Sindex
).Source_Text
;
420 C
:= (C
- 1) / 8 * 8 + (8 + 1);
423 -- Deal with wide character case, but don't include brackets
424 -- notation in this circuit, since we know that this will
425 -- display unencoded (no one encodes brackets notation).
427 elsif Src
(S
) /= '[' and then Is_Start_Of_Wide_Char
(Src
, S
) then
431 -- Normal (non-wide) character case or brackets sequence
441 end Get_Column_Number
;
443 -----------------------------
444 -- Get_Logical_Line_Number --
445 -----------------------------
447 function Get_Logical_Line_Number
448 (P
: Source_Ptr
) return Logical_Line_Number
450 SFR
: Source_File_Record
451 renames Source_File
.Table
(Get_Source_File_Index
(P
));
453 L
: constant Physical_Line_Number
:= Get_Physical_Line_Number
(P
);
456 if SFR
.Num_SRef_Pragmas
= 0 then
457 return Logical_Line_Number
(L
);
459 return SFR
.Logical_Lines_Table
(L
);
461 end Get_Logical_Line_Number
;
463 ------------------------------
464 -- Get_Physical_Line_Number --
465 ------------------------------
467 function Get_Physical_Line_Number
468 (P
: Source_Ptr
) return Physical_Line_Number
470 Sfile
: Source_File_Index
;
471 Table
: Lines_Table_Ptr
;
472 Lo
: Physical_Line_Number
;
473 Hi
: Physical_Line_Number
;
474 Mid
: Physical_Line_Number
;
478 -- If the input source pointer is not a meaningful value then return
479 -- at once with line number 1. This can happen for a file not found
480 -- condition for a file loaded indirectly by RTE, and also perhaps on
481 -- some unknown internal error conditions. In either case we certainly
482 -- don't want to blow up.
487 -- Otherwise we can do the binary search
490 Sfile
:= Get_Source_File_Index
(P
);
491 Loc
:= P
+ Source_File
.Table
(Sfile
).Sloc_Adjust
;
492 Table
:= Source_File
.Table
(Sfile
).Lines_Table
;
494 Hi
:= Source_File
.Table
(Sfile
).Last_Source_Line
;
497 Mid
:= (Lo
+ Hi
) / 2;
499 if Loc
< Table
(Mid
) then
502 else -- Loc >= Table (Mid)
505 Loc
< Table
(Mid
+ 1)
516 end Get_Physical_Line_Number
;
518 ---------------------------
519 -- Get_Source_File_Index --
520 ---------------------------
522 function Get_Source_File_Index
(S
: Source_Ptr
) return Source_File_Index
is
523 Result
: Source_File_Index
;
525 procedure Assertions
;
526 -- Assert various properties of the result
528 procedure Assertions
is
530 -- ???The old version using zero-origin array indexing without array
531 -- bounds checks returned 1 (i.e. system.ads) for these special
532 -- locations, presumably by accident. We are mimicing that here.
534 Special
: constant Boolean :=
536 or else S
= Standard_Location
537 or else S
= Standard_ASCII_Location
538 or else S
= System_Location
;
540 pragma Assert
(S
> No_Location
xor Special
);
541 pragma Assert
(Result
in Source_File
.First
.. Source_File
.Last
);
543 SFR
: Source_File_Record
renames Source_File
.Table
(Result
);
546 -- SFR.Source_Text = null if and only if this is the SFR for a debug
547 -- output file (*.dg), and that file is under construction. S can be
548 -- slightly past Source_Last in that case because we haven't updated
551 if Null_Source_Buffer_Ptr
(SFR
.Source_Text
) then
552 pragma Assert
(S
>= SFR
.Source_First
); null;
554 pragma Assert
(SFR
.Source_Text
'First = SFR
.Source_First
);
555 pragma Assert
(SFR
.Source_Text
'Last = SFR
.Source_Last
);
558 pragma Assert
(S
in SFR
.Source_First
.. SFR
.Source_Last
);
564 -- Start of processing for Get_Source_File_Index
567 if S
> No_Location
then
568 Result
:= Source_File_Index_Table
(Int
(S
) / Source_Align
);
573 pragma Debug
(Assertions
);
576 end Get_Source_File_Index
;
582 procedure Initialize
is
584 Source_gnat_adc
:= No_Source_File
;
587 Instances
.Append
(No_Location
);
588 pragma Assert
(Instances
.Last
= No_Instance_Id
);
595 function Instantiation
(S
: SFI
) return Source_Ptr
is
596 SIE
: Source_File_Record
renames Source_File
.Table
(S
);
598 if SIE
.Inlined_Body
or SIE
.Inherited_Pragma
then
599 return SIE
.Inlined_Call
;
601 return Instances
.Table
(SIE
.Instance
);
605 -------------------------
606 -- Instantiation_Depth --
607 -------------------------
609 function Instantiation_Depth
(S
: Source_Ptr
) return Nat
is
618 Sval
:= Instantiation_Location
(Sval
);
619 exit when Sval
= No_Location
;
624 end Instantiation_Depth
;
626 ----------------------------
627 -- Instantiation_Location --
628 ----------------------------
630 function Instantiation_Location
(S
: Source_Ptr
) return Source_Ptr
is
632 return Instantiation
(Get_Source_File_Index
(S
));
633 end Instantiation_Location
;
635 --------------------------
636 -- Iterate_On_Instances --
637 --------------------------
639 procedure Iterate_On_Instances
is
641 for J
in 1 .. Instances
.Last
loop
642 Process
(J
, Instances
.Table
(J
));
644 end Iterate_On_Instances
;
646 ----------------------
647 -- Last_Source_File --
648 ----------------------
650 function Last_Source_File
return Source_File_Index
is
652 return Source_File
.Last
;
653 end Last_Source_File
;
659 function Line_Start
(P
: Source_Ptr
) return Source_Ptr
is
660 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(P
);
661 Src
: constant Source_Buffer_Ptr
:=
662 Source_File
.Table
(Sindex
).Source_Text
;
663 Sfirst
: constant Source_Ptr
:=
664 Source_File
.Table
(Sindex
).Source_First
;
670 and then Src
(S
- 1) /= CR
671 and then Src
(S
- 1) /= LF
680 (L
: Physical_Line_Number
;
681 S
: Source_File_Index
) return Source_Ptr
684 return Source_File
.Table
(S
).Lines_Table
(L
);
694 Source_File
.Locked
:= True;
697 ----------------------
698 -- Num_Source_Files --
699 ----------------------
701 function Num_Source_Files
return Nat
is
703 return Int
(Source_File
.Last
) - Int
(Source_File
.First
) + 1;
704 end Num_Source_Files
;
706 ----------------------
707 -- Num_Source_Lines --
708 ----------------------
710 function Num_Source_Lines
(S
: Source_File_Index
) return Nat
is
712 return Nat
(Source_File
.Table
(S
).Last_Source_Line
);
713 end Num_Source_Lines
;
715 -----------------------
716 -- Original_Location --
717 -----------------------
719 function Original_Location
(S
: Source_Ptr
) return Source_Ptr
is
720 Sindex
: Source_File_Index
;
721 Tindex
: Source_File_Index
;
724 if S
<= No_Location
then
728 Sindex
:= Get_Source_File_Index
(S
);
730 if Instantiation
(Sindex
) = No_Location
then
734 Tindex
:= Template
(Sindex
);
735 while Instantiation
(Tindex
) /= No_Location
loop
736 Tindex
:= Template
(Tindex
);
739 return S
- Source_First
(Sindex
) + Source_First
(Tindex
);
742 end Original_Location
;
744 -------------------------
745 -- Physical_To_Logical --
746 -------------------------
748 function Physical_To_Logical
749 (Line
: Physical_Line_Number
;
750 S
: Source_File_Index
) return Logical_Line_Number
752 SFR
: Source_File_Record
renames Source_File
.Table
(S
);
755 if SFR
.Num_SRef_Pragmas
= 0 then
756 return Logical_Line_Number
(Line
);
758 return SFR
.Logical_Lines_Table
(Line
);
760 end Physical_To_Logical
;
762 --------------------------------
763 -- Register_Source_Ref_Pragma --
764 --------------------------------
766 procedure Register_Source_Ref_Pragma
767 (File_Name
: File_Name_Type
;
768 Stripped_File_Name
: File_Name_Type
;
770 Line_After_Pragma
: Physical_Line_Number
)
772 subtype size_t
is Memory
.size_t
;
774 SFR
: Source_File_Record
renames Source_File
.Table
(Current_Source_File
);
776 ML
: Logical_Line_Number
;
779 if File_Name
/= No_File
then
780 SFR
.Reference_Name
:= Stripped_File_Name
;
781 SFR
.Full_Ref_Name
:= File_Name
;
783 if not Debug_Generated_Code
then
784 SFR
.Debug_Source_Name
:= Stripped_File_Name
;
785 SFR
.Full_Debug_Name
:= File_Name
;
788 SFR
.Num_SRef_Pragmas
:= SFR
.Num_SRef_Pragmas
+ 1;
791 if SFR
.Num_SRef_Pragmas
= 1 then
792 SFR
.First_Mapped_Line
:= Logical_Line_Number
(Mapped_Line
);
795 if SFR
.Logical_Lines_Table
= null then
796 SFR
.Logical_Lines_Table
:= To_Pointer
798 (size_t
(SFR
.Lines_Table_Max
*
799 Logical_Lines_Table_Type
'Component_Size /
803 SFR
.Logical_Lines_Table
(Line_After_Pragma
- 1) := No_Line_Number
;
805 ML
:= Logical_Line_Number
(Mapped_Line
);
806 for J
in Line_After_Pragma
.. SFR
.Last_Source_Line
loop
807 SFR
.Logical_Lines_Table
(J
) := ML
;
810 end Register_Source_Ref_Pragma
;
812 ---------------------------------
813 -- Set_Source_File_Index_Table --
814 ---------------------------------
816 procedure Set_Source_File_Index_Table
(Xnew
: Source_File_Index
) is
819 SL
: constant Source_Ptr
:= Source_File
.Table
(Xnew
).Source_Last
;
821 SP
:= Source_File
.Table
(Xnew
).Source_First
;
822 pragma Assert
(SP
mod Source_Align
= 0);
823 Ind
:= Int
(SP
) / Source_Align
;
825 Source_File_Index_Table
(Ind
) := Xnew
;
826 SP
:= SP
+ Source_Align
;
829 end Set_Source_File_Index_Table
;
831 ---------------------------
832 -- Skip_Line_Terminators --
833 ---------------------------
835 procedure Skip_Line_Terminators
836 (P
: in out Source_Ptr
;
837 Physical
: out Boolean)
839 Chr
: constant Character := Source
(P
);
843 if Source
(P
+ 1) = LF
then
852 elsif Chr
= FF
or else Chr
= VT
then
857 -- Otherwise we have a wide character
860 Skip_Wide
(Source
, P
);
863 -- Fall through in the physical line terminator case. First deal with
864 -- making a possible entry into the lines table if one is needed.
866 -- Note: we are dealing with a real source file here, this cannot be
867 -- the instantiation case, so we need not worry about Sloc adjustment.
870 S
: Source_File_Record
871 renames Source_File
.Table
(Current_Source_File
);
876 -- Make entry in lines table if not already made (in some scan backup
877 -- cases, we will be rescanning previously scanned source, so the
878 -- entry may have already been made on the previous forward scan).
881 and then P
> S
.Lines_Table
(S
.Last_Source_Line
)
883 Add_Line_Tables_Entry
(S
, P
);
886 end Skip_Line_Terminators
;
893 (Src
: System
.Address
; New_Dope
: Dope_Ptr
)
895 -- A fat pointer is a pair consisting of data pointer and dope pointer,
896 -- in that order. So we want to overwrite the second word.
897 Dope
: System
.Address
;
898 pragma Import
(Ada
, Dope
);
899 use System
.Storage_Elements
;
900 for Dope
'Address use Src
+ System
.Address
'Size / 8;
902 Dope
:= New_Dope
.all'Address;
905 procedure Free_Dope
(Src
: System
.Address
) is
907 pragma Import
(Ada
, Dope
);
908 use System
.Storage_Elements
;
909 for Dope
'Address use Src
+ System
.Address
'Size / 8;
910 procedure Free
is new Ada
.Unchecked_Deallocation
(Dope_Rec
, Dope_Ptr
);
919 procedure Sloc_Range
(N
: Node_Id
; Min
, Max
: out Source_Ptr
) is
921 Indx
: constant Source_File_Index
:= Get_Source_File_Index
(Sloc
(N
));
923 function Process
(N
: Node_Id
) return Traverse_Result
;
924 -- Process function for traversing the node tree
926 procedure Traverse
is new Traverse_Proc
(Process
);
932 function Process
(N
: Node_Id
) return Traverse_Result
is
933 Loc
: constant Source_Ptr
:= Sloc
(Original_Node
(N
));
936 -- Skip nodes that may have been added during expansion and
937 -- that originate in other units, such as code for contracts
938 -- in subprogram bodies.
940 if Get_Source_File_Index
(Loc
) /= Indx
then
944 if Loc
> No_Location
then
955 -- Start of processing for Sloc_Range
967 function Source_Offset
(S
: Source_Ptr
) return Nat
is
968 Sindex
: constant Source_File_Index
:= Get_Source_File_Index
(S
);
969 Sfirst
: constant Source_Ptr
:=
970 Source_File
.Table
(Sindex
).Source_First
;
972 return Nat
(S
- Sfirst
);
975 ------------------------
976 -- Top_Level_Location --
977 ------------------------
979 function Top_Level_Location
(S
: Source_Ptr
) return Source_Ptr
is
987 Newloc
:= Instantiation_Location
(Oldloc
);
988 exit when Newloc
= No_Location
;
992 end Top_Level_Location
;
998 procedure Write_Location
(P
: Source_Ptr
) is
1000 if P
= No_Location
then
1001 Write_Str
("<no location>");
1003 elsif P
<= Standard_Location
then
1004 Write_Str
("<standard location>");
1008 SI
: constant Source_File_Index
:= Get_Source_File_Index
(P
);
1011 Write_Name_For_Debug
(Debug_Source_Name
(SI
));
1013 Write_Int
(Int
(Get_Logical_Line_Number
(P
)));
1015 Write_Int
(Int
(Get_Column_Number
(P
)));
1017 if Instantiation
(SI
) /= No_Location
then
1019 Write_Location
(Instantiation
(SI
));
1026 ----------------------
1027 -- Write_Time_Stamp --
1028 ----------------------
1030 procedure Write_Time_Stamp
(S
: Source_File_Index
) is
1031 T
: constant Time_Stamp_Type
:= Time_Stamp
(S
);
1044 Write_Char
(T
(P
+ 1));
1045 Write_Char
(T
(P
+ 2));
1048 Write_Char
(T
(P
+ 3));
1049 Write_Char
(T
(P
+ 4));
1052 Write_Char
(T
(P
+ 5));
1053 Write_Char
(T
(P
+ 6));
1056 Write_Char
(T
(P
+ 7));
1057 Write_Char
(T
(P
+ 8));
1060 Write_Char
(T
(P
+ 9));
1061 Write_Char
(T
(P
+ 10));
1064 Write_Char
(T
(P
+ 11));
1065 Write_Char
(T
(P
+ 12));
1066 end Write_Time_Stamp
;
1068 ----------------------------------------------
1069 -- Access Subprograms for Source File Table --
1070 ----------------------------------------------
1072 function Debug_Source_Name
(S
: SFI
) return File_Name_Type
is
1074 return Source_File
.Table
(S
).Debug_Source_Name
;
1075 end Debug_Source_Name
;
1077 function Instance
(S
: SFI
) return Instance_Id
is
1079 return Source_File
.Table
(S
).Instance
;
1082 function File_Name
(S
: SFI
) return File_Name_Type
is
1084 return Source_File
.Table
(S
).File_Name
;
1087 function File_Type
(S
: SFI
) return Type_Of_File
is
1089 return Source_File
.Table
(S
).File_Type
;
1092 function First_Mapped_Line
(S
: SFI
) return Logical_Line_Number
is
1094 return Source_File
.Table
(S
).First_Mapped_Line
;
1095 end First_Mapped_Line
;
1097 function Full_Debug_Name
(S
: SFI
) return File_Name_Type
is
1099 return Source_File
.Table
(S
).Full_Debug_Name
;
1100 end Full_Debug_Name
;
1102 function Full_File_Name
(S
: SFI
) return File_Name_Type
is
1104 return Source_File
.Table
(S
).Full_File_Name
;
1107 function Full_Ref_Name
(S
: SFI
) return File_Name_Type
is
1109 return Source_File
.Table
(S
).Full_Ref_Name
;
1112 function Identifier_Casing
(S
: SFI
) return Casing_Type
is
1114 return Source_File
.Table
(S
).Identifier_Casing
;
1115 end Identifier_Casing
;
1117 function Inherited_Pragma
(S
: SFI
) return Boolean is
1119 return Source_File
.Table
(S
).Inherited_Pragma
;
1120 end Inherited_Pragma
;
1122 function Inlined_Body
(S
: SFI
) return Boolean is
1124 return Source_File
.Table
(S
).Inlined_Body
;
1127 function Inlined_Call
(S
: SFI
) return Source_Ptr
is
1129 return Source_File
.Table
(S
).Inlined_Call
;
1132 function Keyword_Casing
(S
: SFI
) return Casing_Type
is
1134 return Source_File
.Table
(S
).Keyword_Casing
;
1137 function Last_Source_Line
(S
: SFI
) return Physical_Line_Number
is
1139 return Source_File
.Table
(S
).Last_Source_Line
;
1140 end Last_Source_Line
;
1142 function License
(S
: SFI
) return License_Type
is
1144 return Source_File
.Table
(S
).License
;
1147 function Num_SRef_Pragmas
(S
: SFI
) return Nat
is
1149 return Source_File
.Table
(S
).Num_SRef_Pragmas
;
1150 end Num_SRef_Pragmas
;
1152 function Reference_Name
(S
: SFI
) return File_Name_Type
is
1154 return Source_File
.Table
(S
).Reference_Name
;
1157 function Source_Checksum
(S
: SFI
) return Word
is
1159 return Source_File
.Table
(S
).Source_Checksum
;
1160 end Source_Checksum
;
1162 function Source_First
(S
: SFI
) return Source_Ptr
is
1164 return Source_File
.Table
(S
).Source_First
;
1167 function Source_Last
(S
: SFI
) return Source_Ptr
is
1169 return Source_File
.Table
(S
).Source_Last
;
1172 function Source_Text
(S
: SFI
) return Source_Buffer_Ptr
is
1174 return Source_File
.Table
(S
).Source_Text
;
1177 function Template
(S
: SFI
) return SFI
is
1179 return Source_File
.Table
(S
).Template
;
1182 function Time_Stamp
(S
: SFI
) return Time_Stamp_Type
is
1184 return Source_File
.Table
(S
).Time_Stamp
;
1187 function Unit
(S
: SFI
) return Unit_Number_Type
is
1189 return Source_File
.Table
(S
).Unit
;
1192 ------------------------------------------
1193 -- Set Procedures for Source File Table --
1194 ------------------------------------------
1196 procedure Set_Identifier_Casing
(S
: SFI
; C
: Casing_Type
) is
1198 Source_File
.Table
(S
).Identifier_Casing
:= C
;
1199 end Set_Identifier_Casing
;
1201 procedure Set_Keyword_Casing
(S
: SFI
; C
: Casing_Type
) is
1203 Source_File
.Table
(S
).Keyword_Casing
:= C
;
1204 end Set_Keyword_Casing
;
1206 procedure Set_License
(S
: SFI
; L
: License_Type
) is
1208 Source_File
.Table
(S
).License
:= L
;
1211 procedure Set_Unit
(S
: SFI
; U
: Unit_Number_Type
) is
1213 Source_File
.Table
(S
).Unit
:= U
;
1216 ----------------------
1217 -- Trim_Lines_Table --
1218 ----------------------
1220 procedure Trim_Lines_Table
(S
: Source_File_Index
) is
1221 Max
: constant Nat
:= Nat
(Source_File
.Table
(S
).Last_Source_Line
);
1224 -- Release allocated storage that is no longer needed
1226 Source_File
.Table
(S
).Lines_Table
:= To_Pointer
1228 (To_Address
(Source_File
.Table
(S
).Lines_Table
),
1230 (Max
* (Lines_Table_Type
'Component_Size / System
.Storage_Unit
))));
1231 Source_File
.Table
(S
).Lines_Table_Max
:= Physical_Line_Number
(Max
);
1232 end Trim_Lines_Table
;
1240 Source_File
.Locked
:= False;
1241 Source_File
.Release
;
1248 procedure wl
(P
: Source_Ptr
) is