2011-06-29 François Dumont <francois.cppdevs@free.fr>
[official-gcc.git] / gcc / ada / gnatbind.adb
blobde3084f02677c5e2e0a5655a7a9b5194f1744871
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-2010, 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 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 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with ALI; use ALI;
27 with ALI.Util; use ALI.Util;
28 with Bcheck; use Bcheck;
29 with Binde; use Binde;
30 with Binderr; use Binderr;
31 with Bindgen; use Bindgen;
32 with Bindusg;
33 with Butil; use Butil;
34 with Casing; use Casing;
35 with Csets;
36 with Debug; use Debug;
37 with Fmap;
38 with Fname; use Fname;
39 with Namet; use Namet;
40 with Opt; use Opt;
41 with Osint; use Osint;
42 with Osint.B; use Osint.B;
43 with Output; use Output;
44 with Rident; use Rident;
45 with Snames;
46 with Switch; use Switch;
47 with Switch.B; use Switch.B;
48 with Table;
49 with Targparm; use Targparm;
50 with Types; use Types;
52 with System.Case_Util; use System.Case_Util;
53 with System.OS_Lib; use System.OS_Lib;
55 with Ada.Command_Line.Response_File; use Ada.Command_Line;
57 procedure Gnatbind is
59 Total_Errors : Nat := 0;
60 -- Counts total errors in all files
62 Total_Warnings : Nat := 0;
63 -- Total warnings in all files
65 Main_Lib_File : File_Name_Type;
66 -- Current main library file
68 First_Main_Lib_File : File_Name_Type := No_File;
69 -- The first library file, that should be a main subprogram if neither -n
70 -- nor -z are used.
72 Std_Lib_File : File_Name_Type;
73 -- Standard library
75 Text : Text_Buffer_Ptr;
76 Next_Arg : Positive;
78 Output_File_Name_Seen : Boolean := False;
79 Output_File_Name : String_Ptr := new String'("");
81 L_Switch_Seen : Boolean := False;
83 Mapping_File : String_Ptr := null;
85 package Closure_Sources is new Table.Table
86 (Table_Component_Type => File_Name_Type,
87 Table_Index_Type => Natural,
88 Table_Low_Bound => 1,
89 Table_Initial => 10,
90 Table_Increment => 100,
91 Table_Name => "Gnatbind.Closure_Sources");
92 -- Table to record the sources in the closure, to avoid duplications. Used
93 -- only with switch -R.
95 function Gnatbind_Supports_Auto_Init return Boolean;
96 -- Indicates if automatic initialization of elaboration procedure
97 -- through the constructor mechanism is possible on the platform.
99 procedure List_Applicable_Restrictions;
100 -- List restrictions that apply to this partition if option taken
102 procedure Scan_Bind_Arg (Argv : String);
103 -- Scan and process binder specific arguments. Argv is a single argument.
104 -- All the one character arguments are still handled by Switch. This
105 -- routine handles -aO -aI and -I-. The lower bound of Argv must be 1.
107 function Is_Cross_Compiler return Boolean;
108 -- Returns True iff this is a cross-compiler
110 ---------------------------------
111 -- Gnatbind_Supports_Auto_Init --
112 ---------------------------------
114 function Gnatbind_Supports_Auto_Init return Boolean is
115 function gnat_binder_supports_auto_init return Integer;
116 pragma Import (C, gnat_binder_supports_auto_init,
117 "__gnat_binder_supports_auto_init");
118 begin
119 return gnat_binder_supports_auto_init /= 0;
120 end Gnatbind_Supports_Auto_Init;
122 -----------------------
123 -- Is_Cross_Compiler --
124 -----------------------
126 function Is_Cross_Compiler return Boolean is
127 Cross_Compiler : Integer;
128 pragma Import (C, Cross_Compiler, "__gnat_is_cross_compiler");
129 begin
130 return Cross_Compiler = 1;
131 end Is_Cross_Compiler;
133 ----------------------------------
134 -- List_Applicable_Restrictions --
135 ----------------------------------
137 procedure List_Applicable_Restrictions is
139 -- Define those restrictions that should be output if the gnatbind
140 -- -r switch is used. Not all restrictions are output for the reasons
141 -- given below in the list, and this array is used to test whether
142 -- the corresponding pragma should be listed. True means that it
143 -- should not be listed.
145 No_Restriction_List : constant array (All_Restrictions) of Boolean :=
146 (No_Allocators_After_Elaboration => True,
147 -- This involves run-time conditions not checkable at compile time
149 No_Anonymous_Allocators => True,
150 -- Premature, since we have not implemented this yet
152 No_Exception_Propagation => True,
153 -- Modifies code resulting in different exception semantics
155 No_Exceptions => True,
156 -- Has unexpected Suppress (All_Checks) effect
158 No_Implicit_Conditionals => True,
159 -- This could modify and pessimize generated code
161 No_Implicit_Dynamic_Code => True,
162 -- This could modify and pessimize generated code
164 No_Implicit_Loops => True,
165 -- This could modify and pessimize generated code
167 No_Recursion => True,
168 -- Not checkable at compile time
170 No_Reentrancy => True,
171 -- Not checkable at compile time
173 Max_Entry_Queue_Length => True,
174 -- Not checkable at compile time
176 Max_Storage_At_Blocking => True,
177 -- Not checkable at compile time
179 others => False);
181 Additional_Restrictions_Listed : Boolean := False;
182 -- Set True if we have listed header for restrictions
184 function Restriction_Could_Be_Set (R : Restriction_Id) return Boolean;
185 -- Returns True if the given restriction can be listed as an additional
186 -- restriction that could be set.
188 ------------------------------
189 -- Restriction_Could_Be_Set --
190 ------------------------------
192 function Restriction_Could_Be_Set (R : Restriction_Id) return Boolean is
193 CR : Restrictions_Info renames Cumulative_Restrictions;
195 begin
196 case R is
198 -- Boolean restriction
200 when All_Boolean_Restrictions =>
202 -- The condition for listing a boolean restriction as an
203 -- additional restriction that could be set is that it is
204 -- not violated by any unit, and not already set.
206 return CR.Violated (R) = False and then CR.Set (R) = False;
208 -- Parameter restriction
210 when All_Parameter_Restrictions =>
212 -- If the restriction is violated and the level of violation is
213 -- unknown, the restriction can definitely not be listed.
215 if CR.Violated (R) and then CR.Unknown (R) then
216 return False;
218 -- We can list the restriction if it is not set
220 elsif not CR.Set (R) then
221 return True;
223 -- We can list the restriction if is set to a greater value
224 -- than the maximum value known for the violation.
226 else
227 return CR.Value (R) > CR.Count (R);
228 end if;
230 -- No other values for R possible
232 when others =>
233 raise Program_Error;
235 end case;
236 end Restriction_Could_Be_Set;
238 -- Start of processing for List_Applicable_Restrictions
240 begin
241 -- Loop through restrictions
243 for R in All_Restrictions loop
244 if not No_Restriction_List (R)
245 and then Restriction_Could_Be_Set (R)
246 then
247 if not Additional_Restrictions_Listed then
248 Write_Eol;
249 Write_Line
250 ("The following additional restrictions may be" &
251 " applied to this partition:");
252 Additional_Restrictions_Listed := True;
253 end if;
255 Write_Str ("pragma Restrictions (");
257 declare
258 S : constant String := Restriction_Id'Image (R);
259 begin
260 Name_Len := S'Length;
261 Name_Buffer (1 .. Name_Len) := S;
262 end;
264 Set_Casing (Mixed_Case);
265 Write_Str (Name_Buffer (1 .. Name_Len));
267 if R in All_Parameter_Restrictions then
268 Write_Str (" => ");
269 Write_Int (Int (Cumulative_Restrictions.Count (R)));
270 end if;
272 Write_Str (");");
273 Write_Eol;
274 end if;
275 end loop;
276 end List_Applicable_Restrictions;
278 -------------------
279 -- Scan_Bind_Arg --
280 -------------------
282 procedure Scan_Bind_Arg (Argv : String) is
283 pragma Assert (Argv'First = 1);
285 begin
286 -- Now scan arguments that are specific to the binder and are not
287 -- handled by the common circuitry in Switch.
289 if Opt.Output_File_Name_Present
290 and then not Output_File_Name_Seen
291 then
292 Output_File_Name_Seen := True;
294 if Argv'Length = 0
295 or else (Argv'Length >= 1 and then Argv (1) = '-')
296 then
297 Fail ("output File_Name missing after -o");
299 else
300 Output_File_Name := new String'(Argv);
301 end if;
303 elsif Argv'Length >= 2 and then Argv (1) = '-' then
305 -- -I-
307 if Argv (2 .. Argv'Last) = "I-" then
308 Opt.Look_In_Primary_Dir := False;
310 -- -Idir
312 elsif Argv (2) = 'I' then
313 Add_Src_Search_Dir (Argv (3 .. Argv'Last));
314 Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
316 -- -Ldir
318 elsif Argv (2) = 'L' then
319 if Argv'Length >= 3 then
321 -- Remember that the -L switch was specified, so that if this
322 -- is on OpenVMS, the export names are put in uppercase.
323 -- This is not known before the target parameters are read.
325 L_Switch_Seen := True;
327 Opt.Bind_For_Library := True;
328 Opt.Ada_Init_Name :=
329 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Init_Suffix);
330 Opt.Ada_Final_Name :=
331 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Final_Suffix);
332 Opt.Ada_Main_Name :=
333 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Main_Name_Suffix);
335 -- This option (-Lxxx) implies -n
337 Opt.Bind_Main_Program := False;
339 else
340 Fail
341 ("Prefix of initialization and finalization " &
342 "procedure names missing in -L");
343 end if;
345 -- -Sin -Slo -Shi -Sxx -Sev
347 elsif Argv'Length = 4
348 and then Argv (2) = 'S'
349 then
350 declare
351 C1 : Character := Argv (3);
352 C2 : Character := Argv (4);
354 begin
355 -- Fold to upper case
357 if C1 in 'a' .. 'z' then
358 C1 := Character'Val (Character'Pos (C1) - 32);
359 end if;
361 if C2 in 'a' .. 'z' then
362 C2 := Character'Val (Character'Pos (C2) - 32);
363 end if;
365 -- Test valid option and set mode accordingly
367 if C1 = 'E' and then C2 = 'V' then
368 null;
370 elsif C1 = 'I' and then C2 = 'N' then
371 null;
373 elsif C1 = 'L' and then C2 = 'O' then
374 null;
376 elsif C1 = 'H' and then C2 = 'I' then
377 null;
379 elsif (C1 in '0' .. '9' or else C1 in 'A' .. 'F')
380 and then
381 (C2 in '0' .. '9' or else C2 in 'A' .. 'F')
382 then
383 null;
385 -- Invalid -S switch, let Switch give error, set default of IN
387 else
388 Scan_Binder_Switches (Argv);
389 C1 := 'I';
390 C2 := 'N';
391 end if;
393 Initialize_Scalars_Mode1 := C1;
394 Initialize_Scalars_Mode2 := C2;
395 end;
397 -- -aIdir
399 elsif Argv'Length >= 3
400 and then Argv (2 .. 3) = "aI"
401 then
402 Add_Src_Search_Dir (Argv (4 .. Argv'Last));
404 -- -aOdir
406 elsif Argv'Length >= 3
407 and then Argv (2 .. 3) = "aO"
408 then
409 Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
411 -- -nostdlib
413 elsif Argv (2 .. Argv'Last) = "nostdlib" then
414 Opt.No_Stdlib := True;
416 -- -nostdinc
418 elsif Argv (2 .. Argv'Last) = "nostdinc" then
419 Opt.No_Stdinc := True;
421 -- -static
423 elsif Argv (2 .. Argv'Last) = "static" then
424 Opt.Shared_Libgnat := False;
426 -- -shared
428 elsif Argv (2 .. Argv'Last) = "shared" then
429 Opt.Shared_Libgnat := True;
431 -- -F=mapping_file
433 elsif Argv'Length >= 4 and then Argv (2 .. 3) = "F=" then
434 if Mapping_File /= null then
435 Fail ("cannot specify several mapping files");
436 end if;
438 Mapping_File := new String'(Argv (4 .. Argv'Last));
440 -- -Mname
442 elsif Argv'Length >= 3 and then Argv (2) = 'M' then
443 if not Is_Cross_Compiler then
444 Write_Line
445 ("gnatbind: -M not expected to be used on native platforms");
446 end if;
448 Opt.Bind_Alternate_Main_Name := True;
449 Opt.Alternate_Main_Name := new String'(Argv (3 .. Argv'Last));
451 -- All other options are single character and are handled by
452 -- Scan_Binder_Switches.
454 else
455 Scan_Binder_Switches (Argv);
456 end if;
458 -- Not a switch, so must be a file name (if non-empty)
460 elsif Argv'Length /= 0 then
461 if Argv'Length > 4
462 and then Argv (Argv'Last - 3 .. Argv'Last) = ".ali"
463 then
464 Add_File (Argv);
465 else
466 Add_File (Argv & ".ali");
467 end if;
468 end if;
469 end Scan_Bind_Arg;
471 procedure Check_Version_And_Help is
472 new Check_Version_And_Help_G (Bindusg.Display);
474 -- Start of processing for Gnatbind
476 begin
478 -- Set default for Shared_Libgnat option
480 declare
481 Shared_Libgnat_Default : Character;
482 pragma Import
483 (C, Shared_Libgnat_Default, "__gnat_shared_libgnat_default");
485 SHARED : constant Character := 'H';
486 STATIC : constant Character := 'T';
488 begin
489 pragma Assert
490 (Shared_Libgnat_Default = SHARED
491 or else
492 Shared_Libgnat_Default = STATIC);
493 Shared_Libgnat := (Shared_Libgnat_Default = SHARED);
494 end;
496 -- Scan the switches and arguments
498 -- First, scan to detect --version and/or --help
500 Check_Version_And_Help ("GNATBIND", "1995");
502 -- Use low level argument routines to avoid dragging in the secondary stack
504 Next_Arg := 1;
505 Scan_Args : while Next_Arg < Arg_Count loop
506 declare
507 Next_Argv : String (1 .. Len_Arg (Next_Arg));
508 begin
509 Fill_Arg (Next_Argv'Address, Next_Arg);
511 if Next_Argv'Length > 0 then
512 if Next_Argv (1) = '@' then
513 if Next_Argv'Length > 1 then
514 declare
515 Arguments : constant Argument_List :=
516 Response_File.Arguments_From
517 (Response_File_Name =>
518 Next_Argv (2 .. Next_Argv'Last),
519 Recursive => True,
520 Ignore_Non_Existing_Files => True);
521 begin
522 for J in Arguments'Range loop
523 Scan_Bind_Arg (Arguments (J).all);
524 end loop;
525 end;
526 end if;
528 else
529 Scan_Bind_Arg (Next_Argv);
530 end if;
531 end if;
532 end;
534 Next_Arg := Next_Arg + 1;
535 end loop Scan_Args;
537 if Use_Pragma_Linker_Constructor then
538 if Bind_Main_Program then
539 Fail ("switch -a must be used in conjunction with -n or -Lxxx");
541 elsif not Gnatbind_Supports_Auto_Init then
542 Fail ("automatic initialisation of elaboration " &
543 "not supported on this platform");
544 end if;
545 end if;
547 -- Test for trailing -o switch
549 if Opt.Output_File_Name_Present
550 and then not Output_File_Name_Seen
551 then
552 Fail ("output file name missing after -o");
553 end if;
555 -- Output usage if requested
557 if Usage_Requested then
558 Bindusg.Display;
559 end if;
561 -- Check that the Ada binder file specified has extension .adb and that
562 -- the C binder file has extension .c
564 if Opt.Output_File_Name_Present
565 and then Output_File_Name_Seen
566 then
567 Check_Extensions : declare
568 Length : constant Natural := Output_File_Name'Length;
569 Last : constant Natural := Output_File_Name'Last;
571 begin
572 if Ada_Bind_File then
573 if Length <= 4
574 or else Output_File_Name (Last - 3 .. Last) /= ".adb"
575 then
576 Fail ("output file name should have .adb extension");
577 end if;
579 else
580 if Length <= 2
581 or else Output_File_Name (Last - 1 .. Last) /= ".c"
582 then
583 Fail ("output file name should have .c extension");
584 end if;
585 end if;
586 end Check_Extensions;
587 end if;
589 Osint.Add_Default_Search_Dirs;
591 -- Carry out package initializations. These are initializations which
592 -- might logically be performed at elaboration time, and we decide to be
593 -- consistent. Like elaboration, the order in which these calls are made
594 -- is in some cases important.
596 Csets.Initialize;
597 Snames.Initialize;
599 -- Acquire target parameters
601 Targparm.Get_Target_Parameters;
603 -- Initialize Cumulative_Restrictions with the restrictions on the target
604 -- scanned from the system.ads file. Then as we read ALI files, we will
605 -- accumulate additional restrictions specified in other files.
607 Cumulative_Restrictions := Targparm.Restrictions_On_Target;
609 -- On OpenVMS, when -L is used, all external names used in pragmas Export
610 -- are in upper case. The reason is that on OpenVMS, the macro-assembler
611 -- MACASM-32, used to build Stand-Alone Libraries, only understands
612 -- uppercase.
614 if L_Switch_Seen and then OpenVMS_On_Target then
615 To_Upper (Opt.Ada_Init_Name.all);
616 To_Upper (Opt.Ada_Final_Name.all);
617 To_Upper (Opt.Ada_Main_Name.all);
618 end if;
620 -- Acquire configurable run-time mode
622 if Configurable_Run_Time_On_Target then
623 Configurable_Run_Time_Mode := True;
624 end if;
626 -- Output copyright notice if in verbose mode
628 if Verbose_Mode then
629 Write_Eol;
630 Display_Version ("GNATBIND", "1995");
631 end if;
633 -- Output usage information if no files
635 if not More_Lib_Files then
636 Bindusg.Display;
637 Exit_Program (E_Fatal);
638 end if;
640 -- If a mapping file was specified, initialize the file mapping
642 if Mapping_File /= null then
643 Fmap.Initialize (Mapping_File.all);
644 end if;
646 -- The block here is to catch the Unrecoverable_Error exception in the
647 -- case where we exceed the maximum number of permissible errors or some
648 -- other unrecoverable error occurs.
650 begin
651 -- Initialize binder packages
653 Initialize_Binderr;
654 Initialize_ALI;
655 Initialize_ALI_Source;
657 if Verbose_Mode then
658 Write_Eol;
659 end if;
661 -- Input ALI files
663 while More_Lib_Files loop
664 Main_Lib_File := Next_Main_Lib_File;
666 if First_Main_Lib_File = No_File then
667 First_Main_Lib_File := Main_Lib_File;
668 end if;
670 if Verbose_Mode then
671 if Check_Only then
672 Write_Str ("Checking: ");
673 else
674 Write_Str ("Binding: ");
675 end if;
677 Write_Name (Main_Lib_File);
678 Write_Eol;
679 end if;
681 Text := Read_Library_Info (Main_Lib_File, True);
683 declare
684 Id : ALI_Id;
685 pragma Warnings (Off, Id);
687 begin
688 Id := Scan_ALI
689 (F => Main_Lib_File,
690 T => Text,
691 Ignore_ED => False,
692 Err => False,
693 Ignore_Errors => Debug_Flag_I,
694 Directly_Scanned => True);
695 end;
697 Free (Text);
698 end loop;
700 -- No_Run_Time mode
702 if No_Run_Time_Mode then
704 -- Set standard configuration parameters
706 Suppress_Standard_Library_On_Target := True;
707 Configurable_Run_Time_Mode := True;
708 end if;
710 -- For main ALI files, even if they are interfaces, we get their
711 -- dependencies. To be sure, we reset the Interface flag for all main
712 -- ALI files.
714 for Index in ALIs.First .. ALIs.Last loop
715 ALIs.Table (Index).SAL_Interface := False;
716 end loop;
718 -- Add System.Standard_Library to list to ensure that these files are
719 -- included in the bind, even if not directly referenced from Ada code
720 -- This is suppressed if the appropriate targparm switch is set.
722 if not Suppress_Standard_Library_On_Target then
723 Name_Buffer (1 .. 12) := "s-stalib.ali";
724 Name_Len := 12;
725 Std_Lib_File := Name_Find;
726 Text := Read_Library_Info (Std_Lib_File, True);
728 declare
729 Id : ALI_Id;
730 pragma Warnings (Off, Id);
732 begin
733 Id :=
734 Scan_ALI
735 (F => Std_Lib_File,
736 T => Text,
737 Ignore_ED => False,
738 Err => False,
739 Ignore_Errors => Debug_Flag_I);
740 end;
742 Free (Text);
743 end if;
745 -- Load ALIs for all dependent units
747 for Index in ALIs.First .. ALIs.Last loop
748 Read_Withed_ALIs (Index);
749 end loop;
751 -- Quit if some file needs compiling
753 if No_Object_Specified then
754 raise Unrecoverable_Error;
755 end if;
757 -- Output list of ALI files in closure
759 if Output_ALI_List then
760 if ALI_List_Filename /= null then
761 Set_List_File (ALI_List_Filename.all);
762 end if;
764 for Index in ALIs.First .. ALIs.Last loop
765 declare
766 Full_Afile : constant File_Name_Type :=
767 Find_File (ALIs.Table (Index).Afile, Library);
768 begin
769 Write_Name (Full_Afile);
770 Write_Eol;
771 end;
772 end loop;
774 if ALI_List_Filename /= null then
775 Close_List_File;
776 end if;
777 end if;
779 -- Build source file table from the ALI files we have read in
781 Set_Source_Table;
783 -- If there is main program to bind, set Main_Lib_File to the first
784 -- library file, and the name from which to derive the binder generate
785 -- file to the first ALI file.
787 if Bind_Main_Program then
788 Main_Lib_File := First_Main_Lib_File;
789 Set_Current_File_Name_Index (To => 1);
790 end if;
792 -- Check that main library file is a suitable main program
794 if Bind_Main_Program
795 and then ALIs.Table (ALIs.First).Main_Program = None
796 and then not No_Main_Subprogram
797 then
798 Get_Name_String
799 (Units.Table (ALIs.Table (ALIs.First).First_Unit).Uname);
801 declare
802 Unit_Name : String := Name_Buffer (1 .. Name_Len - 2);
803 begin
804 To_Mixed (Unit_Name);
805 Get_Name_String (ALIs.Table (ALIs.First).Sfile);
806 Add_Str_To_Name_Buffer (":1: ");
807 Add_Str_To_Name_Buffer (Unit_Name);
808 Add_Str_To_Name_Buffer (" cannot be used as a main program");
809 Write_Line (Name_Buffer (1 .. Name_Len));
810 Errors_Detected := Errors_Detected + 1;
811 end;
812 end if;
814 -- Perform consistency and correctness checks
816 Check_Duplicated_Subunits;
817 Check_Versions;
818 Check_Consistency;
819 Check_Configuration_Consistency;
821 -- List restrictions that could be applied to this partition
823 if List_Restrictions then
824 List_Applicable_Restrictions;
825 end if;
827 -- Complete bind if no errors
829 if Errors_Detected = 0 then
830 Find_Elab_Order;
832 if Errors_Detected = 0 then
833 -- Display elaboration order if -l was specified
835 if Elab_Order_Output then
836 if not Zero_Formatting then
837 Write_Eol;
838 Write_Str ("ELABORATION ORDER");
839 Write_Eol;
840 end if;
842 for J in Elab_Order.First .. Elab_Order.Last loop
843 if not Units.Table (Elab_Order.Table (J)).SAL_Interface then
844 if not Zero_Formatting then
845 Write_Str (" ");
846 end if;
848 Write_Unit_Name
849 (Units.Table (Elab_Order.Table (J)).Uname);
850 Write_Eol;
851 end if;
852 end loop;
854 if not Zero_Formatting then
855 Write_Eol;
856 end if;
857 end if;
859 if not Check_Only then
860 Gen_Output_File (Output_File_Name.all);
861 end if;
863 -- Display list of sources in the closure (except predefined
864 -- sources) if -R was used.
866 if List_Closure then
867 List_Closure_Display : declare
868 Source : File_Name_Type;
870 function Put_In_Sources (S : File_Name_Type) return Boolean;
871 -- Check if S is already in table Sources and put in Sources
872 -- if it is not. Return False if the source is already in
873 -- Sources, and True if it is added.
875 --------------------
876 -- Put_In_Sources --
877 --------------------
879 function Put_In_Sources (S : File_Name_Type)
880 return Boolean
882 begin
883 for J in 1 .. Closure_Sources.Last loop
884 if Closure_Sources.Table (J) = S then
885 return False;
886 end if;
887 end loop;
889 Closure_Sources.Append (S);
890 return True;
891 end Put_In_Sources;
893 -- Start of processing for List_Closure_Display
895 begin
896 Closure_Sources.Init;
898 if not Zero_Formatting then
899 Write_Eol;
900 Write_Str ("REFERENCED SOURCES");
901 Write_Eol;
902 end if;
904 for J in reverse Elab_Order.First .. Elab_Order.Last loop
905 Source := Units.Table (Elab_Order.Table (J)).Sfile;
907 -- Do not include the sources of the runtime and do not
908 -- include the same source several times.
910 if Put_In_Sources (Source)
911 and then not Is_Internal_File_Name (Source)
912 then
913 if not Zero_Formatting then
914 Write_Str (" ");
915 end if;
917 Write_Str (Get_Name_String (Source));
918 Write_Eol;
919 end if;
920 end loop;
922 -- Subunits do not appear in the elaboration table because
923 -- they are subsumed by their parent units, but we need to
924 -- list them for other tools. For now they are listed after
925 -- other files, rather than right after their parent, since
926 -- there is no easy link between the elaboration table and
927 -- the ALIs table ??? As subunits may appear repeatedly in
928 -- the list, if the parent unit appears in the context of
929 -- several units in the closure, duplicates are suppressed.
931 for J in Sdep.First .. Sdep.Last loop
932 Source := Sdep.Table (J).Sfile;
934 if Sdep.Table (J).Subunit_Name /= No_Name
935 and then Put_In_Sources (Source)
936 and then not Is_Internal_File_Name (Source)
937 then
938 if not Zero_Formatting then
939 Write_Str (" ");
940 end if;
942 Write_Str (Get_Name_String (Source));
943 Write_Eol;
944 end if;
945 end loop;
947 if not Zero_Formatting then
948 Write_Eol;
949 end if;
950 end List_Closure_Display;
951 end if;
952 end if;
953 end if;
955 Total_Errors := Total_Errors + Errors_Detected;
956 Total_Warnings := Total_Warnings + Warnings_Detected;
958 exception
959 when Unrecoverable_Error =>
960 Total_Errors := Total_Errors + Errors_Detected;
961 Total_Warnings := Total_Warnings + Warnings_Detected;
962 end;
964 -- All done. Set proper exit status
966 Finalize_Binderr;
967 Namet.Finalize;
969 if Total_Errors > 0 then
970 Exit_Program (E_Errors);
972 elsif Total_Warnings > 0 then
973 Exit_Program (E_Warnings);
975 else
976 -- Do not call Exit_Program (E_Success), so that finalization occurs
977 -- normally.
979 null;
980 end if;
982 end Gnatbind;