Typo in last patch.
[official-gcc.git] / gcc / ada / gnatbind.adb
blob3dc76ef09322ef6718f0cc2eccdbbf7321be78cd
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- G N A T B I N D --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
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 2, 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 COPYING. If not, write --
19 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 with ALI; use ALI;
28 with ALI.Util; use ALI.Util;
29 with Bcheck; use Bcheck;
30 with Binde; use Binde;
31 with Binderr; use Binderr;
32 with Bindgen; use Bindgen;
33 with Bindusg;
34 with Butil; use Butil;
35 with Casing; use Casing;
36 with Csets;
37 with Debug; use Debug;
38 with Fmap;
39 with Gnatvsn; use Gnatvsn;
40 with Namet; use Namet;
41 with Opt; use Opt;
42 with Osint; use Osint;
43 with Osint.B; use Osint.B;
44 with Output; use Output;
45 with Rident; use Rident;
46 with Switch; use Switch;
47 with Switch.B; use Switch.B;
48 with Targparm; use Targparm;
49 with Types; use Types;
51 with System.Case_Util; use System.Case_Util;
53 procedure Gnatbind is
55 Total_Errors : Nat := 0;
56 -- Counts total errors in all files
58 Total_Warnings : Nat := 0;
59 -- Total warnings in all files
61 Main_Lib_File : File_Name_Type;
62 -- Current main library file
64 Std_Lib_File : File_Name_Type;
65 -- Standard library
67 Text : Text_Buffer_Ptr;
68 Next_Arg : Positive;
70 Output_File_Name_Seen : Boolean := False;
71 Output_File_Name : String_Ptr := new String'("");
73 L_Switch_Seen : Boolean := False;
75 Mapping_File : String_Ptr := null;
77 procedure List_Applicable_Restrictions;
78 -- List restrictions that apply to this partition if option taken
80 procedure Scan_Bind_Arg (Argv : String);
81 -- Scan and process binder specific arguments. Argv is a single argument.
82 -- All the one character arguments are still handled by Switch. This
83 -- routine handles -aO -aI and -I-.
85 ----------------------------------
86 -- List_Applicable_Restrictions --
87 ----------------------------------
89 procedure List_Applicable_Restrictions is
91 -- Define those restrictions that should be output if the gnatbind
92 -- -r switch is used. Not all restrictions are output for the reasons
93 -- given above in the list, and this array is used to test whether
94 -- the corresponding pragma should be listed. True means that it
95 -- should not be listed.
97 No_Restriction_List : constant array (All_Restrictions) of Boolean :=
98 (No_Exceptions => True,
99 -- Has unexpected Suppress (All_Checks) effect
101 No_Implicit_Conditionals => True,
102 -- This could modify and pessimize generated code
104 No_Implicit_Dynamic_Code => True,
105 -- This could modify and pessimize generated code
107 No_Implicit_Loops => True,
108 -- This could modify and pessimize generated code
110 No_Recursion => True,
111 -- Not checkable at compile time
113 No_Reentrancy => True,
114 -- Not checkable at compile time
116 Max_Entry_Queue_Length => True,
117 -- Not checkable at compile time
119 Max_Storage_At_Blocking => True,
120 -- Not checkable at compile time
122 others => False);
124 Additional_Restrictions_Listed : Boolean := False;
125 -- Set True if we have listed header for restrictions
127 begin
128 -- Loop through restrictions
130 for R in All_Restrictions loop
131 if not No_Restriction_List (R) then
133 -- We list a restriction if it is not violated, or if
134 -- it is violated but the violation count is exactly known.
136 if Cumulative_Restrictions.Violated (R) = False
137 or else (R in All_Parameter_Restrictions
138 and then
139 Cumulative_Restrictions.Unknown (R) = False)
140 then
141 if not Additional_Restrictions_Listed then
142 Write_Eol;
143 Write_Line
144 ("The following additional restrictions may be" &
145 " applied to this partition:");
146 Additional_Restrictions_Listed := True;
147 end if;
149 Write_Str ("pragma Restrictions (");
151 declare
152 S : constant String := Restriction_Id'Image (R);
153 begin
154 Name_Len := S'Length;
155 Name_Buffer (1 .. Name_Len) := S;
156 end;
158 Set_Casing (Mixed_Case);
159 Write_Str (Name_Buffer (1 .. Name_Len));
161 if R in All_Parameter_Restrictions then
162 Write_Str (" => ");
163 Write_Int (Int (Cumulative_Restrictions.Count (R)));
164 end if;
166 Write_Str (");");
167 Write_Eol;
168 end if;
169 end if;
170 end loop;
171 end List_Applicable_Restrictions;
173 -------------------
174 -- Scan_Bind_Arg --
175 -------------------
177 procedure Scan_Bind_Arg (Argv : String) is
178 begin
179 -- Now scan arguments that are specific to the binder and are not
180 -- handled by the common circuitry in Switch.
182 if Opt.Output_File_Name_Present
183 and then not Output_File_Name_Seen
184 then
185 Output_File_Name_Seen := True;
187 if Argv'Length = 0
188 or else (Argv'Length >= 1 and then Argv (1) = '-')
189 then
190 Fail ("output File_Name missing after -o");
192 else
193 Output_File_Name := new String'(Argv);
194 end if;
196 elsif Argv'Length >= 2 and then Argv (1) = '-' then
198 -- -I-
200 if Argv (2 .. Argv'Last) = "I-" then
201 Opt.Look_In_Primary_Dir := False;
203 -- -Idir
205 elsif Argv (2) = 'I' then
206 Add_Src_Search_Dir (Argv (3 .. Argv'Last));
207 Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
209 -- -Ldir
211 elsif Argv (2) = 'L' then
212 if Argv'Length >= 3 then
214 -- Remember that the -L switch was specified, so that if this
215 -- is on OpenVMS, the export names are put in uppercase.
216 -- This is not known before the target parameters are read.
218 L_Switch_Seen := True;
220 Opt.Bind_For_Library := True;
221 Opt.Ada_Init_Name :=
222 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Init_Suffix);
223 Opt.Ada_Final_Name :=
224 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Final_Suffix);
225 Opt.Ada_Main_Name :=
226 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Main_Name_Suffix);
228 -- This option (-Lxxx) implies -n
230 Opt.Bind_Main_Program := False;
232 else
233 Fail
234 ("Prefix of initialization and finalization " &
235 "procedure names missing in -L");
236 end if;
238 -- -Sin -Slo -Shi -Sxx
240 elsif Argv'Length = 4
241 and then Argv (2) = 'S'
242 then
243 declare
244 C1 : Character := Argv (3);
245 C2 : Character := Argv (4);
247 begin
248 -- Fold to upper case
250 if C1 in 'a' .. 'z' then
251 C1 := Character'Val (Character'Pos (C1) - 32);
252 end if;
254 if C2 in 'a' .. 'z' then
255 C2 := Character'Val (Character'Pos (C2) - 32);
256 end if;
258 -- Test valid option and set mode accordingly
260 if C1 = 'E' and then C2 = 'V' then
261 null;
263 elsif C1 = 'I' and then C2 = 'N' then
264 null;
266 elsif C1 = 'L' and then C2 = 'O' then
267 null;
269 elsif C1 = 'H' and then C2 = 'I' then
270 null;
272 elsif (C1 in '0' .. '9' or else C1 in 'A' .. 'F')
273 and then
274 (C2 in '0' .. '9' or else C2 in 'A' .. 'F')
275 then
276 null;
278 -- Invalid -S switch, let Switch give error, set defalut of IN
280 else
281 Scan_Binder_Switches (Argv);
282 C1 := 'I';
283 C2 := 'N';
284 end if;
286 Initialize_Scalars_Mode1 := C1;
287 Initialize_Scalars_Mode2 := C2;
288 end;
290 -- -aIdir
292 elsif Argv'Length >= 3
293 and then Argv (2 .. 3) = "aI"
294 then
295 Add_Src_Search_Dir (Argv (4 .. Argv'Last));
297 -- -aOdir
299 elsif Argv'Length >= 3
300 and then Argv (2 .. 3) = "aO"
301 then
302 Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
304 -- -nostdlib
306 elsif Argv (2 .. Argv'Last) = "nostdlib" then
307 Opt.No_Stdlib := True;
309 -- -nostdinc
311 elsif Argv (2 .. Argv'Last) = "nostdinc" then
312 Opt.No_Stdinc := True;
314 -- -static
316 elsif Argv (2 .. Argv'Last) = "static" then
317 Opt.Shared_Libgnat := False;
319 -- -shared
321 elsif Argv (2 .. Argv'Last) = "shared" then
322 Opt.Shared_Libgnat := True;
324 -- -F=mapping_file
326 elsif Argv'Length >= 4 and then Argv (2 .. 3) = "F=" then
327 if Mapping_File /= null then
328 Fail ("cannot specify several mapping files");
329 end if;
331 Mapping_File := new String'(Argv (4 .. Argv'Last));
333 -- -Mname
335 elsif Argv'Length >= 3 and then Argv (2) = 'M' then
336 Opt.Bind_Alternate_Main_Name := True;
337 Opt.Alternate_Main_Name := new String'(Argv (3 .. Argv'Last));
339 -- All other options are single character and are handled
340 -- by Scan_Binder_Switches.
342 else
343 Scan_Binder_Switches (Argv);
344 end if;
346 -- Not a switch, so must be a file name (if non-empty)
348 elsif Argv'Length /= 0 then
349 if Argv'Length > 4
350 and then Argv (Argv'Last - 3 .. Argv'Last) = ".ali"
351 then
352 Add_File (Argv);
353 else
354 Add_File (Argv & ".ali");
355 end if;
356 end if;
357 end Scan_Bind_Arg;
359 -- Start of processing for Gnatbind
361 begin
363 -- Set default for Shared_Libgnat option
365 declare
366 Shared_Libgnat_Default : Character;
367 pragma Import
368 (C, Shared_Libgnat_Default, "__gnat_shared_libgnat_default");
370 SHARED : constant Character := 'H';
371 STATIC : constant Character := 'T';
373 begin
374 pragma Assert
375 (Shared_Libgnat_Default = SHARED
376 or else
377 Shared_Libgnat_Default = STATIC);
378 Shared_Libgnat := (Shared_Libgnat_Default = SHARED);
379 end;
381 -- Use low level argument routines to avoid dragging in the secondary stack
383 Next_Arg := 1;
384 Scan_Args : while Next_Arg < Arg_Count loop
385 declare
386 Next_Argv : String (1 .. Len_Arg (Next_Arg));
388 begin
389 Fill_Arg (Next_Argv'Address, Next_Arg);
390 Scan_Bind_Arg (Next_Argv);
391 end;
392 Next_Arg := Next_Arg + 1;
393 end loop Scan_Args;
395 -- Test for trailing -o switch
397 if Opt.Output_File_Name_Present
398 and then not Output_File_Name_Seen
399 then
400 Fail ("output file name missing after -o");
401 end if;
403 -- Output usage if requested
405 if Usage_Requested then
406 Bindusg;
407 end if;
409 -- Check that the Ada binder file specified has extension .adb and that
410 -- the C binder file has extension .c
412 if Opt.Output_File_Name_Present
413 and then Output_File_Name_Seen
414 then
415 Check_Extensions : declare
416 Length : constant Natural := Output_File_Name'Length;
417 Last : constant Natural := Output_File_Name'Last;
419 begin
420 if Ada_Bind_File then
421 if Length <= 4
422 or else Output_File_Name (Last - 3 .. Last) /= ".adb"
423 then
424 Fail ("output file name should have .adb extension");
425 end if;
427 else
428 if Length <= 2
429 or else Output_File_Name (Last - 1 .. Last) /= ".c"
430 then
431 Fail ("output file name should have .c extension");
432 end if;
433 end if;
434 end Check_Extensions;
435 end if;
437 Osint.Add_Default_Search_Dirs;
439 -- Carry out package initializations. These are initializations which
440 -- might logically be performed at elaboration time, but Namet at
441 -- least can't be done that way (because it is used in the Compiler),
442 -- and we decide to be consistent. Like elaboration, the order in
443 -- which these calls are made is in some cases important.
445 Csets.Initialize;
446 Namet.Initialize;
448 -- Acquire target parameters
450 Targparm.Get_Target_Parameters;
452 -- Initialize Cumulative_Restrictions with the restrictions on the target
453 -- scanned from the system.ads file. Then as we read ALI files, we will
454 -- accumulate additional restrictions specified in other files.
456 Cumulative_Restrictions := Targparm.Restrictions_On_Target;
458 -- On OpenVMS, when -L is used, all external names used in pragmas Export
459 -- are in upper case. The reason is that on OpenVMS, the macro-assembler
460 -- MACASM-32, used to build Stand-Alone Libraries, only understands
461 -- uppercase.
463 if L_Switch_Seen and then OpenVMS_On_Target then
464 To_Upper (Opt.Ada_Init_Name.all);
465 To_Upper (Opt.Ada_Final_Name.all);
466 To_Upper (Opt.Ada_Main_Name.all);
467 end if;
469 -- Acquire configurable run-time mode
471 if Configurable_Run_Time_On_Target then
472 Configurable_Run_Time_Mode := True;
473 end if;
475 -- Output copyright notice if in verbose mode
477 if Verbose_Mode then
478 Write_Eol;
479 Write_Str ("GNATBIND ");
480 Write_Str (Gnat_Version_String);
481 Write_Str (" Copyright 1995-2004 Free Software Foundation, Inc.");
482 Write_Eol;
483 end if;
485 -- Output usage information if no files
487 if not More_Lib_Files then
488 Bindusg;
489 Exit_Program (E_Fatal);
490 end if;
492 -- If a mapping file was specified, initialize the file mapping
494 if Mapping_File /= null then
495 Fmap.Initialize (Mapping_File.all);
496 end if;
498 -- The block here is to catch the Unrecoverable_Error exception in the
499 -- case where we exceed the maximum number of permissible errors or some
500 -- other unrecoverable error occurs.
502 begin
503 -- Initialize binder packages
505 Initialize_Binderr;
506 Initialize_ALI;
507 Initialize_ALI_Source;
509 if Verbose_Mode then
510 Write_Eol;
511 end if;
513 -- Input ALI files
515 while More_Lib_Files loop
516 Main_Lib_File := Next_Main_Lib_File;
518 if Verbose_Mode then
519 if Check_Only then
520 Write_Str ("Checking: ");
521 else
522 Write_Str ("Binding: ");
523 end if;
525 Write_Name (Main_Lib_File);
526 Write_Eol;
527 end if;
529 Text := Read_Library_Info (Main_Lib_File, True);
531 declare
532 Id : ALI_Id;
533 pragma Warnings (Off, Id);
535 begin
536 Id := Scan_ALI
537 (F => Main_Lib_File,
538 T => Text,
539 Ignore_ED => Force_RM_Elaboration_Order,
540 Err => False,
541 Ignore_Errors => Debug_Flag_I);
542 end;
544 Free (Text);
545 end loop;
547 -- No_Run_Time mode
549 if No_Run_Time_Mode then
551 -- Set standard configuration parameters
553 Suppress_Standard_Library_On_Target := True;
554 Configurable_Run_Time_Mode := True;
555 end if;
557 -- For main ALI files, even if they are interfaces, we get their
558 -- dependencies. To be sure, we reset the Interface flag for all main
559 -- ALI files.
561 for Index in ALIs.First .. ALIs.Last loop
562 ALIs.Table (Index).Interface := False;
563 end loop;
565 -- Add System.Standard_Library to list to ensure that these files are
566 -- included in the bind, even if not directly referenced from Ada code
567 -- This is suppressed if the appropriate targparm switch is set.
569 if not Suppress_Standard_Library_On_Target then
570 Name_Buffer (1 .. 12) := "s-stalib.ali";
571 Name_Len := 12;
572 Std_Lib_File := Name_Find;
573 Text := Read_Library_Info (Std_Lib_File, True);
575 declare
576 Id : ALI_Id;
577 pragma Warnings (Off, Id);
579 begin
580 Id :=
581 Scan_ALI
582 (F => Std_Lib_File,
583 T => Text,
584 Ignore_ED => Force_RM_Elaboration_Order,
585 Err => False,
586 Ignore_Errors => Debug_Flag_I);
587 end;
589 Free (Text);
590 end if;
592 -- Acquire all information in ALI files that have been read in
594 for Index in ALIs.First .. ALIs.Last loop
595 Read_ALI (Index);
596 end loop;
598 -- Warn if -f switch used
600 if Force_RM_Elaboration_Order then
601 Error_Msg
602 ("?-f is obsolescent and should not be used");
603 Error_Msg
604 ("?may result in missing run-time elaboration checks");
605 Error_Msg
606 ("?use -gnatE, pragma Suppress (Elaboration_Checks) instead");
607 end if;
609 -- Quit if some file needs compiling
611 if No_Object_Specified then
612 raise Unrecoverable_Error;
613 end if;
615 -- Build source file table from the ALI files we have read in
617 Set_Source_Table;
619 -- Check that main library file is a suitable main program
621 if Bind_Main_Program
622 and then ALIs.Table (ALIs.First).Main_Program = None
623 and then not No_Main_Subprogram
624 then
625 Error_Msg_Name_1 := Main_Lib_File;
626 Error_Msg ("% does not contain a unit that can be a main program");
627 end if;
629 -- Perform consistency and correctness checks
631 Check_Duplicated_Subunits;
632 Check_Versions;
633 Check_Consistency;
634 Check_Configuration_Consistency;
636 -- List restrictions that could be applied to this partition
638 if List_Restrictions then
639 List_Applicable_Restrictions;
640 end if;
642 -- Complete bind if no errors
644 if Errors_Detected = 0 then
645 Find_Elab_Order;
647 if Errors_Detected = 0 then
648 if Elab_Order_Output then
649 Write_Eol;
650 Write_Str ("ELABORATION ORDER");
651 Write_Eol;
653 for J in Elab_Order.First .. Elab_Order.Last loop
654 if not Units.Table (Elab_Order.Table (J)).Interface then
655 Write_Str (" ");
656 Write_Unit_Name
657 (Units.Table (Elab_Order.Table (J)).Uname);
658 Write_Eol;
659 end if;
660 end loop;
662 Write_Eol;
663 end if;
665 if not Check_Only then
666 Gen_Output_File (Output_File_Name.all);
667 end if;
668 end if;
669 end if;
671 Total_Errors := Total_Errors + Errors_Detected;
672 Total_Warnings := Total_Warnings + Warnings_Detected;
674 exception
675 when Unrecoverable_Error =>
676 Total_Errors := Total_Errors + Errors_Detected;
677 Total_Warnings := Total_Warnings + Warnings_Detected;
678 end;
680 -- All done. Set proper exit status.
682 Finalize_Binderr;
683 Namet.Finalize;
685 if Total_Errors > 0 then
686 Exit_Program (E_Errors);
687 elsif Total_Warnings > 0 then
688 Exit_Program (E_Warnings);
689 else
690 Exit_Program (E_Success);
691 end if;
693 end Gnatbind;