[multiple changes]
[gcc.git] / gcc / ada / gnatbind.adb
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-2014, 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 ------------------------------------------------------------------------------
25
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;
51
52 with System.Case_Util; use System.Case_Util;
53 with System.OS_Lib; use System.OS_Lib;
54
55 with Ada.Command_Line.Response_File; use Ada.Command_Line;
56
57 procedure Gnatbind is
58
59 Total_Errors : Nat := 0;
60 -- Counts total errors in all files
61
62 Total_Warnings : Nat := 0;
63 -- Total warnings in all files
64
65 Main_Lib_File : File_Name_Type;
66 -- Current main library file
67
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.
71
72 Std_Lib_File : File_Name_Type;
73 -- Standard library
74
75 Text : Text_Buffer_Ptr;
76
77 Output_File_Name_Seen : Boolean := False;
78 Output_File_Name : String_Ptr := new String'("");
79
80 L_Switch_Seen : Boolean := False;
81
82 Mapping_File : String_Ptr := null;
83
84 package Closure_Sources is new Table.Table
85 (Table_Component_Type => File_Name_Type,
86 Table_Index_Type => Natural,
87 Table_Low_Bound => 1,
88 Table_Initial => 10,
89 Table_Increment => 100,
90 Table_Name => "Gnatbind.Closure_Sources");
91 -- Table to record the sources in the closure, to avoid duplications. Used
92 -- only with switch -R.
93
94 function Gnatbind_Supports_Auto_Init return Boolean;
95 -- Indicates if automatic initialization of elaboration procedure
96 -- through the constructor mechanism is possible on the platform.
97
98 procedure List_Applicable_Restrictions;
99 -- List restrictions that apply to this partition if option taken
100
101 procedure Scan_Bind_Arg (Argv : String);
102 -- Scan and process binder specific arguments. Argv is a single argument.
103 -- All the one character arguments are still handled by Switch. This
104 -- routine handles -aO -aI and -I-. The lower bound of Argv must be 1.
105
106 generic
107 with procedure Action (Argv : String);
108 procedure Generic_Scan_Bind_Args;
109 -- Iterate through the args calling Action on each one, taking care of
110 -- response files.
111
112 procedure Write_Arg (S : String);
113 -- Passed to Generic_Scan_Bind_Args to print args
114
115 function Is_Cross_Compiler return Boolean;
116 -- Returns True iff this is a cross-compiler
117
118 ---------------------------------
119 -- Gnatbind_Supports_Auto_Init --
120 ---------------------------------
121
122 function Gnatbind_Supports_Auto_Init return Boolean is
123 function gnat_binder_supports_auto_init return Integer;
124 pragma Import (C, gnat_binder_supports_auto_init,
125 "__gnat_binder_supports_auto_init");
126 begin
127 return gnat_binder_supports_auto_init /= 0;
128 end Gnatbind_Supports_Auto_Init;
129
130 -----------------------
131 -- Is_Cross_Compiler --
132 -----------------------
133
134 function Is_Cross_Compiler return Boolean is
135 Cross_Compiler : Integer;
136 pragma Import (C, Cross_Compiler, "__gnat_is_cross_compiler");
137 begin
138 return Cross_Compiler = 1;
139 end Is_Cross_Compiler;
140
141 ----------------------------------
142 -- List_Applicable_Restrictions --
143 ----------------------------------
144
145 procedure List_Applicable_Restrictions is
146
147 -- Define those restrictions that should be output if the gnatbind
148 -- -r switch is used. Not all restrictions are output for the reasons
149 -- given below in the list, and this array is used to test whether
150 -- the corresponding pragma should be listed. True means that it
151 -- should not be listed.
152
153 No_Restriction_List : constant array (All_Restrictions) of Boolean :=
154 (No_Standard_Allocators_After_Elaboration => True,
155 -- This involves run-time conditions not checkable at compile time
156
157 No_Anonymous_Allocators => True,
158 -- Premature, since we have not implemented this yet
159
160 No_Exception_Propagation => True,
161 -- Modifies code resulting in different exception semantics
162
163 No_Exceptions => True,
164 -- Has unexpected Suppress (All_Checks) effect
165
166 No_Implicit_Conditionals => True,
167 -- This could modify and pessimize generated code
168
169 No_Implicit_Dynamic_Code => True,
170 -- This could modify and pessimize generated code
171
172 No_Implicit_Loops => True,
173 -- This could modify and pessimize generated code
174
175 No_Recursion => True,
176 -- Not checkable at compile time
177
178 No_Reentrancy => True,
179 -- Not checkable at compile time
180
181 Max_Entry_Queue_Length => True,
182 -- Not checkable at compile time
183
184 Max_Storage_At_Blocking => True,
185 -- Not checkable at compile time
186
187 -- The following three should not be partition-wide, so the
188 -- following tests are junk to be removed eventually ???
189
190 No_Specification_Of_Aspect => True,
191 -- Requires a parameter value, not a count
192
193 No_Use_Of_Attribute => True,
194 -- Requires a parameter value, not a count
195
196 No_Use_Of_Pragma => True,
197 -- Requires a parameter value, not a count
198
199 others => False);
200
201 Additional_Restrictions_Listed : Boolean := False;
202 -- Set True if we have listed header for restrictions
203
204 function Restriction_Could_Be_Set (R : Restriction_Id) return Boolean;
205 -- Returns True if the given restriction can be listed as an additional
206 -- restriction that could be set.
207
208 ------------------------------
209 -- Restriction_Could_Be_Set --
210 ------------------------------
211
212 function Restriction_Could_Be_Set (R : Restriction_Id) return Boolean is
213 CR : Restrictions_Info renames Cumulative_Restrictions;
214
215 begin
216 case R is
217
218 -- Boolean restriction
219
220 when All_Boolean_Restrictions =>
221
222 -- The condition for listing a boolean restriction as an
223 -- additional restriction that could be set is that it is
224 -- not violated by any unit, and not already set.
225
226 return CR.Violated (R) = False and then CR.Set (R) = False;
227
228 -- Parameter restriction
229
230 when All_Parameter_Restrictions =>
231
232 -- If the restriction is violated and the level of violation is
233 -- unknown, the restriction can definitely not be listed.
234
235 if CR.Violated (R) and then CR.Unknown (R) then
236 return False;
237
238 -- We can list the restriction if it is not set
239
240 elsif not CR.Set (R) then
241 return True;
242
243 -- We can list the restriction if is set to a greater value
244 -- than the maximum value known for the violation.
245
246 else
247 return CR.Value (R) > CR.Count (R);
248 end if;
249
250 -- No other values for R possible
251
252 when others =>
253 raise Program_Error;
254
255 end case;
256 end Restriction_Could_Be_Set;
257
258 -- Start of processing for List_Applicable_Restrictions
259
260 begin
261 -- Loop through restrictions
262
263 for R in All_Restrictions loop
264 if not No_Restriction_List (R)
265 and then Restriction_Could_Be_Set (R)
266 then
267 if not Additional_Restrictions_Listed then
268 Write_Eol;
269 Write_Line
270 ("The following additional restrictions may be" &
271 " applied to this partition:");
272 Additional_Restrictions_Listed := True;
273 end if;
274
275 Write_Str ("pragma Restrictions (");
276
277 declare
278 S : constant String := Restriction_Id'Image (R);
279 begin
280 Name_Len := S'Length;
281 Name_Buffer (1 .. Name_Len) := S;
282 end;
283
284 Set_Casing (Mixed_Case);
285 Write_Str (Name_Buffer (1 .. Name_Len));
286
287 if R in All_Parameter_Restrictions then
288 Write_Str (" => ");
289 Write_Int (Int (Cumulative_Restrictions.Count (R)));
290 end if;
291
292 Write_Str (");");
293 Write_Eol;
294 end if;
295 end loop;
296 end List_Applicable_Restrictions;
297
298 -------------------
299 -- Scan_Bind_Arg --
300 -------------------
301
302 procedure Scan_Bind_Arg (Argv : String) is
303 pragma Assert (Argv'First = 1);
304
305 begin
306 -- Now scan arguments that are specific to the binder and are not
307 -- handled by the common circuitry in Switch.
308
309 if Opt.Output_File_Name_Present
310 and then not Output_File_Name_Seen
311 then
312 Output_File_Name_Seen := True;
313
314 if Argv'Length = 0
315 or else (Argv'Length >= 1 and then Argv (1) = '-')
316 then
317 Fail ("output File_Name missing after -o");
318
319 else
320 Output_File_Name := new String'(Argv);
321 end if;
322
323 elsif Argv'Length >= 2 and then Argv (1) = '-' then
324
325 -- -I-
326
327 if Argv (2 .. Argv'Last) = "I-" then
328 Opt.Look_In_Primary_Dir := False;
329
330 -- -Idir
331
332 elsif Argv (2) = 'I' then
333 Add_Src_Search_Dir (Argv (3 .. Argv'Last));
334 Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
335
336 -- -Ldir
337
338 elsif Argv (2) = 'L' then
339 if Argv'Length >= 3 then
340
341 -- Remember that the -L switch was specified, so that if this
342 -- is on OpenVMS, the export names are put in uppercase.
343 -- This is not known before the target parameters are read.
344
345 L_Switch_Seen := True;
346
347 Opt.Bind_For_Library := True;
348 Opt.Ada_Init_Name :=
349 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Init_Suffix);
350 Opt.Ada_Final_Name :=
351 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Final_Suffix);
352 Opt.Ada_Main_Name :=
353 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Main_Name_Suffix);
354
355 -- This option (-Lxxx) implies -n
356
357 Opt.Bind_Main_Program := False;
358
359 else
360 Fail
361 ("Prefix of initialization and finalization " &
362 "procedure names missing in -L");
363 end if;
364
365 -- -Sin -Slo -Shi -Sxx -Sev
366
367 elsif Argv'Length = 4
368 and then Argv (2) = 'S'
369 then
370 declare
371 C1 : Character := Argv (3);
372 C2 : Character := Argv (4);
373
374 begin
375 -- Fold to upper case
376
377 if C1 in 'a' .. 'z' then
378 C1 := Character'Val (Character'Pos (C1) - 32);
379 end if;
380
381 if C2 in 'a' .. 'z' then
382 C2 := Character'Val (Character'Pos (C2) - 32);
383 end if;
384
385 -- Test valid option and set mode accordingly
386
387 if C1 = 'E' and then C2 = 'V' then
388 null;
389
390 elsif C1 = 'I' and then C2 = 'N' then
391 null;
392
393 elsif C1 = 'L' and then C2 = 'O' then
394 null;
395
396 elsif C1 = 'H' and then C2 = 'I' then
397 null;
398
399 elsif (C1 in '0' .. '9' or else C1 in 'A' .. 'F')
400 and then
401 (C2 in '0' .. '9' or else C2 in 'A' .. 'F')
402 then
403 null;
404
405 -- Invalid -S switch, let Switch give error, set default of IN
406
407 else
408 Scan_Binder_Switches (Argv);
409 C1 := 'I';
410 C2 := 'N';
411 end if;
412
413 Initialize_Scalars_Mode1 := C1;
414 Initialize_Scalars_Mode2 := C2;
415 end;
416
417 -- -aIdir
418
419 elsif Argv'Length >= 3
420 and then Argv (2 .. 3) = "aI"
421 then
422 Add_Src_Search_Dir (Argv (4 .. Argv'Last));
423
424 -- -aOdir
425
426 elsif Argv'Length >= 3
427 and then Argv (2 .. 3) = "aO"
428 then
429 Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
430
431 -- -nostdlib
432
433 elsif Argv (2 .. Argv'Last) = "nostdlib" then
434 Opt.No_Stdlib := True;
435
436 -- -nostdinc
437
438 elsif Argv (2 .. Argv'Last) = "nostdinc" then
439 Opt.No_Stdinc := True;
440
441 -- -static
442
443 elsif Argv (2 .. Argv'Last) = "static" then
444 Opt.Shared_Libgnat := False;
445
446 -- -shared
447
448 elsif Argv (2 .. Argv'Last) = "shared" then
449 Opt.Shared_Libgnat := True;
450
451 -- -F=mapping_file
452
453 elsif Argv'Length >= 4 and then Argv (2 .. 3) = "F=" then
454 if Mapping_File /= null then
455 Fail ("cannot specify several mapping files");
456 end if;
457
458 Mapping_File := new String'(Argv (4 .. Argv'Last));
459
460 -- -Mname
461
462 elsif Argv'Length >= 3 and then Argv (2) = 'M' then
463 if not Is_Cross_Compiler then
464 Write_Line
465 ("gnatbind: -M not expected to be used on native platforms");
466 end if;
467
468 Opt.Bind_Alternate_Main_Name := True;
469 Opt.Alternate_Main_Name := new String'(Argv (3 .. Argv'Last));
470
471 -- All other options are single character and are handled by
472 -- Scan_Binder_Switches.
473
474 else
475 Scan_Binder_Switches (Argv);
476 end if;
477
478 -- Not a switch, so must be a file name (if non-empty)
479
480 elsif Argv'Length /= 0 then
481 if Argv'Length > 4
482 and then Argv (Argv'Last - 3 .. Argv'Last) = ".ali"
483 then
484 Add_File (Argv);
485 else
486 Add_File (Argv & ".ali");
487 end if;
488 end if;
489 end Scan_Bind_Arg;
490
491 ----------------------------
492 -- Generic_Scan_Bind_Args --
493 ----------------------------
494
495 procedure Generic_Scan_Bind_Args is
496 Next_Arg : Positive := 1;
497
498 begin
499 -- Use low level argument routines to avoid dragging in secondary stack
500
501 while Next_Arg < Arg_Count loop
502 declare
503 Next_Argv : String (1 .. Len_Arg (Next_Arg));
504
505 begin
506 Fill_Arg (Next_Argv'Address, Next_Arg);
507
508 if Next_Argv'Length > 0 then
509 if Next_Argv (1) = '@' then
510 if Next_Argv'Length > 1 then
511 declare
512 Arguments : constant Argument_List :=
513 Response_File.Arguments_From
514 (Response_File_Name =>
515 Next_Argv (2 .. Next_Argv'Last),
516 Recursive => True,
517 Ignore_Non_Existing_Files => True);
518 begin
519 for J in Arguments'Range loop
520 Action (Arguments (J).all);
521 end loop;
522 end;
523 end if;
524
525 else
526 Action (Next_Argv);
527 end if;
528 end if;
529 end;
530
531 Next_Arg := Next_Arg + 1;
532 end loop;
533 end Generic_Scan_Bind_Args;
534
535 ---------------
536 -- Write_Arg --
537 ---------------
538
539 procedure Write_Arg (S : String) is
540 begin
541 Write_Str (" " & S);
542 end Write_Arg;
543
544 procedure Scan_Bind_Args is new Generic_Scan_Bind_Args (Scan_Bind_Arg);
545 procedure Put_Bind_Args is new Generic_Scan_Bind_Args (Write_Arg);
546
547 procedure Check_Version_And_Help is
548 new Check_Version_And_Help_G (Bindusg.Display);
549
550 -- Start of processing for Gnatbind
551
552 begin
553 -- Set default for Shared_Libgnat option
554
555 declare
556 Shared_Libgnat_Default : Character;
557 pragma Import
558 (C, Shared_Libgnat_Default, "__gnat_shared_libgnat_default");
559
560 SHARED : constant Character := 'H';
561 STATIC : constant Character := 'T';
562
563 begin
564 pragma Assert
565 (Shared_Libgnat_Default = SHARED
566 or else
567 Shared_Libgnat_Default = STATIC);
568 Shared_Libgnat := (Shared_Libgnat_Default = SHARED);
569 end;
570
571 -- Scan the switches and arguments
572
573 -- First, scan to detect --version and/or --help
574
575 Check_Version_And_Help ("GNATBIND", "1992");
576
577 -- We need to Scan_Bind_Args first, to set Verbose_Mode, so we know whether
578 -- to Put_Bind_Args.
579
580 Scan_Bind_Args;
581
582 if Verbose_Mode then
583 Write_Str (Command_Name);
584 Put_Bind_Args;
585 Write_Eol;
586 end if;
587
588 if Use_Pragma_Linker_Constructor then
589 if Bind_Main_Program then
590 Fail ("switch -a must be used in conjunction with -n or -Lxxx");
591
592 elsif not Gnatbind_Supports_Auto_Init then
593 Fail ("automatic initialisation of elaboration " &
594 "not supported on this platform");
595 end if;
596 end if;
597
598 -- Test for trailing -o switch
599
600 if Opt.Output_File_Name_Present and then not Output_File_Name_Seen then
601 Fail ("output file name missing after -o");
602 end if;
603
604 -- Output usage if requested
605
606 if Usage_Requested then
607 Bindusg.Display;
608 end if;
609
610 -- Check that the binder file specified has extension .adb
611
612 if Opt.Output_File_Name_Present and then Output_File_Name_Seen then
613 Check_Extensions : declare
614 Length : constant Natural := Output_File_Name'Length;
615 Last : constant Natural := Output_File_Name'Last;
616 begin
617 if Length <= 4
618 or else Output_File_Name (Last - 3 .. Last) /= ".adb"
619 then
620 Fail ("output file name should have .adb extension");
621 end if;
622 end Check_Extensions;
623 end if;
624
625 Osint.Add_Default_Search_Dirs;
626
627 -- Carry out package initializations. These are initializations which
628 -- might logically be performed at elaboration time, and we decide to be
629 -- consistent. Like elaboration, the order in which these calls are made
630 -- is in some cases important.
631
632 Csets.Initialize;
633 Snames.Initialize;
634
635 -- Acquire target parameters
636
637 Targparm.Get_Target_Parameters;
638
639 -- Initialize Cumulative_Restrictions with the restrictions on the target
640 -- scanned from the system.ads file. Then as we read ALI files, we will
641 -- accumulate additional restrictions specified in other files.
642
643 Cumulative_Restrictions := Targparm.Restrictions_On_Target;
644
645 -- On OpenVMS, when -L is used, all external names used in pragmas Export
646 -- are in upper case. The reason is that on OpenVMS, the macro-assembler
647 -- MACASM-32, used to build Stand-Alone Libraries, only understands
648 -- uppercase.
649
650 if L_Switch_Seen and then OpenVMS_On_Target then
651 To_Upper (Opt.Ada_Init_Name.all);
652 To_Upper (Opt.Ada_Final_Name.all);
653 To_Upper (Opt.Ada_Main_Name.all);
654 end if;
655
656 -- Acquire configurable run-time mode
657
658 if Configurable_Run_Time_On_Target then
659 Configurable_Run_Time_Mode := True;
660 end if;
661
662 -- Output copyright notice if in verbose mode
663
664 if Verbose_Mode then
665 Write_Eol;
666 Display_Version ("GNATBIND", "1995");
667 end if;
668
669 -- Output usage information if no arguments
670
671 if not More_Lib_Files then
672 if Argument_Count = 0 then
673 Bindusg.Display;
674 else
675 Write_Line ("try `gnatbind --help` for more information.");
676 end if;
677
678 Exit_Program (E_Fatal);
679 end if;
680
681 -- If a mapping file was specified, initialize the file mapping
682
683 if Mapping_File /= null then
684 Fmap.Initialize (Mapping_File.all);
685 end if;
686
687 -- The block here is to catch the Unrecoverable_Error exception in the
688 -- case where we exceed the maximum number of permissible errors or some
689 -- other unrecoverable error occurs.
690
691 begin
692 -- Initialize binder packages
693
694 Initialize_Binderr;
695 Initialize_ALI;
696 Initialize_ALI_Source;
697
698 if Verbose_Mode then
699 Write_Eol;
700 end if;
701
702 -- Input ALI files
703
704 while More_Lib_Files loop
705 Main_Lib_File := Next_Main_Lib_File;
706
707 if First_Main_Lib_File = No_File then
708 First_Main_Lib_File := Main_Lib_File;
709 end if;
710
711 if Verbose_Mode then
712 if Check_Only then
713 Write_Str ("Checking: ");
714 else
715 Write_Str ("Binding: ");
716 end if;
717
718 Write_Name (Main_Lib_File);
719 Write_Eol;
720 end if;
721
722 Text := Read_Library_Info (Main_Lib_File, True);
723
724 declare
725 Id : ALI_Id;
726 pragma Warnings (Off, Id);
727
728 begin
729 Id := Scan_ALI
730 (F => Main_Lib_File,
731 T => Text,
732 Ignore_ED => False,
733 Err => False,
734 Ignore_Errors => Debug_Flag_I,
735 Directly_Scanned => True);
736 end;
737
738 Free (Text);
739 end loop;
740
741 -- No_Run_Time mode
742
743 if No_Run_Time_Mode then
744
745 -- Set standard configuration parameters
746
747 Suppress_Standard_Library_On_Target := True;
748 Configurable_Run_Time_Mode := True;
749 end if;
750
751 -- For main ALI files, even if they are interfaces, we get their
752 -- dependencies. To be sure, we reset the Interface flag for all main
753 -- ALI files.
754
755 for Index in ALIs.First .. ALIs.Last loop
756 ALIs.Table (Index).SAL_Interface := False;
757 end loop;
758
759 -- Add System.Standard_Library to list to ensure that these files are
760 -- included in the bind, even if not directly referenced from Ada code
761 -- This is suppressed if the appropriate targparm switch is set.
762
763 if not Suppress_Standard_Library_On_Target then
764 Name_Buffer (1 .. 12) := "s-stalib.ali";
765 Name_Len := 12;
766 Std_Lib_File := Name_Find;
767 Text := Read_Library_Info (Std_Lib_File, True);
768
769 declare
770 Id : ALI_Id;
771 pragma Warnings (Off, Id);
772
773 begin
774 Id :=
775 Scan_ALI
776 (F => Std_Lib_File,
777 T => Text,
778 Ignore_ED => False,
779 Err => False,
780 Ignore_Errors => Debug_Flag_I);
781 end;
782
783 Free (Text);
784 end if;
785
786 -- Load ALIs for all dependent units
787
788 for Index in ALIs.First .. ALIs.Last loop
789 Read_Withed_ALIs (Index);
790 end loop;
791
792 -- Quit if some file needs compiling
793
794 if No_Object_Specified then
795 raise Unrecoverable_Error;
796 end if;
797
798 -- Output list of ALI files in closure
799
800 if Output_ALI_List then
801 if ALI_List_Filename /= null then
802 Set_List_File (ALI_List_Filename.all);
803 end if;
804
805 for Index in ALIs.First .. ALIs.Last loop
806 declare
807 Full_Afile : constant File_Name_Type :=
808 Find_File (ALIs.Table (Index).Afile, Library);
809 begin
810 Write_Name (Full_Afile);
811 Write_Eol;
812 end;
813 end loop;
814
815 if ALI_List_Filename /= null then
816 Close_List_File;
817 end if;
818 end if;
819
820 -- Build source file table from the ALI files we have read in
821
822 Set_Source_Table;
823
824 -- If there is main program to bind, set Main_Lib_File to the first
825 -- library file, and the name from which to derive the binder generate
826 -- file to the first ALI file.
827
828 if Bind_Main_Program then
829 Main_Lib_File := First_Main_Lib_File;
830 Set_Current_File_Name_Index (To => 1);
831 end if;
832
833 -- Check that main library file is a suitable main program
834
835 if Bind_Main_Program
836 and then ALIs.Table (ALIs.First).Main_Program = None
837 and then not No_Main_Subprogram
838 then
839 Get_Name_String
840 (Units.Table (ALIs.Table (ALIs.First).First_Unit).Uname);
841
842 declare
843 Unit_Name : String := Name_Buffer (1 .. Name_Len - 2);
844 begin
845 To_Mixed (Unit_Name);
846 Get_Name_String (ALIs.Table (ALIs.First).Sfile);
847 Add_Str_To_Name_Buffer (":1: ");
848 Add_Str_To_Name_Buffer (Unit_Name);
849 Add_Str_To_Name_Buffer (" cannot be used as a main program");
850 Write_Line (Name_Buffer (1 .. Name_Len));
851 Errors_Detected := Errors_Detected + 1;
852 end;
853 end if;
854
855 -- Perform consistency and correctness checks
856
857 Check_Duplicated_Subunits;
858 Check_Versions;
859 Check_Consistency;
860 Check_Configuration_Consistency;
861
862 -- List restrictions that could be applied to this partition
863
864 if List_Restrictions then
865 List_Applicable_Restrictions;
866 end if;
867
868 -- Complete bind if no errors
869
870 if Errors_Detected = 0 then
871 Find_Elab_Order;
872
873 if Errors_Detected = 0 then
874 -- Display elaboration order if -l was specified
875
876 if Elab_Order_Output then
877 if not Zero_Formatting then
878 Write_Eol;
879 Write_Str ("ELABORATION ORDER");
880 Write_Eol;
881 end if;
882
883 for J in Elab_Order.First .. Elab_Order.Last loop
884 if not Units.Table (Elab_Order.Table (J)).SAL_Interface then
885 if not Zero_Formatting then
886 Write_Str (" ");
887 end if;
888
889 Write_Unit_Name
890 (Units.Table (Elab_Order.Table (J)).Uname);
891 Write_Eol;
892 end if;
893 end loop;
894
895 if not Zero_Formatting then
896 Write_Eol;
897 end if;
898 end if;
899
900 if not Check_Only then
901 Gen_Output_File (Output_File_Name.all);
902 end if;
903
904 -- Display list of sources in the closure (except predefined
905 -- sources) if -R was used.
906
907 if List_Closure then
908 List_Closure_Display : declare
909 Source : File_Name_Type;
910
911 function Put_In_Sources (S : File_Name_Type) return Boolean;
912 -- Check if S is already in table Sources and put in Sources
913 -- if it is not. Return False if the source is already in
914 -- Sources, and True if it is added.
915
916 --------------------
917 -- Put_In_Sources --
918 --------------------
919
920 function Put_In_Sources
921 (S : File_Name_Type) return Boolean
922 is
923 begin
924 for J in 1 .. Closure_Sources.Last loop
925 if Closure_Sources.Table (J) = S then
926 return False;
927 end if;
928 end loop;
929
930 Closure_Sources.Append (S);
931 return True;
932 end Put_In_Sources;
933
934 -- Start of processing for List_Closure_Display
935
936 begin
937 Closure_Sources.Init;
938
939 if not Zero_Formatting then
940 Write_Eol;
941 Write_Str ("REFERENCED SOURCES");
942 Write_Eol;
943 end if;
944
945 for J in reverse Elab_Order.First .. Elab_Order.Last loop
946 Source := Units.Table (Elab_Order.Table (J)).Sfile;
947
948 -- Do not include same source more than once
949
950 if Put_In_Sources (Source)
951
952 -- Do not include run-time units unless -Ra switch set
953
954 and then (List_Closure_All
955 or else not Is_Internal_File_Name (Source))
956 then
957 if not Zero_Formatting then
958 Write_Str (" ");
959 end if;
960
961 Write_Str (Get_Name_String (Source));
962 Write_Eol;
963 end if;
964 end loop;
965
966 -- Subunits do not appear in the elaboration table because
967 -- they are subsumed by their parent units, but we need to
968 -- list them for other tools. For now they are listed after
969 -- other files, rather than right after their parent, since
970 -- there is no easy link between the elaboration table and
971 -- the ALIs table ??? As subunits may appear repeatedly in
972 -- the list, if the parent unit appears in the context of
973 -- several units in the closure, duplicates are suppressed.
974
975 for J in Sdep.First .. Sdep.Last loop
976 Source := Sdep.Table (J).Sfile;
977
978 if Sdep.Table (J).Subunit_Name /= No_Name
979 and then Put_In_Sources (Source)
980 and then not Is_Internal_File_Name (Source)
981 then
982 if not Zero_Formatting then
983 Write_Str (" ");
984 end if;
985
986 Write_Str (Get_Name_String (Source));
987 Write_Eol;
988 end if;
989 end loop;
990
991 if not Zero_Formatting then
992 Write_Eol;
993 end if;
994 end List_Closure_Display;
995 end if;
996 end if;
997 end if;
998
999 Total_Errors := Total_Errors + Errors_Detected;
1000 Total_Warnings := Total_Warnings + Warnings_Detected;
1001
1002 exception
1003 when Unrecoverable_Error =>
1004 Total_Errors := Total_Errors + Errors_Detected;
1005 Total_Warnings := Total_Warnings + Warnings_Detected;
1006 end;
1007
1008 -- All done. Set proper exit status
1009
1010 Finalize_Binderr;
1011 Namet.Finalize;
1012
1013 if Total_Errors > 0 then
1014 Exit_Program (E_Errors);
1015
1016 elsif Total_Warnings > 0 then
1017 Exit_Program (E_Warnings);
1018
1019 else
1020 -- Do not call Exit_Program (E_Success), so that finalization occurs
1021 -- normally.
1022
1023 null;
1024 end if;
1025 end Gnatbind;