annotate gcc/ada/sinput-l.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- S I N P U T . L --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
kono
parents:
diff changeset
9 -- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Alloc;
kono
parents:
diff changeset
27 with Atree; use Atree;
kono
parents:
diff changeset
28 with Debug; use Debug;
kono
parents:
diff changeset
29 with Einfo; use Einfo;
kono
parents:
diff changeset
30 with Errout; use Errout;
kono
parents:
diff changeset
31 with Fname; use Fname;
kono
parents:
diff changeset
32 with Lib; use Lib;
kono
parents:
diff changeset
33 with Opt; use Opt;
kono
parents:
diff changeset
34 with Osint; use Osint;
kono
parents:
diff changeset
35 with Output; use Output;
kono
parents:
diff changeset
36 with Prep; use Prep;
kono
parents:
diff changeset
37 with Prepcomp; use Prepcomp;
kono
parents:
diff changeset
38 with Scans; use Scans;
kono
parents:
diff changeset
39 with Scn; use Scn;
kono
parents:
diff changeset
40 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
41 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
42 with Sinfo; use Sinfo;
kono
parents:
diff changeset
43 with Snames; use Snames;
kono
parents:
diff changeset
44 with System; use System;
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 with System.OS_Lib; use System.OS_Lib;
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 package body Sinput.L is
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 Prep_Buffer : Text_Buffer_Ptr := null;
kono
parents:
diff changeset
51 -- A buffer to temporarily stored the result of preprocessing a source.
kono
parents:
diff changeset
52 -- It is only allocated if there is at least one source to preprocess.
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 Prep_Buffer_Last : Text_Ptr := 0;
kono
parents:
diff changeset
55 -- Index of the last significant character in Prep_Buffer
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 Initial_Size_Of_Prep_Buffer : constant := 10_000;
kono
parents:
diff changeset
58 -- Size of Prep_Buffer when it is first allocated
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 -- When a file is to be preprocessed and the options to list symbols
kono
parents:
diff changeset
61 -- has been selected (switch -s), Prep.List_Symbols is called with a
kono
parents:
diff changeset
62 -- "foreword", a single line indicating what source the symbols apply to.
kono
parents:
diff changeset
63 -- The following two constant String are the start and the end of this
kono
parents:
diff changeset
64 -- foreword.
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 Foreword_Start : constant String :=
kono
parents:
diff changeset
67 "Preprocessing Symbols for source """;
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 Foreword_End : constant String := """";
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 -----------------
kono
parents:
diff changeset
72 -- Subprograms --
kono
parents:
diff changeset
73 -----------------
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 procedure Put_Char_In_Prep_Buffer (C : Character);
kono
parents:
diff changeset
76 -- Add one character in Prep_Buffer, extending Prep_Buffer if need be.
kono
parents:
diff changeset
77 -- Used to initialize the preprocessor.
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 procedure New_EOL_In_Prep_Buffer;
kono
parents:
diff changeset
80 -- Add an LF to Prep_Buffer (used to initialize the preprocessor)
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 function Load_File
kono
parents:
diff changeset
83 (N : File_Name_Type;
kono
parents:
diff changeset
84 T : Osint.File_Type) return Source_File_Index;
kono
parents:
diff changeset
85 -- Load a source file, a configuration pragmas file or a definition file
kono
parents:
diff changeset
86 -- Coding also allows preprocessing file, but not a library file ???
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 -------------------------------
kono
parents:
diff changeset
89 -- Adjust_Instantiation_Sloc --
kono
parents:
diff changeset
90 -------------------------------
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 procedure Adjust_Instantiation_Sloc
kono
parents:
diff changeset
93 (N : Node_Id;
kono
parents:
diff changeset
94 Factor : Sloc_Adjustment)
kono
parents:
diff changeset
95 is
kono
parents:
diff changeset
96 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 begin
kono
parents:
diff changeset
99 -- We only do the adjustment if the value is between the appropriate low
kono
parents:
diff changeset
100 -- and high values. It is not clear that this should ever not be the
kono
parents:
diff changeset
101 -- case, but in practice there seem to be some nodes that get copied
kono
parents:
diff changeset
102 -- twice, and this is a defence against that happening.
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 if Loc in Factor.Lo .. Factor.Hi then
kono
parents:
diff changeset
105 Set_Sloc (N, Loc + Factor.Adjust);
kono
parents:
diff changeset
106 end if;
kono
parents:
diff changeset
107 end Adjust_Instantiation_Sloc;
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 --------------------------------
kono
parents:
diff changeset
110 -- Complete_Source_File_Entry --
kono
parents:
diff changeset
111 --------------------------------
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 procedure Complete_Source_File_Entry is
kono
parents:
diff changeset
114 CSF : constant Source_File_Index := Current_Source_File;
kono
parents:
diff changeset
115 begin
kono
parents:
diff changeset
116 Trim_Lines_Table (CSF);
kono
parents:
diff changeset
117 Source_File.Table (CSF).Source_Checksum := Checksum;
kono
parents:
diff changeset
118 end Complete_Source_File_Entry;
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 ---------------------------------
kono
parents:
diff changeset
121 -- Create_Instantiation_Source --
kono
parents:
diff changeset
122 ---------------------------------
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 procedure Create_Instantiation_Source
kono
parents:
diff changeset
125 (Inst_Node : Entity_Id;
kono
parents:
diff changeset
126 Template_Id : Entity_Id;
kono
parents:
diff changeset
127 Factor : out Sloc_Adjustment;
kono
parents:
diff changeset
128 Inlined_Body : Boolean := False;
kono
parents:
diff changeset
129 Inherited_Pragma : Boolean := False)
kono
parents:
diff changeset
130 is
kono
parents:
diff changeset
131 Dnod : constant Node_Id := Declaration_Node (Template_Id);
kono
parents:
diff changeset
132 Xold : Source_File_Index;
kono
parents:
diff changeset
133 Xnew : Source_File_Index;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 begin
kono
parents:
diff changeset
136 Xold := Get_Source_File_Index (Sloc (Template_Id));
kono
parents:
diff changeset
137 Factor.Lo := Source_File.Table (Xold).Source_First;
kono
parents:
diff changeset
138 Factor.Hi := Source_File.Table (Xold).Source_Last;
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 Source_File.Append (Source_File.Table (Xold));
kono
parents:
diff changeset
141 Xnew := Source_File.Last;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 if Debug_Flag_L then
kono
parents:
diff changeset
144 Write_Eol;
kono
parents:
diff changeset
145 Write_Str ("*** Create_Instantiation_Source: created source ");
kono
parents:
diff changeset
146 Write_Int (Int (Xnew));
kono
parents:
diff changeset
147 Write_Line ("");
kono
parents:
diff changeset
148 end if;
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 declare
kono
parents:
diff changeset
151 Sold : Source_File_Record renames Source_File.Table (Xold);
kono
parents:
diff changeset
152 Snew : Source_File_Record renames Source_File.Table (Xnew);
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 Inst_Spec : Node_Id;
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 begin
kono
parents:
diff changeset
157 Snew.Index := Xnew;
kono
parents:
diff changeset
158 Snew.Inlined_Body := Inlined_Body;
kono
parents:
diff changeset
159 Snew.Inherited_Pragma := Inherited_Pragma;
kono
parents:
diff changeset
160 Snew.Template := Xold;
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 -- For a genuine generic instantiation, assign new instance id. For
kono
parents:
diff changeset
163 -- inlined bodies or inherited pragmas, we retain that of the
kono
parents:
diff changeset
164 -- template, but we save the call location.
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 if Inlined_Body or Inherited_Pragma then
kono
parents:
diff changeset
167 Snew.Inlined_Call := Sloc (Inst_Node);
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 else
kono
parents:
diff changeset
170 -- If the spec has been instantiated already, and we are now
kono
parents:
diff changeset
171 -- creating the instance source for the corresponding body now,
kono
parents:
diff changeset
172 -- retrieve the instance id that was assigned to the spec, which
kono
parents:
diff changeset
173 -- corresponds to the same instantiation sloc.
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 Inst_Spec := Instance_Spec (Inst_Node);
kono
parents:
diff changeset
176 if Present (Inst_Spec) then
kono
parents:
diff changeset
177 declare
kono
parents:
diff changeset
178 Inst_Spec_Ent : Entity_Id;
kono
parents:
diff changeset
179 -- Instance spec entity
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 Inst_Spec_Sloc : Source_Ptr;
kono
parents:
diff changeset
182 -- Virtual sloc of the spec instance source
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 Inst_Spec_Inst_Id : Instance_Id;
kono
parents:
diff changeset
185 -- Instance id assigned to the instance spec
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 begin
kono
parents:
diff changeset
188 Inst_Spec_Ent := Defining_Entity (Inst_Spec);
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 -- For a subprogram instantiation, we want the subprogram
kono
parents:
diff changeset
191 -- instance, not the wrapper package.
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 if Present (Related_Instance (Inst_Spec_Ent)) then
kono
parents:
diff changeset
194 Inst_Spec_Ent := Related_Instance (Inst_Spec_Ent);
kono
parents:
diff changeset
195 end if;
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 -- The specification of the instance entity has a virtual
kono
parents:
diff changeset
198 -- sloc within the instance sloc range.
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 -- ??? But the Unit_Declaration_Node has the sloc of the
kono
parents:
diff changeset
201 -- instantiation, which is somewhat of an oddity.
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 Inst_Spec_Sloc :=
kono
parents:
diff changeset
204 Sloc
kono
parents:
diff changeset
205 (Specification (Unit_Declaration_Node (Inst_Spec_Ent)));
kono
parents:
diff changeset
206 Inst_Spec_Inst_Id :=
kono
parents:
diff changeset
207 Source_File.Table
kono
parents:
diff changeset
208 (Get_Source_File_Index (Inst_Spec_Sloc)).Instance;
kono
parents:
diff changeset
209
kono
parents:
diff changeset
210 pragma Assert
kono
parents:
diff changeset
211 (Sloc (Inst_Node) = Instances.Table (Inst_Spec_Inst_Id));
kono
parents:
diff changeset
212 Snew.Instance := Inst_Spec_Inst_Id;
kono
parents:
diff changeset
213 end;
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 else
kono
parents:
diff changeset
216 Instances.Append (Sloc (Inst_Node));
kono
parents:
diff changeset
217 Snew.Instance := Instances.Last;
kono
parents:
diff changeset
218 end if;
kono
parents:
diff changeset
219 end if;
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 -- Now compute the new values of Source_First and Source_Last and
kono
parents:
diff changeset
222 -- adjust the source file pointer to have the correct bounds for the
kono
parents:
diff changeset
223 -- new range of values.
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 -- Source_First must be greater than the last Source_Last value and
kono
parents:
diff changeset
226 -- also must be a multiple of Source_Align.
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 Snew.Source_First :=
kono
parents:
diff changeset
229 ((Source_File.Table (Xnew - 1).Source_Last + Source_Align) /
kono
parents:
diff changeset
230 Source_Align) * Source_Align;
kono
parents:
diff changeset
231 Factor.Adjust := Snew.Source_First - Factor.Lo;
kono
parents:
diff changeset
232 Snew.Source_Last := Factor.Hi + Factor.Adjust;
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 Set_Source_File_Index_Table (Xnew);
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 Snew.Sloc_Adjust := Sold.Sloc_Adjust - Factor.Adjust;
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 -- Modify the Dope of the instance Source_Text to use the
kono
parents:
diff changeset
239 -- above-computed bounds.
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 declare
kono
parents:
diff changeset
242 Dope : constant Dope_Ptr :=
kono
parents:
diff changeset
243 new Dope_Rec'(Snew.Source_First, Snew.Source_Last);
kono
parents:
diff changeset
244 begin
kono
parents:
diff changeset
245 Snew.Source_Text := Sold.Source_Text;
kono
parents:
diff changeset
246 Set_Dope (Snew.Source_Text'Address, Dope);
kono
parents:
diff changeset
247 pragma Assert (Snew.Source_Text'First = Snew.Source_First);
kono
parents:
diff changeset
248 pragma Assert (Snew.Source_Text'Last = Snew.Source_Last);
kono
parents:
diff changeset
249 end;
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 if Debug_Flag_L then
kono
parents:
diff changeset
252 Write_Str (" for ");
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 if Nkind (Dnod) in N_Proper_Body
kono
parents:
diff changeset
255 and then Was_Originally_Stub (Dnod)
kono
parents:
diff changeset
256 then
kono
parents:
diff changeset
257 Write_Str ("subunit ");
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 elsif Ekind (Template_Id) = E_Generic_Package then
kono
parents:
diff changeset
260 if Nkind (Dnod) = N_Package_Body then
kono
parents:
diff changeset
261 Write_Str ("body of package ");
kono
parents:
diff changeset
262 else
kono
parents:
diff changeset
263 Write_Str ("spec of package ");
kono
parents:
diff changeset
264 end if;
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 elsif Ekind (Template_Id) = E_Function then
kono
parents:
diff changeset
267 Write_Str ("body of function ");
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 elsif Ekind (Template_Id) = E_Procedure then
kono
parents:
diff changeset
270 Write_Str ("body of procedure ");
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 elsif Ekind (Template_Id) = E_Generic_Function then
kono
parents:
diff changeset
273 Write_Str ("spec of function ");
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 elsif Ekind (Template_Id) = E_Generic_Procedure then
kono
parents:
diff changeset
276 Write_Str ("spec of procedure ");
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 elsif Ekind (Template_Id) = E_Package_Body then
kono
parents:
diff changeset
279 Write_Str ("body of package ");
kono
parents:
diff changeset
280
kono
parents:
diff changeset
281 else pragma Assert (Ekind (Template_Id) = E_Subprogram_Body);
kono
parents:
diff changeset
282 if Nkind (Dnod) = N_Procedure_Specification then
kono
parents:
diff changeset
283 Write_Str ("body of procedure ");
kono
parents:
diff changeset
284 else
kono
parents:
diff changeset
285 Write_Str ("body of function ");
kono
parents:
diff changeset
286 end if;
kono
parents:
diff changeset
287 end if;
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 Write_Name (Chars (Template_Id));
kono
parents:
diff changeset
290 Write_Eol;
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 Write_Str (" copying from file name = ");
kono
parents:
diff changeset
293 Write_Name (File_Name (Xold));
kono
parents:
diff changeset
294 Write_Eol;
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 Write_Str (" old source index = ");
kono
parents:
diff changeset
297 Write_Int (Int (Xold));
kono
parents:
diff changeset
298 Write_Eol;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 Write_Str (" old lo = ");
kono
parents:
diff changeset
301 Write_Int (Int (Factor.Lo));
kono
parents:
diff changeset
302 Write_Eol;
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Write_Str (" old hi = ");
kono
parents:
diff changeset
305 Write_Int (Int (Factor.Hi));
kono
parents:
diff changeset
306 Write_Eol;
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308 Write_Str (" new lo = ");
kono
parents:
diff changeset
309 Write_Int (Int (Snew.Source_First));
kono
parents:
diff changeset
310 Write_Eol;
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 Write_Str (" new hi = ");
kono
parents:
diff changeset
313 Write_Int (Int (Snew.Source_Last));
kono
parents:
diff changeset
314 Write_Eol;
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 Write_Str (" adjustment factor = ");
kono
parents:
diff changeset
317 Write_Int (Int (Factor.Adjust));
kono
parents:
diff changeset
318 Write_Eol;
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 Write_Str (" instantiation location: ");
kono
parents:
diff changeset
321 Write_Location (Sloc (Inst_Node));
kono
parents:
diff changeset
322 Write_Eol;
kono
parents:
diff changeset
323 end if;
kono
parents:
diff changeset
324 end;
kono
parents:
diff changeset
325 end Create_Instantiation_Source;
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 ----------------------
kono
parents:
diff changeset
328 -- Load_Config_File --
kono
parents:
diff changeset
329 ----------------------
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 function Load_Config_File
kono
parents:
diff changeset
332 (N : File_Name_Type) return Source_File_Index
kono
parents:
diff changeset
333 is
kono
parents:
diff changeset
334 begin
kono
parents:
diff changeset
335 return Load_File (N, Osint.Config);
kono
parents:
diff changeset
336 end Load_Config_File;
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 --------------------------
kono
parents:
diff changeset
339 -- Load_Definition_File --
kono
parents:
diff changeset
340 --------------------------
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 function Load_Definition_File
kono
parents:
diff changeset
343 (N : File_Name_Type) return Source_File_Index
kono
parents:
diff changeset
344 is
kono
parents:
diff changeset
345 begin
kono
parents:
diff changeset
346 return Load_File (N, Osint.Definition);
kono
parents:
diff changeset
347 end Load_Definition_File;
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 ---------------
kono
parents:
diff changeset
350 -- Load_File --
kono
parents:
diff changeset
351 ---------------
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 function Load_File
kono
parents:
diff changeset
354 (N : File_Name_Type;
kono
parents:
diff changeset
355 T : Osint.File_Type) return Source_File_Index
kono
parents:
diff changeset
356 is
kono
parents:
diff changeset
357 FD : File_Descriptor;
kono
parents:
diff changeset
358 Hi : Source_Ptr;
kono
parents:
diff changeset
359 Lo : Source_Ptr;
kono
parents:
diff changeset
360 Src : Source_Buffer_Ptr;
kono
parents:
diff changeset
361 X : Source_File_Index;
kono
parents:
diff changeset
362
kono
parents:
diff changeset
363 Preprocessing_Needed : Boolean := False;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 begin
kono
parents:
diff changeset
366 -- If already there, don't need to reload file. An exception occurs
kono
parents:
diff changeset
367 -- in multiple unit per file mode. It would be nice in this case to
kono
parents:
diff changeset
368 -- share the same source file for each unit, but this leads to many
kono
parents:
diff changeset
369 -- difficulties with assumptions (e.g. in the body of lib), that a
kono
parents:
diff changeset
370 -- unit can be found by locating its source file index. Since we do
kono
parents:
diff changeset
371 -- not expect much use of this mode, it's no big deal to waste a bit
kono
parents:
diff changeset
372 -- of space and time by reading and storing the source multiple times.
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 if Multiple_Unit_Index = 0 then
kono
parents:
diff changeset
375 for J in 1 .. Source_File.Last loop
kono
parents:
diff changeset
376 if Source_File.Table (J).File_Name = N then
kono
parents:
diff changeset
377 return J;
kono
parents:
diff changeset
378 end if;
kono
parents:
diff changeset
379 end loop;
kono
parents:
diff changeset
380 end if;
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 -- Here we must build a new entry in the file table
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 -- But first, we must check if a source needs to be preprocessed,
kono
parents:
diff changeset
385 -- because we may have to load and parse a definition file, and we want
kono
parents:
diff changeset
386 -- to do that before we load the source, so that the buffer of the
kono
parents:
diff changeset
387 -- source will be the last created, and we will be able to replace it
kono
parents:
diff changeset
388 -- and modify Hi without stepping on another buffer.
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 if T = Osint.Source and then not Is_Internal_File_Name (N) then
kono
parents:
diff changeset
391 Prepare_To_Preprocess
kono
parents:
diff changeset
392 (Source => N, Preprocessing_Needed => Preprocessing_Needed);
kono
parents:
diff changeset
393 end if;
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 Source_File.Increment_Last;
kono
parents:
diff changeset
396 X := Source_File.Last;
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 if Debug_Flag_L then
kono
parents:
diff changeset
399 Write_Eol;
kono
parents:
diff changeset
400 Write_Str ("Sinput.L.Load_File: created source ");
kono
parents:
diff changeset
401 Write_Int (Int (X));
kono
parents:
diff changeset
402 Write_Str (" for ");
kono
parents:
diff changeset
403 Write_Str (Get_Name_String (N));
kono
parents:
diff changeset
404 end if;
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 -- Compute starting index, respecting alignment requirement
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 if X = Source_File.First then
kono
parents:
diff changeset
409 Lo := First_Source_Ptr;
kono
parents:
diff changeset
410 else
kono
parents:
diff changeset
411 Lo := ((Source_File.Table (X - 1).Source_Last + Source_Align) /
kono
parents:
diff changeset
412 Source_Align) * Source_Align;
kono
parents:
diff changeset
413 end if;
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 Osint.Read_Source_File (N, Lo, Hi, Src, FD, T);
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 if Null_Source_Buffer_Ptr (Src) then
kono
parents:
diff changeset
418 Source_File.Decrement_Last;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 if FD = Null_FD then
kono
parents:
diff changeset
421 return No_Source_File;
kono
parents:
diff changeset
422 else
kono
parents:
diff changeset
423 return No_Access_To_Source_File;
kono
parents:
diff changeset
424 end if;
kono
parents:
diff changeset
425 else
kono
parents:
diff changeset
426 if Debug_Flag_L then
kono
parents:
diff changeset
427 Write_Eol;
kono
parents:
diff changeset
428 Write_Str ("*** Build source file table entry, Index = ");
kono
parents:
diff changeset
429 Write_Int (Int (X));
kono
parents:
diff changeset
430 Write_Str (", file name = ");
kono
parents:
diff changeset
431 Write_Name (N);
kono
parents:
diff changeset
432 Write_Eol;
kono
parents:
diff changeset
433 Write_Str (" lo = ");
kono
parents:
diff changeset
434 Write_Int (Int (Lo));
kono
parents:
diff changeset
435 Write_Eol;
kono
parents:
diff changeset
436 Write_Str (" hi = ");
kono
parents:
diff changeset
437 Write_Int (Int (Hi));
kono
parents:
diff changeset
438 Write_Eol;
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 Write_Str (" first 10 chars -->");
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 declare
kono
parents:
diff changeset
443 procedure Wchar (C : Character);
kono
parents:
diff changeset
444 -- Writes character or ? for control character
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 -----------
kono
parents:
diff changeset
447 -- Wchar --
kono
parents:
diff changeset
448 -----------
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 procedure Wchar (C : Character) is
kono
parents:
diff changeset
451 begin
kono
parents:
diff changeset
452 if C < ' '
kono
parents:
diff changeset
453 or else C in ASCII.DEL .. Character'Val (16#9F#)
kono
parents:
diff changeset
454 then
kono
parents:
diff changeset
455 Write_Char ('?');
kono
parents:
diff changeset
456 else
kono
parents:
diff changeset
457 Write_Char (C);
kono
parents:
diff changeset
458 end if;
kono
parents:
diff changeset
459 end Wchar;
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 begin
kono
parents:
diff changeset
462 for J in Lo .. Lo + 9 loop
kono
parents:
diff changeset
463 Wchar (Src (J));
kono
parents:
diff changeset
464 end loop;
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 Write_Str ("<--");
kono
parents:
diff changeset
467 Write_Eol;
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 Write_Str (" last 10 chars -->");
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 for J in Hi - 10 .. Hi - 1 loop
kono
parents:
diff changeset
472 Wchar (Src (J));
kono
parents:
diff changeset
473 end loop;
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 Write_Str ("<--");
kono
parents:
diff changeset
476 Write_Eol;
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 if Src (Hi) /= EOF then
kono
parents:
diff changeset
479 Write_Str (" error: no EOF at end");
kono
parents:
diff changeset
480 Write_Eol;
kono
parents:
diff changeset
481 end if;
kono
parents:
diff changeset
482 end;
kono
parents:
diff changeset
483 end if;
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 declare
kono
parents:
diff changeset
486 S : Source_File_Record renames Source_File.Table (X);
kono
parents:
diff changeset
487 File_Type : Type_Of_File;
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 begin
kono
parents:
diff changeset
490 case T is
kono
parents:
diff changeset
491 when Osint.Source =>
kono
parents:
diff changeset
492 File_Type := Sinput.Src;
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 when Osint.Library =>
kono
parents:
diff changeset
495 raise Program_Error;
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 when Osint.Config =>
kono
parents:
diff changeset
498 File_Type := Sinput.Config;
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 when Osint.Definition =>
kono
parents:
diff changeset
501 File_Type := Def;
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 when Osint.Preprocessing_Data =>
kono
parents:
diff changeset
504 File_Type := Preproc;
kono
parents:
diff changeset
505 end case;
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 S := (Debug_Source_Name => N,
kono
parents:
diff changeset
508 File_Name => N,
kono
parents:
diff changeset
509 File_Type => File_Type,
kono
parents:
diff changeset
510 First_Mapped_Line => No_Line_Number,
kono
parents:
diff changeset
511 Full_Debug_Name => Osint.Full_Source_Name,
kono
parents:
diff changeset
512 Full_File_Name => Osint.Full_Source_Name,
kono
parents:
diff changeset
513 Full_Ref_Name => Osint.Full_Source_Name,
kono
parents:
diff changeset
514 Instance => No_Instance_Id,
kono
parents:
diff changeset
515 Identifier_Casing => Unknown,
kono
parents:
diff changeset
516 Inlined_Call => No_Location,
kono
parents:
diff changeset
517 Inlined_Body => False,
kono
parents:
diff changeset
518 Inherited_Pragma => False,
kono
parents:
diff changeset
519 Keyword_Casing => Unknown,
kono
parents:
diff changeset
520 Last_Source_Line => 1,
kono
parents:
diff changeset
521 License => Unknown,
kono
parents:
diff changeset
522 Lines_Table => null,
kono
parents:
diff changeset
523 Lines_Table_Max => 1,
kono
parents:
diff changeset
524 Logical_Lines_Table => null,
kono
parents:
diff changeset
525 Num_SRef_Pragmas => 0,
kono
parents:
diff changeset
526 Reference_Name => N,
kono
parents:
diff changeset
527 Sloc_Adjust => 0,
kono
parents:
diff changeset
528 Source_Checksum => 0,
kono
parents:
diff changeset
529 Source_First => Lo,
kono
parents:
diff changeset
530 Source_Last => Hi,
kono
parents:
diff changeset
531 Source_Text => Src,
kono
parents:
diff changeset
532 Template => No_Source_File,
kono
parents:
diff changeset
533 Unit => No_Unit,
kono
parents:
diff changeset
534 Time_Stamp => Osint.Current_Source_File_Stamp,
kono
parents:
diff changeset
535 Index => X);
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 Alloc_Line_Tables (S, Opt.Table_Factor * Alloc.Lines_Initial);
kono
parents:
diff changeset
538 S.Lines_Table (1) := Lo;
kono
parents:
diff changeset
539 end;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 -- Preprocess the source if it needs to be preprocessed
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 if Preprocessing_Needed then
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 -- Temporarily set the Source_File_Index_Table entries for the
kono
parents:
diff changeset
546 -- source, to avoid crash when reporting an error.
kono
parents:
diff changeset
547
kono
parents:
diff changeset
548 Set_Source_File_Index_Table (X);
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 if Opt.List_Preprocessing_Symbols then
kono
parents:
diff changeset
551 Get_Name_String (N);
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 declare
kono
parents:
diff changeset
554 Foreword : String (1 .. Foreword_Start'Length +
kono
parents:
diff changeset
555 Name_Len + Foreword_End'Length);
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 begin
kono
parents:
diff changeset
558 Foreword (1 .. Foreword_Start'Length) := Foreword_Start;
kono
parents:
diff changeset
559 Foreword (Foreword_Start'Length + 1 ..
kono
parents:
diff changeset
560 Foreword_Start'Length + Name_Len) :=
kono
parents:
diff changeset
561 Name_Buffer (1 .. Name_Len);
kono
parents:
diff changeset
562 Foreword (Foreword'Last - Foreword_End'Length + 1 ..
kono
parents:
diff changeset
563 Foreword'Last) := Foreword_End;
kono
parents:
diff changeset
564 Prep.List_Symbols (Foreword);
kono
parents:
diff changeset
565 end;
kono
parents:
diff changeset
566 end if;
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 declare
kono
parents:
diff changeset
569 T : constant Nat := Total_Errors_Detected;
kono
parents:
diff changeset
570 -- Used to check if there were errors during preprocessing
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 Save_Style_Check : Boolean;
kono
parents:
diff changeset
573 -- Saved state of the Style_Check flag (which needs to be
kono
parents:
diff changeset
574 -- temporarily set to False during preprocessing, see below).
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 Modified : Boolean;
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 begin
kono
parents:
diff changeset
579 -- If this is the first time we preprocess a source, allocate
kono
parents:
diff changeset
580 -- the preprocessing buffer.
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 if Prep_Buffer = null then
kono
parents:
diff changeset
583 Prep_Buffer :=
kono
parents:
diff changeset
584 new Text_Buffer (1 .. Initial_Size_Of_Prep_Buffer);
kono
parents:
diff changeset
585 end if;
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 -- Make sure the preprocessing buffer is empty
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 Prep_Buffer_Last := 0;
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 -- Initialize the preprocessor hooks
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 Prep.Setup_Hooks
kono
parents:
diff changeset
594 (Error_Msg => Errout.Error_Msg'Access,
kono
parents:
diff changeset
595 Scan => Scn.Scanner.Scan'Access,
kono
parents:
diff changeset
596 Set_Ignore_Errors => Errout.Set_Ignore_Errors'Access,
kono
parents:
diff changeset
597 Put_Char => Put_Char_In_Prep_Buffer'Access,
kono
parents:
diff changeset
598 New_EOL => New_EOL_In_Prep_Buffer'Access);
kono
parents:
diff changeset
599
kono
parents:
diff changeset
600 -- Initialize scanner and set its behavior for preprocessing,
kono
parents:
diff changeset
601 -- then preprocess. Also disable style checks, since some of
kono
parents:
diff changeset
602 -- them are done in the scanner (specifically, those dealing
kono
parents:
diff changeset
603 -- with line length and line termination), and cannot be done
kono
parents:
diff changeset
604 -- during preprocessing (because the source file index table
kono
parents:
diff changeset
605 -- has not been set yet).
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 Scn.Scanner.Initialize_Scanner (X);
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 Scn.Scanner.Set_Special_Character ('#');
kono
parents:
diff changeset
610 Scn.Scanner.Set_Special_Character ('$');
kono
parents:
diff changeset
611 Scn.Scanner.Set_End_Of_Line_As_Token (True);
kono
parents:
diff changeset
612 Save_Style_Check := Opt.Style_Check;
kono
parents:
diff changeset
613 Opt.Style_Check := False;
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 -- The actual preprocessing step
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 Preprocess (Modified);
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 -- Reset the scanner to its standard behavior, and restore the
kono
parents:
diff changeset
620 -- Style_Checks flag.
kono
parents:
diff changeset
621
kono
parents:
diff changeset
622 Scn.Scanner.Reset_Special_Characters;
kono
parents:
diff changeset
623 Scn.Scanner.Set_End_Of_Line_As_Token (False);
kono
parents:
diff changeset
624 Opt.Style_Check := Save_Style_Check;
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 -- If there were errors during preprocessing, record an error
kono
parents:
diff changeset
627 -- at the start of the file, and do not change the source
kono
parents:
diff changeset
628 -- buffer.
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 if T /= Total_Errors_Detected then
kono
parents:
diff changeset
631 Errout.Error_Msg
kono
parents:
diff changeset
632 ("file could not be successfully preprocessed", Lo);
kono
parents:
diff changeset
633 return No_Source_File;
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 else
kono
parents:
diff changeset
636 -- Output the result of the preprocessing, if requested and
kono
parents:
diff changeset
637 -- the source has been modified by the preprocessing. Only
kono
parents:
diff changeset
638 -- do that for the main unit (spec, body and subunits).
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 if Generate_Processed_File
kono
parents:
diff changeset
641 and then Modified
kono
parents:
diff changeset
642 and then
kono
parents:
diff changeset
643 ((Compiler_State = Parsing
kono
parents:
diff changeset
644 and then Parsing_Main_Extended_Source)
kono
parents:
diff changeset
645 or else
kono
parents:
diff changeset
646 (Compiler_State = Analyzing
kono
parents:
diff changeset
647 and then Analysing_Subunit_Of_Main))
kono
parents:
diff changeset
648 then
kono
parents:
diff changeset
649 declare
kono
parents:
diff changeset
650 FD : File_Descriptor;
kono
parents:
diff changeset
651 NB : Integer;
kono
parents:
diff changeset
652 Status : Boolean;
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 begin
kono
parents:
diff changeset
655 Get_Name_String (N);
kono
parents:
diff changeset
656 Add_Str_To_Name_Buffer (Prep_Suffix);
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 Delete_File (Name_Buffer (1 .. Name_Len), Status);
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 FD :=
kono
parents:
diff changeset
661 Create_New_File (Name_Buffer (1 .. Name_Len), Text);
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 Status := FD /= Invalid_FD;
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 if Status then
kono
parents:
diff changeset
666 NB :=
kono
parents:
diff changeset
667 Write
kono
parents:
diff changeset
668 (FD,
kono
parents:
diff changeset
669 Prep_Buffer (1)'Address,
kono
parents:
diff changeset
670 Integer (Prep_Buffer_Last));
kono
parents:
diff changeset
671 Status := NB = Integer (Prep_Buffer_Last);
kono
parents:
diff changeset
672 end if;
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 if Status then
kono
parents:
diff changeset
675 Close (FD, Status);
kono
parents:
diff changeset
676 end if;
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 if not Status then
kono
parents:
diff changeset
679 Errout.Error_Msg
kono
parents:
diff changeset
680 ("??could not write processed file """ &
kono
parents:
diff changeset
681 Name_Buffer (1 .. Name_Len) & '"',
kono
parents:
diff changeset
682 Lo);
kono
parents:
diff changeset
683 end if;
kono
parents:
diff changeset
684 end;
kono
parents:
diff changeset
685 end if;
kono
parents:
diff changeset
686
kono
parents:
diff changeset
687 -- Set the new value of Hi
kono
parents:
diff changeset
688
kono
parents:
diff changeset
689 Hi := Lo + Source_Ptr (Prep_Buffer_Last);
kono
parents:
diff changeset
690
kono
parents:
diff changeset
691 -- Create the new source buffer
kono
parents:
diff changeset
692
kono
parents:
diff changeset
693 declare
kono
parents:
diff changeset
694 Var_Ptr : constant Source_Buffer_Ptr_Var :=
kono
parents:
diff changeset
695 new Source_Buffer (Lo .. Hi);
kono
parents:
diff changeset
696 -- Allocate source buffer, allowing extra character at
kono
parents:
diff changeset
697 -- end for EOF.
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 begin
kono
parents:
diff changeset
700 Var_Ptr (Lo .. Hi - 1) :=
kono
parents:
diff changeset
701 Prep_Buffer (1 .. Prep_Buffer_Last);
kono
parents:
diff changeset
702 Var_Ptr (Hi) := EOF;
kono
parents:
diff changeset
703 Src := Var_Ptr.all'Access;
kono
parents:
diff changeset
704 end;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 -- Record in the table the new source buffer and the
kono
parents:
diff changeset
707 -- new value of Hi.
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 Source_File.Table (X).Source_Text := Src;
kono
parents:
diff changeset
710 Source_File.Table (X).Source_Last := Hi;
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 -- Reset Last_Line to 1, because the lines do not
kono
parents:
diff changeset
713 -- have necessarily the same starts and lengths.
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 Source_File.Table (X).Last_Source_Line := 1;
kono
parents:
diff changeset
716 end if;
kono
parents:
diff changeset
717 end;
kono
parents:
diff changeset
718 end if;
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 Set_Source_File_Index_Table (X);
kono
parents:
diff changeset
721 return X;
kono
parents:
diff changeset
722 end if;
kono
parents:
diff changeset
723 end Load_File;
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 ----------------------------------
kono
parents:
diff changeset
726 -- Load_Preprocessing_Data_File --
kono
parents:
diff changeset
727 ----------------------------------
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 function Load_Preprocessing_Data_File
kono
parents:
diff changeset
730 (N : File_Name_Type) return Source_File_Index
kono
parents:
diff changeset
731 is
kono
parents:
diff changeset
732 begin
kono
parents:
diff changeset
733 return Load_File (N, Osint.Preprocessing_Data);
kono
parents:
diff changeset
734 end Load_Preprocessing_Data_File;
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 ----------------------
kono
parents:
diff changeset
737 -- Load_Source_File --
kono
parents:
diff changeset
738 ----------------------
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 function Load_Source_File
kono
parents:
diff changeset
741 (N : File_Name_Type) return Source_File_Index
kono
parents:
diff changeset
742 is
kono
parents:
diff changeset
743 begin
kono
parents:
diff changeset
744 return Load_File (N, Osint.Source);
kono
parents:
diff changeset
745 end Load_Source_File;
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 ----------------------------
kono
parents:
diff changeset
748 -- New_EOL_In_Prep_Buffer --
kono
parents:
diff changeset
749 ----------------------------
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 procedure New_EOL_In_Prep_Buffer is
kono
parents:
diff changeset
752 begin
kono
parents:
diff changeset
753 Put_Char_In_Prep_Buffer (ASCII.LF);
kono
parents:
diff changeset
754 end New_EOL_In_Prep_Buffer;
kono
parents:
diff changeset
755
kono
parents:
diff changeset
756 -----------------------------
kono
parents:
diff changeset
757 -- Put_Char_In_Prep_Buffer --
kono
parents:
diff changeset
758 -----------------------------
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 procedure Put_Char_In_Prep_Buffer (C : Character) is
kono
parents:
diff changeset
761 begin
kono
parents:
diff changeset
762 -- If preprocessing buffer is not large enough, double it
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 if Prep_Buffer_Last = Prep_Buffer'Last then
kono
parents:
diff changeset
765 declare
kono
parents:
diff changeset
766 New_Prep_Buffer : constant Text_Buffer_Ptr :=
kono
parents:
diff changeset
767 new Text_Buffer (1 .. 2 * Prep_Buffer_Last);
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 begin
kono
parents:
diff changeset
770 New_Prep_Buffer (Prep_Buffer'Range) := Prep_Buffer.all;
kono
parents:
diff changeset
771 Free (Prep_Buffer);
kono
parents:
diff changeset
772 Prep_Buffer := New_Prep_Buffer;
kono
parents:
diff changeset
773 end;
kono
parents:
diff changeset
774 end if;
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 Prep_Buffer_Last := Prep_Buffer_Last + 1;
kono
parents:
diff changeset
777 Prep_Buffer (Prep_Buffer_Last) := C;
kono
parents:
diff changeset
778 end Put_Char_In_Prep_Buffer;
kono
parents:
diff changeset
779
kono
parents:
diff changeset
780 -------------------------
kono
parents:
diff changeset
781 -- Source_File_Is_Body --
kono
parents:
diff changeset
782 -------------------------
kono
parents:
diff changeset
783
kono
parents:
diff changeset
784 function Source_File_Is_Body (X : Source_File_Index) return Boolean is
kono
parents:
diff changeset
785 Pcount : Natural;
kono
parents:
diff changeset
786
kono
parents:
diff changeset
787 begin
kono
parents:
diff changeset
788 Initialize_Scanner (No_Unit, X);
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 -- Loop to look for subprogram or package body
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 loop
kono
parents:
diff changeset
793 case Token is
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 -- PRAGMA, WITH, USE (which can appear before a body)
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 when Tok_Pragma
kono
parents:
diff changeset
798 | Tok_Use
kono
parents:
diff changeset
799 | Tok_With
kono
parents:
diff changeset
800 =>
kono
parents:
diff changeset
801 -- We just want to skip any of these, do it by skipping to a
kono
parents:
diff changeset
802 -- semicolon, but check for EOF, in case we have bad syntax.
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 loop
kono
parents:
diff changeset
805 if Token = Tok_Semicolon then
kono
parents:
diff changeset
806 Scan;
kono
parents:
diff changeset
807 exit;
kono
parents:
diff changeset
808 elsif Token = Tok_EOF then
kono
parents:
diff changeset
809 return False;
kono
parents:
diff changeset
810 else
kono
parents:
diff changeset
811 Scan;
kono
parents:
diff changeset
812 end if;
kono
parents:
diff changeset
813 end loop;
kono
parents:
diff changeset
814
kono
parents:
diff changeset
815 -- PACKAGE
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 when Tok_Package =>
kono
parents:
diff changeset
818 Scan; -- Past PACKAGE
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 -- We have a body if and only if BODY follows
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 return Token = Tok_Body;
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 -- FUNCTION or PROCEDURE
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 when Tok_Function
kono
parents:
diff changeset
827 | Tok_Procedure
kono
parents:
diff changeset
828 =>
kono
parents:
diff changeset
829 Pcount := 0;
kono
parents:
diff changeset
830
kono
parents:
diff changeset
831 -- Loop through tokens following PROCEDURE or FUNCTION
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 loop
kono
parents:
diff changeset
834 Scan;
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 case Token is
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 -- For parens, count paren level (note that paren level
kono
parents:
diff changeset
839 -- can get greater than 1 if we have default parameters).
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 when Tok_Left_Paren =>
kono
parents:
diff changeset
842 Pcount := Pcount + 1;
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 when Tok_Right_Paren =>
kono
parents:
diff changeset
845 Pcount := Pcount - 1;
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 -- EOF means something weird, probably no body
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 when Tok_EOF =>
kono
parents:
diff changeset
850 return False;
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 -- BEGIN or IS or END definitely means body is present
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 when Tok_Begin
kono
parents:
diff changeset
855 | Tok_End
kono
parents:
diff changeset
856 | Tok_Is
kono
parents:
diff changeset
857 =>
kono
parents:
diff changeset
858 return True;
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 -- Semicolon means no body present if at outside any
kono
parents:
diff changeset
861 -- parens. If within parens, ignore, since it could be
kono
parents:
diff changeset
862 -- a parameter separator.
kono
parents:
diff changeset
863
kono
parents:
diff changeset
864 when Tok_Semicolon =>
kono
parents:
diff changeset
865 if Pcount = 0 then
kono
parents:
diff changeset
866 return False;
kono
parents:
diff changeset
867 end if;
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 -- Skip anything else
kono
parents:
diff changeset
870
kono
parents:
diff changeset
871 when others =>
kono
parents:
diff changeset
872 null;
kono
parents:
diff changeset
873 end case;
kono
parents:
diff changeset
874 end loop;
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 -- Anything else in main scan means we don't have a body
kono
parents:
diff changeset
877
kono
parents:
diff changeset
878 when others =>
kono
parents:
diff changeset
879 return False;
kono
parents:
diff changeset
880 end case;
kono
parents:
diff changeset
881 end loop;
kono
parents:
diff changeset
882 end Source_File_Is_Body;
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 ----------------------------
kono
parents:
diff changeset
885 -- Source_File_Is_No_Body --
kono
parents:
diff changeset
886 ----------------------------
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 function Source_File_Is_No_Body (X : Source_File_Index) return Boolean is
kono
parents:
diff changeset
889 begin
kono
parents:
diff changeset
890 Initialize_Scanner (No_Unit, X);
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 if Token /= Tok_Pragma then
kono
parents:
diff changeset
893 return False;
kono
parents:
diff changeset
894 end if;
kono
parents:
diff changeset
895
kono
parents:
diff changeset
896 Scan; -- past pragma
kono
parents:
diff changeset
897
kono
parents:
diff changeset
898 if Token /= Tok_Identifier
kono
parents:
diff changeset
899 or else Chars (Token_Node) /= Name_No_Body
kono
parents:
diff changeset
900 then
kono
parents:
diff changeset
901 return False;
kono
parents:
diff changeset
902 end if;
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904 Scan; -- past No_Body
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 if Token /= Tok_Semicolon then
kono
parents:
diff changeset
907 return False;
kono
parents:
diff changeset
908 end if;
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 Scan; -- past semicolon
kono
parents:
diff changeset
911
kono
parents:
diff changeset
912 return Token = Tok_EOF;
kono
parents:
diff changeset
913 end Source_File_Is_No_Body;
kono
parents:
diff changeset
914
kono
parents:
diff changeset
915 end Sinput.L;