]>
Commit | Line | Data |
---|---|---|
e63f29e8 AC |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
f96fd197 | 3 | -- GNAT COMPILER COMPONENTS -- |
e63f29e8 AC |
4 | -- -- |
5 | -- A D A B K E N D -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
8d0d46f4 | 9 | -- Copyright (C) 2001-2021, AdaCore -- |
e63f29e8 AC |
10 | -- -- |
11 | -- GNAT is free software; you can redistribute it and/or modify it under -- | |
12 | -- terms of the GNU General Public License as published by the Free Soft- -- | |
13 | -- ware Foundation; either version 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. -- | |
20 | -- -- | |
21 | ------------------------------------------------------------------------------ | |
22 | ||
23 | -- This is the version of the Back_End package for back ends written in Ada | |
24 | ||
f71b4cd4 | 25 | with Atree; use Atree; |
e63f29e8 AC |
26 | with Debug; |
27 | with Lib; | |
28 | with Opt; use Opt; | |
29 | with Output; use Output; | |
30 | with Osint; use Osint; | |
31 | with Osint.C; use Osint.C; | |
32 | with Switch.C; use Switch.C; | |
33 | with Types; use Types; | |
34 | ||
35 | with System.OS_Lib; use System.OS_Lib; | |
36 | ||
37 | package body Adabkend is | |
38 | ||
39 | use Switch; | |
40 | ||
41 | ------------------- | |
42 | -- Call_Back_End -- | |
43 | ------------------- | |
44 | ||
45 | procedure Call_Back_End is | |
46 | begin | |
47 | if (Opt.Verbose_Mode or Opt.Full_List) | |
48 | and then not Debug.Debug_Flag_7 | |
49 | then | |
50 | Write_Eol; | |
51 | Write_Str (Product_Name); | |
52 | Write_Str (", Copyright "); | |
53 | Write_Str (Copyright_Years); | |
54 | Write_Str (" Ada Core Technologies, Inc."); | |
55 | Write_Str (" (http://www.adacore.com)"); | |
56 | Write_Eol; | |
57 | Write_Eol; | |
58 | end if; | |
59 | ||
d449ed75 PMR |
60 | -- The front end leaves the Current_Error_Node at a location that is |
61 | -- meaningless and confusing when emitting bug boxes from the back end. | |
7f5e671b PMR |
62 | -- Reset the global variable in order to emit "No source file position |
63 | -- information available" messages on back end crashes. | |
f71b4cd4 PMR |
64 | |
65 | Current_Error_Node := Empty; | |
66 | ||
e63f29e8 AC |
67 | Driver (Lib.Cunit (Types.Main_Unit)); |
68 | end Call_Back_End; | |
69 | ||
8016e567 PT |
70 | ----------------------------- |
71 | -- Scan_Compiler_Arguments -- | |
72 | ----------------------------- | |
e63f29e8 AC |
73 | |
74 | procedure Scan_Compiler_Arguments is | |
75 | Output_File_Name_Seen : Boolean := False; | |
76 | -- Set to True after having scanned the file_name for switch | |
77 | -- "-gnatO file_name" | |
78 | ||
79 | Argument_Count : constant Integer := Arg_Count - 1; | |
80 | -- Number of arguments (excluding program name) | |
81 | ||
82 | Args : Argument_List (1 .. Argument_Count); | |
83 | Next_Arg : Positive := 1; | |
84 | ||
85 | procedure Scan_Back_End_Switches (Switch_Chars : String); | |
86 | -- Procedure to scan out switches stored in Switch_Chars. The first | |
87 | -- character is known to be a valid switch character, and there are no | |
88 | -- blanks or other switch terminator characters in the string, so the | |
89 | -- entire string should consist of valid switch characters, except that | |
90 | -- an optional terminating NUL character is allowed. | |
91 | -- | |
92 | -- If the switch is not valid, control will not return. The switches | |
93 | -- must still be scanned to skip the "-o" arguments, or internal GCC | |
d449ed75 | 94 | -- switches, which may be safely ignored by other back ends. |
e63f29e8 AC |
95 | |
96 | ---------------------------- | |
97 | -- Scan_Back_End_Switches -- | |
98 | ---------------------------- | |
99 | ||
100 | procedure Scan_Back_End_Switches (Switch_Chars : String) is | |
101 | First : constant Positive := Switch_Chars'First + 1; | |
102 | Last : constant Natural := Switch_Last (Switch_Chars); | |
103 | ||
104 | begin | |
105 | -- Process any back end switches, returning if the switch does not | |
106 | -- affect code generation or falling through if it does, so the | |
107 | -- switch will get stored. | |
108 | ||
0e77949e AC |
109 | -- Skip -o, -G or internal GCC switches together with their argument. |
110 | ||
111 | if Switch_Chars (First .. Last) = "o" | |
112 | or else Switch_Chars (First .. Last) = "G" | |
113 | or else Is_Internal_GCC_Switch (Switch_Chars) | |
114 | then | |
e63f29e8 AC |
115 | Next_Arg := Next_Arg + 1; |
116 | return; -- ignore this switch | |
117 | ||
e63f29e8 AC |
118 | -- Set optimization indicators appropriately. In gcc-based GNAT this |
119 | -- is picked up from imported variables set by the gcc driver, but | |
9cbb5574 YM |
120 | -- for compilers with non-gcc back ends we do it here to allow use of |
121 | -- these switches by the front end. Allowed optimization switches are | |
122 | -- -Os (optimize for size), -O[0123], -O (same as -O1), -Ofast | |
123 | -- (disregard strict standards compliance), and -Og (optimize | |
124 | -- debugging experience). | |
e63f29e8 AC |
125 | |
126 | elsif Switch_Chars (First) = 'O' then | |
127 | if First = Last then | |
128 | Optimization_Level := 1; | |
129 | ||
130 | elsif Last - First = 1 then | |
131 | if Switch_Chars (Last) = 's' then | |
132 | Optimize_Size := 1; | |
133 | Optimization_Level := 2; -- Consistent with gcc setting | |
134 | ||
135 | elsif Switch_Chars (Last) in '0' .. '3' then | |
136 | Optimization_Level := | |
137 | Character'Pos (Switch_Chars (Last)) - Character'Pos ('0'); | |
138 | ||
9cbb5574 YM |
139 | -- Switch -Og is between -O0 and -O1 in GCC. Consider it like |
140 | -- -O0 for other back ends. | |
141 | ||
142 | elsif Switch_Chars (Last) = 'g' then | |
143 | Optimization_Level := 0; | |
144 | ||
e63f29e8 AC |
145 | else |
146 | Fail ("invalid switch: " & Switch_Chars); | |
147 | end if; | |
148 | ||
9cbb5574 YM |
149 | -- Switch -Ofast enables -O3 |
150 | ||
151 | elsif Switch_Chars (First + 1 .. Last) = "fast" then | |
152 | Optimization_Level := 3; | |
153 | ||
e63f29e8 AC |
154 | else |
155 | Fail ("invalid switch: " & Switch_Chars); | |
156 | end if; | |
157 | ||
158 | elsif Switch_Chars (First .. Last) = "quiet" then | |
159 | return; -- ignore this switch | |
160 | ||
161 | elsif Switch_Chars (First .. Last) = "c" then | |
162 | return; -- ignore this switch | |
163 | ||
164 | -- The -x switch and its language name argument will generally be | |
f96fd197 AC |
165 | -- ignored by non-gcc back ends. In any case, we save the switch and |
166 | -- argument in the compilation switches. | |
e63f29e8 AC |
167 | |
168 | elsif Switch_Chars (First .. Last) = "x" then | |
169 | Lib.Store_Compilation_Switch (Switch_Chars); | |
170 | Next_Arg := Next_Arg + 1; | |
171 | ||
172 | declare | |
173 | Argv : constant String := Args (Next_Arg).all; | |
174 | ||
175 | begin | |
176 | if Is_Switch (Argv) then | |
177 | Fail ("language name missing after -x"); | |
178 | else | |
179 | Lib.Store_Compilation_Switch (Argv); | |
180 | end if; | |
181 | end; | |
182 | ||
183 | return; | |
184 | ||
9cbb5574 | 185 | -- Special check, the back-end switch -fno-inline also sets the |
17ce1f52 AC |
186 | -- front end flags to entirely inhibit all inlining. So we store it |
187 | -- and set the appropriate flags. | |
e63f29e8 AC |
188 | |
189 | elsif Switch_Chars (First .. Last) = "fno-inline" then | |
190 | Lib.Store_Compilation_Switch (Switch_Chars); | |
17ce1f52 | 191 | Opt.Disable_FE_Inline := True; |
e63f29e8 AC |
192 | return; |
193 | ||
194 | -- Similar processing for -fpreserve-control-flow | |
195 | ||
196 | elsif Switch_Chars (First .. Last) = "fpreserve-control-flow" then | |
197 | Lib.Store_Compilation_Switch (Switch_Chars); | |
198 | Opt.Suppress_Control_Flow_Optimizations := True; | |
199 | return; | |
200 | ||
fb620f0e AC |
201 | -- Recognize -gxxx switches |
202 | ||
203 | elsif Switch_Chars (First) = 'g' then | |
204 | Debugger_Level := 2; | |
205 | ||
206 | if First < Last then | |
207 | case Switch_Chars (First + 1) is | |
208 | when '0' => | |
209 | Debugger_Level := 0; | |
210 | when '1' => | |
211 | Debugger_Level := 1; | |
212 | when '2' => | |
213 | Debugger_Level := 2; | |
214 | when '3' => | |
215 | Debugger_Level := 3; | |
216 | when others => | |
217 | null; | |
218 | end case; | |
219 | end if; | |
220 | ||
eafca96f AC |
221 | elsif Switch_Chars (First .. Last) = "S" then |
222 | Generate_Asm := True; | |
223 | ||
9cbb5574 | 224 | -- Ignore all other back-end switches |
e63f29e8 AC |
225 | |
226 | elsif Is_Back_End_Switch (Switch_Chars) then | |
227 | null; | |
228 | ||
229 | -- Give error for junk switch | |
230 | ||
231 | else | |
232 | Fail ("invalid switch: " & Switch_Chars); | |
233 | end if; | |
234 | ||
235 | -- Store any other GCC switches | |
236 | ||
237 | Lib.Store_Compilation_Switch (Switch_Chars); | |
238 | end Scan_Back_End_Switches; | |
239 | ||
240 | -- Start of processing for Scan_Compiler_Args | |
241 | ||
242 | begin | |
243 | -- Put all the arguments in argument list Args | |
244 | ||
245 | for Arg in 1 .. Argument_Count loop | |
246 | declare | |
247 | Argv : String (1 .. Len_Arg (Arg)); | |
248 | begin | |
249 | Fill_Arg (Argv'Address, Arg); | |
250 | Args (Arg) := new String'(Argv); | |
251 | end; | |
252 | end loop; | |
253 | ||
254 | -- Loop through command line arguments, storing them for later access | |
255 | ||
256 | while Next_Arg <= Argument_Count loop | |
257 | Look_At_Arg : declare | |
258 | Argv : constant String := Args (Next_Arg).all; | |
259 | ||
260 | begin | |
261 | if Argv'Length = 0 then | |
262 | Fail ("Empty argument"); | |
263 | end if; | |
264 | ||
265 | -- If the previous switch has set the Output_File_Name_Present | |
266 | -- flag (that is we have seen a -gnatO), then the next argument | |
267 | -- is the name of the output object file. | |
268 | ||
269 | if Opt.Output_File_Name_Present | |
270 | and then not Output_File_Name_Seen | |
271 | then | |
272 | if Is_Switch (Argv) then | |
273 | Fail ("Object file name missing after -gnatO"); | |
274 | else | |
275 | Set_Output_Object_File_Name (Argv); | |
276 | Output_File_Name_Seen := True; | |
277 | end if; | |
278 | ||
279 | -- If the previous switch has set the Search_Directory_Present | |
280 | -- flag (that is if we have just seen -I), then the next | |
281 | -- argument is a search directory path. | |
282 | ||
283 | elsif Search_Directory_Present then | |
284 | if Is_Switch (Argv) then | |
285 | Fail ("search directory missing after -I"); | |
286 | else | |
287 | Add_Src_Search_Dir (Argv); | |
288 | ||
d449ed75 | 289 | -- Add directory to lib search so that back end can take as |
e63f29e8 AC |
290 | -- input ALI files if needed. Otherwise this won't have any |
291 | -- impact on the compiler. | |
292 | ||
293 | Add_Lib_Search_Dir (Argv); | |
294 | ||
295 | Search_Directory_Present := False; | |
296 | end if; | |
297 | ||
298 | -- If not a switch, must be a file name | |
299 | ||
300 | elsif not Is_Switch (Argv) then | |
301 | Add_File (Argv); | |
302 | ||
47fb6ca8 AC |
303 | -- We must recognize -nostdinc to suppress visibility on the |
304 | -- standard GNAT RTL sources. | |
305 | ||
306 | elsif Argv (Argv'First + 1 .. Argv'Last) = "nostdinc" then | |
307 | Opt.No_Stdinc := True; | |
308 | ||
e63f29e8 AC |
309 | -- Front end switch |
310 | ||
311 | elsif Is_Front_End_Switch (Argv) then | |
312 | Scan_Front_End_Switches (Argv, Args, Next_Arg); | |
313 | ||
314 | -- All non-front-end switches are back-end switches | |
315 | ||
316 | else | |
317 | Scan_Back_End_Switches (Argv); | |
318 | end if; | |
319 | end Look_At_Arg; | |
320 | ||
321 | Next_Arg := Next_Arg + 1; | |
322 | end loop; | |
323 | end Scan_Compiler_Arguments; | |
324 | ||
325 | end Adabkend; |