1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2013, 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 ------------------------------------------------------------------------------
27 with Atree
; use Atree
;
28 with Debug
; use Debug
;
29 with Einfo
; use Einfo
;
30 with Errout
; use Errout
;
31 with Fname
; use Fname
;
35 with Osint
; use Osint
;
36 with Output
; use Output
;
38 with Prepcomp
; use Prepcomp
;
39 with Scans
; use Scans
;
41 with Sem_Aux
; use Sem_Aux
;
42 with Sem_Util
; use Sem_Util
;
43 with Sinfo
; use Sinfo
;
44 with Snames
; use Snames
;
45 with System
; use System
;
47 with System
.OS_Lib
; use System
.OS_Lib
;
49 with Unchecked_Conversion
;
51 package body Sinput
.L
is
53 Prep_Buffer
: Text_Buffer_Ptr
:= null;
54 -- A buffer to temporarily stored the result of preprocessing a source.
55 -- It is only allocated if there is at least one source to preprocess.
57 Prep_Buffer_Last
: Text_Ptr
:= 0;
58 -- Index of the last significant character in Prep_Buffer
60 Initial_Size_Of_Prep_Buffer
: constant := 10_000
;
61 -- Size of Prep_Buffer when it is first allocated
63 -- When a file is to be preprocessed and the options to list symbols
64 -- has been selected (switch -s), Prep.List_Symbols is called with a
65 -- "foreword", a single line indicating what source the symbols apply to.
66 -- The following two constant String are the start and the end of this
69 Foreword_Start
: constant String :=
70 "Preprocessing Symbols for source """;
72 Foreword_End
: constant String := """";
78 procedure Put_Char_In_Prep_Buffer
(C
: Character);
79 -- Add one character in Prep_Buffer, extending Prep_Buffer if need be.
80 -- Used to initialize the preprocessor.
82 procedure New_EOL_In_Prep_Buffer
;
83 -- Add an LF to Prep_Buffer (used to initialize the preprocessor)
87 T
: Osint
.File_Type
) return Source_File_Index
;
88 -- Load a source file, a configuration pragmas file or a definition file
89 -- Coding also allows preprocessing file, but not a library file ???
91 -------------------------------
92 -- Adjust_Instantiation_Sloc --
93 -------------------------------
95 procedure Adjust_Instantiation_Sloc
(N
: Node_Id
; A
: Sloc_Adjustment
) is
96 Loc
: constant Source_Ptr
:= Sloc
(N
);
99 -- We only do the adjustment if the value is between the appropriate low
100 -- and high values. It is not clear that this should ever not be the
101 -- case, but in practice there seem to be some nodes that get copied
102 -- twice, and this is a defence against that happening.
104 if A
.Lo
<= Loc
and then Loc
<= A
.Hi
then
105 Set_Sloc
(N
, Loc
+ A
.Adjust
);
107 end Adjust_Instantiation_Sloc
;
109 --------------------------------
110 -- Complete_Source_File_Entry --
111 --------------------------------
113 procedure Complete_Source_File_Entry
is
114 CSF
: constant Source_File_Index
:= Current_Source_File
;
116 Trim_Lines_Table
(CSF
);
117 Source_File
.Table
(CSF
).Source_Checksum
:= Checksum
;
118 end Complete_Source_File_Entry
;
120 ---------------------------------
121 -- Create_Instantiation_Source --
122 ---------------------------------
124 procedure Create_Instantiation_Source
125 (Inst_Node
: Entity_Id
;
126 Template_Id
: Entity_Id
;
127 Inlined_Body
: Boolean;
128 A
: out Sloc_Adjustment
)
130 Dnod
: constant Node_Id
:= Declaration_Node
(Template_Id
);
131 Xold
: Source_File_Index
;
132 Xnew
: Source_File_Index
;
135 Xold
:= Get_Source_File_Index
(Sloc
(Template_Id
));
136 A
.Lo
:= Source_File
.Table
(Xold
).Source_First
;
137 A
.Hi
:= Source_File
.Table
(Xold
).Source_Last
;
139 Source_File
.Append
(Source_File
.Table
(Xold
));
140 Xnew
:= Source_File
.Last
;
143 Sold
: Source_File_Record
renames Source_File
.Table
(Xold
);
144 Snew
: Source_File_Record
renames Source_File
.Table
(Xnew
);
149 Snew
.Inlined_Body
:= Inlined_Body
;
150 Snew
.Template
:= Xold
;
152 -- For a genuine generic instantiation, assign new instance id.
153 -- For inlined bodies, we retain that of the template, but we
154 -- save the call location.
157 Snew
.Inlined_Call
:= Sloc
(Inst_Node
);
160 -- If the spec has been instantiated already, and we are now
161 -- creating the instance source for the corresponding body now,
162 -- retrieve the instance id that was assigned to the spec, which
163 -- corresponds to the same instantiation sloc.
165 Inst_Spec
:= Instance_Spec
(Inst_Node
);
166 if Present
(Inst_Spec
) then
168 Inst_Spec_Ent
: Entity_Id
;
169 -- Instance spec entity
171 Inst_Spec_Sloc
: Source_Ptr
;
172 -- Virtual sloc of the spec instance source
174 Inst_Spec_Inst_Id
: Instance_Id
;
175 -- Instance id assigned to the instance spec
178 Inst_Spec_Ent
:= Defining_Entity
(Inst_Spec
);
180 -- For a subprogram instantiation, we want the subprogram
181 -- instance, not the wrapper package.
183 if Present
(Related_Instance
(Inst_Spec_Ent
)) then
184 Inst_Spec_Ent
:= Related_Instance
(Inst_Spec_Ent
);
187 -- The specification of the instance entity has a virtual
188 -- sloc within the instance sloc range.
190 -- ??? But the Unit_Declaration_Node has the sloc of the
191 -- instantiation, which is somewhat of an oddity.
195 (Specification
(Unit_Declaration_Node
(Inst_Spec_Ent
)));
198 (Get_Source_File_Index
(Inst_Spec_Sloc
)).Instance
;
201 (Sloc
(Inst_Node
) = Instances
.Table
(Inst_Spec_Inst_Id
));
202 Snew
.Instance
:= Inst_Spec_Inst_Id
;
206 Instances
.Append
(Sloc
(Inst_Node
));
207 Snew
.Instance
:= Instances
.Last
;
211 -- Now we need to compute the new values of Source_First and
212 -- Source_Last and adjust the source file pointer to have the
213 -- correct virtual origin for the new range of values.
215 -- Source_First must be greater than the last Source_Last value
216 -- and also must be a multiple of Source_Align
219 ((Source_File
.Table
(Xnew
- 1).Source_Last
+ Source_Align
) /
220 Source_Align
) * Source_Align
;
221 A
.Adjust
:= Snew
.Source_First
- A
.Lo
;
222 Snew
.Source_Last
:= A
.Hi
+ A
.Adjust
;
224 Set_Source_File_Index_Table
(Xnew
);
226 Snew
.Sloc_Adjust
:= Sold
.Sloc_Adjust
- A
.Adjust
;
230 Write_Str
("*** Create instantiation source for ");
232 if Nkind
(Dnod
) in N_Proper_Body
233 and then Was_Originally_Stub
(Dnod
)
235 Write_Str
("subunit ");
237 elsif Ekind
(Template_Id
) = E_Generic_Package
then
238 if Nkind
(Dnod
) = N_Package_Body
then
239 Write_Str
("body of package ");
241 Write_Str
("spec of package ");
244 elsif Ekind
(Template_Id
) = E_Function
then
245 Write_Str
("body of function ");
247 elsif Ekind
(Template_Id
) = E_Procedure
then
248 Write_Str
("body of procedure ");
250 elsif Ekind
(Template_Id
) = E_Generic_Function
then
251 Write_Str
("spec of function ");
253 elsif Ekind
(Template_Id
) = E_Generic_Procedure
then
254 Write_Str
("spec of procedure ");
256 elsif Ekind
(Template_Id
) = E_Package_Body
then
257 Write_Str
("body of package ");
259 else pragma Assert
(Ekind
(Template_Id
) = E_Subprogram_Body
);
261 if Nkind
(Dnod
) = N_Procedure_Specification
then
262 Write_Str
("body of procedure ");
264 Write_Str
("body of function ");
268 Write_Name
(Chars
(Template_Id
));
271 Write_Str
(" new source index = ");
272 Write_Int
(Int
(Xnew
));
275 Write_Str
(" copying from file name = ");
276 Write_Name
(File_Name
(Xold
));
279 Write_Str
(" old source index = ");
280 Write_Int
(Int
(Xold
));
283 Write_Str
(" old lo = ");
284 Write_Int
(Int
(A
.Lo
));
287 Write_Str
(" old hi = ");
288 Write_Int
(Int
(A
.Hi
));
291 Write_Str
(" new lo = ");
292 Write_Int
(Int
(Snew
.Source_First
));
295 Write_Str
(" new hi = ");
296 Write_Int
(Int
(Snew
.Source_Last
));
299 Write_Str
(" adjustment factor = ");
300 Write_Int
(Int
(A
.Adjust
));
303 Write_Str
(" instantiation location: ");
304 Write_Location
(Sloc
(Inst_Node
));
308 -- For a given character in the source, a higher subscript will be
309 -- used to access the instantiation, which means that the virtual
310 -- origin must have a corresponding lower value. We compute this new
311 -- origin by taking the address of the appropriate adjusted element
312 -- in the old array. Since this adjusted element will be at a
313 -- negative subscript, we must suppress checks.
316 pragma Suppress
(All_Checks
);
318 pragma Warnings
(Off
);
319 -- This unchecked conversion is aliasing safe, since it is never
320 -- used to create improperly aliased pointer values.
322 function To_Source_Buffer_Ptr
is new
323 Unchecked_Conversion
(Address
, Source_Buffer_Ptr
);
325 pragma Warnings
(On
);
330 (Sold
.Source_Text
(-A
.Adjust
)'Address);
333 end Create_Instantiation_Source
;
335 ----------------------
336 -- Load_Config_File --
337 ----------------------
339 function Load_Config_File
340 (N
: File_Name_Type
) return Source_File_Index
343 return Load_File
(N
, Osint
.Config
);
344 end Load_Config_File
;
346 --------------------------
347 -- Load_Definition_File --
348 --------------------------
350 function Load_Definition_File
351 (N
: File_Name_Type
) return Source_File_Index
354 return Load_File
(N
, Osint
.Definition
);
355 end Load_Definition_File
;
363 T
: Osint
.File_Type
) return Source_File_Index
365 Src
: Source_Buffer_Ptr
;
366 X
: Source_File_Index
;
370 Preprocessing_Needed
: Boolean := False;
373 -- If already there, don't need to reload file. An exception occurs
374 -- in multiple unit per file mode. It would be nice in this case to
375 -- share the same source file for each unit, but this leads to many
376 -- difficulties with assumptions (e.g. in the body of lib), that a
377 -- unit can be found by locating its source file index. Since we do
378 -- not expect much use of this mode, it's no big deal to waste a bit
379 -- of space and time by reading and storing the source multiple times.
381 if Multiple_Unit_Index
= 0 then
382 for J
in 1 .. Source_File
.Last
loop
383 if Source_File
.Table
(J
).File_Name
= N
then
389 -- Here we must build a new entry in the file table
391 -- But first, we must check if a source needs to be preprocessed,
392 -- because we may have to load and parse a definition file, and we want
393 -- to do that before we load the source, so that the buffer of the
394 -- source will be the last created, and we will be able to replace it
395 -- and modify Hi without stepping on another buffer.
397 if T
= Osint
.Source
and then not Is_Internal_File_Name
(N
) then
398 Prepare_To_Preprocess
399 (Source
=> N
, Preprocessing_Needed
=> Preprocessing_Needed
);
402 Source_File
.Increment_Last
;
403 X
:= Source_File
.Last
;
405 -- Compute starting index, respecting alignment requirement
407 if X
= Source_File
.First
then
408 Lo
:= First_Source_Ptr
;
410 Lo
:= ((Source_File
.Table
(X
- 1).Source_Last
+ Source_Align
) /
411 Source_Align
) * Source_Align
;
414 Osint
.Read_Source_File
(N
, Lo
, Hi
, Src
, T
);
417 Source_File
.Decrement_Last
;
418 return No_Source_File
;
423 Write_Str
("*** Build source file table entry, Index = ");
425 Write_Str
(", file name = ");
428 Write_Str
(" lo = ");
429 Write_Int
(Int
(Lo
));
431 Write_Str
(" hi = ");
432 Write_Int
(Int
(Hi
));
435 Write_Str
(" first 10 chars -->");
438 procedure Wchar
(C
: Character);
439 -- Writes character or ? for control character
445 procedure Wchar
(C
: Character) is
448 or else C
in ASCII
.DEL
.. Character'Val (16#
9F#
)
457 for J
in Lo
.. Lo
+ 9 loop
464 Write_Str
(" last 10 chars -->");
466 for J
in Hi
- 10 .. Hi
- 1 loop
473 if Src
(Hi
) /= EOF
then
474 Write_Str
(" error: no EOF at end");
481 S
: Source_File_Record
renames Source_File
.Table
(X
);
482 File_Type
: Type_Of_File
;
487 File_Type
:= Sinput
.Src
;
489 when Osint
.Library
=>
493 File_Type
:= Sinput
.Config
;
495 when Osint
.Definition
=>
498 when Osint
.Preprocessing_Data
=>
499 File_Type
:= Preproc
;
502 S
:= (Debug_Source_Name
=> N
,
504 File_Type
=> File_Type
,
505 First_Mapped_Line
=> No_Line_Number
,
506 Full_Debug_Name
=> Osint
.Full_Source_Name
,
507 Full_File_Name
=> Osint
.Full_Source_Name
,
508 Full_Ref_Name
=> Osint
.Full_Source_Name
,
509 Instance
=> No_Instance_Id
,
510 Identifier_Casing
=> Unknown
,
511 Inlined_Call
=> No_Location
,
512 Inlined_Body
=> False,
513 Keyword_Casing
=> Unknown
,
514 Last_Source_Line
=> 1,
517 Lines_Table_Max
=> 1,
518 Logical_Lines_Table
=> null,
519 Num_SRef_Pragmas
=> 0,
522 Source_Checksum
=> 0,
526 Template
=> No_Source_File
,
528 Time_Stamp
=> Osint
.Current_Source_File_Stamp
);
530 Alloc_Line_Tables
(S
, Opt
.Table_Factor
* Alloc
.Lines_Initial
);
531 S
.Lines_Table
(1) := Lo
;
534 -- Preprocess the source if it needs to be preprocessed
536 if Preprocessing_Needed
then
538 -- Temporarily set the Source_File_Index_Table entries for the
539 -- source, to avoid crash when reporting an error.
541 Set_Source_File_Index_Table
(X
);
543 if Opt
.List_Preprocessing_Symbols
then
547 Foreword
: String (1 .. Foreword_Start
'Length +
548 Name_Len
+ Foreword_End
'Length);
551 Foreword
(1 .. Foreword_Start
'Length) := Foreword_Start
;
552 Foreword
(Foreword_Start
'Length + 1 ..
553 Foreword_Start
'Length + Name_Len
) :=
554 Name_Buffer
(1 .. Name_Len
);
555 Foreword
(Foreword
'Last - Foreword_End
'Length + 1 ..
556 Foreword
'Last) := Foreword_End
;
557 Prep
.List_Symbols
(Foreword
);
562 T
: constant Nat
:= Total_Errors_Detected
;
563 -- Used to check if there were errors during preprocessing
565 Save_Style_Check
: Boolean;
566 -- Saved state of the Style_Check flag (which needs to be
567 -- temporarily set to False during preprocessing, see below).
572 -- If this is the first time we preprocess a source, allocate
573 -- the preprocessing buffer.
575 if Prep_Buffer
= null then
577 new Text_Buffer
(1 .. Initial_Size_Of_Prep_Buffer
);
580 -- Make sure the preprocessing buffer is empty
582 Prep_Buffer_Last
:= 0;
584 -- Initialize the preprocessor hooks
587 (Error_Msg
=> Errout
.Error_Msg
'Access,
588 Scan
=> Scn
.Scanner
.Scan
'Access,
589 Set_Ignore_Errors
=> Errout
.Set_Ignore_Errors
'Access,
590 Put_Char
=> Put_Char_In_Prep_Buffer
'Access,
591 New_EOL
=> New_EOL_In_Prep_Buffer
'Access);
593 -- Initialize scanner and set its behavior for preprocessing,
594 -- then preprocess. Also disable style checks, since some of
595 -- them are done in the scanner (specifically, those dealing
596 -- with line length and line termination), and cannot be done
597 -- during preprocessing (because the source file index table
598 -- has not been set yet).
600 Scn
.Scanner
.Initialize_Scanner
(X
);
602 Scn
.Scanner
.Set_Special_Character
('#');
603 Scn
.Scanner
.Set_Special_Character
('$');
604 Scn
.Scanner
.Set_End_Of_Line_As_Token
(True);
605 Save_Style_Check
:= Opt
.Style_Check
;
606 Opt
.Style_Check
:= False;
608 -- The actual preprocessing step
610 Preprocess
(Modified
);
612 -- Reset the scanner to its standard behavior, and restore the
613 -- Style_Checks flag.
615 Scn
.Scanner
.Reset_Special_Characters
;
616 Scn
.Scanner
.Set_End_Of_Line_As_Token
(False);
617 Opt
.Style_Check
:= Save_Style_Check
;
619 -- If there were errors during preprocessing, record an error
620 -- at the start of the file, and do not change the source
623 if T
/= Total_Errors_Detected
then
625 ("file could not be successfully preprocessed", Lo
);
626 return No_Source_File
;
629 -- Output the result of the preprocessing, if requested and
630 -- the source has been modified by the preprocessing. Only
631 -- do that for the main unit (spec, body and subunits).
633 if Generate_Processed_File
636 ((Compiler_State
= Parsing
637 and then Parsing_Main_Extended_Source
)
639 (Compiler_State
= Analyzing
640 and then Analysing_Subunit_Of_Main
))
643 FD
: File_Descriptor
;
650 if Hostparm
.OpenVMS
then
651 Add_Str_To_Name_Buffer
("_prep");
653 Add_Str_To_Name_Buffer
(".prep");
656 Delete_File
(Name_Buffer
(1 .. Name_Len
), Status
);
659 Create_New_File
(Name_Buffer
(1 .. Name_Len
), Text
);
661 Status
:= FD
/= Invalid_FD
;
667 Prep_Buffer
(1)'Address,
668 Integer (Prep_Buffer_Last
));
669 Status
:= NB
= Integer (Prep_Buffer_Last
);
678 ("??could not write processed file """ &
679 Name_Buffer
(1 .. Name_Len
) & '"',
685 -- Set the new value of Hi
687 Hi
:= Lo
+ Source_Ptr
(Prep_Buffer_Last
);
689 -- Create the new source buffer
692 subtype Actual_Source_Buffer
is Source_Buffer
(Lo
.. Hi
);
693 -- Physical buffer allocated
695 type Actual_Source_Ptr
is access Actual_Source_Buffer
;
696 -- Pointer type for the physical buffer allocated
698 Actual_Ptr
: constant Actual_Source_Ptr
:=
699 new Actual_Source_Buffer
;
700 -- Actual physical buffer
703 Actual_Ptr
(Lo
.. Hi
- 1) :=
704 Prep_Buffer
(1 .. Prep_Buffer_Last
);
705 Actual_Ptr
(Hi
) := EOF
;
707 -- Now we need to work out the proper virtual origin
708 -- pointer to return. This is Actual_Ptr (0)'Address, but
709 -- we have to be careful to suppress checks to compute
713 pragma Suppress
(All_Checks
);
715 pragma Warnings
(Off
);
716 -- This unchecked conversion is aliasing safe, since
717 -- it is never used to create improperly aliased
720 function To_Source_Buffer_Ptr
is new
721 Unchecked_Conversion
(Address
, Source_Buffer_Ptr
);
723 pragma Warnings
(On
);
726 Src
:= To_Source_Buffer_Ptr
(Actual_Ptr
(0)'Address);
728 -- Record in the table the new source buffer and the
731 Source_File
.Table
(X
).Source_Text
:= Src
;
732 Source_File
.Table
(X
).Source_Last
:= Hi
;
734 -- Reset Last_Line to 1, because the lines do not
735 -- have necessarily the same starts and lengths.
737 Source_File
.Table
(X
).Last_Source_Line
:= 1;
744 Set_Source_File_Index_Table
(X
);
749 ----------------------------------
750 -- Load_Preprocessing_Data_File --
751 ----------------------------------
753 function Load_Preprocessing_Data_File
754 (N
: File_Name_Type
) return Source_File_Index
757 return Load_File
(N
, Osint
.Preprocessing_Data
);
758 end Load_Preprocessing_Data_File
;
760 ----------------------
761 -- Load_Source_File --
762 ----------------------
764 function Load_Source_File
765 (N
: File_Name_Type
) return Source_File_Index
768 return Load_File
(N
, Osint
.Source
);
769 end Load_Source_File
;
771 ----------------------------
772 -- New_EOL_In_Prep_Buffer --
773 ----------------------------
775 procedure New_EOL_In_Prep_Buffer
is
777 Put_Char_In_Prep_Buffer
(ASCII
.LF
);
778 end New_EOL_In_Prep_Buffer
;
780 -----------------------------
781 -- Put_Char_In_Prep_Buffer --
782 -----------------------------
784 procedure Put_Char_In_Prep_Buffer
(C
: Character) is
786 -- If preprocessing buffer is not large enough, double it
788 if Prep_Buffer_Last
= Prep_Buffer
'Last then
790 New_Prep_Buffer
: constant Text_Buffer_Ptr
:=
791 new Text_Buffer
(1 .. 2 * Prep_Buffer_Last
);
794 New_Prep_Buffer
(Prep_Buffer
'Range) := Prep_Buffer
.all;
796 Prep_Buffer
:= New_Prep_Buffer
;
800 Prep_Buffer_Last
:= Prep_Buffer_Last
+ 1;
801 Prep_Buffer
(Prep_Buffer_Last
) := C
;
802 end Put_Char_In_Prep_Buffer
;
804 -----------------------------------
805 -- Source_File_Is_Pragma_No_Body --
806 -----------------------------------
808 function Source_File_Is_No_Body
(X
: Source_File_Index
) return Boolean is
810 Initialize_Scanner
(No_Unit
, X
);
812 if Token
/= Tok_Pragma
then
818 if Token
/= Tok_Identifier
819 or else Chars
(Token_Node
) /= Name_No_Body
824 Scan
; -- past No_Body
826 if Token
/= Tok_Semicolon
then
830 Scan
; -- past semicolon
832 return Token
= Tok_EOF
;
833 end Source_File_Is_No_Body
;
835 ----------------------------
836 -- Source_File_Is_Subunit --
837 ----------------------------
839 function Source_File_Is_Subunit
(X
: Source_File_Index
) return Boolean is
841 Initialize_Scanner
(No_Unit
, X
);
843 -- We scan past junk to the first interesting compilation unit token, to
844 -- see if it is SEPARATE. We ignore WITH keywords during this and also
845 -- PRIVATE. The reason for ignoring PRIVATE is that it handles some
846 -- error situations, and also to handle PRIVATE WITH in Ada 2005 mode.
848 while Token
= Tok_With
849 or else Token
= Tok_Private
850 or else (Token
not in Token_Class_Cunit
and then Token
/= Tok_EOF
)
855 return Token
= Tok_Separate
;
856 end Source_File_Is_Subunit
;