re PR fortran/30371 (kill suboutine accepts (invalid) array arguments.)
[official-gcc.git] / gcc / ada / gnatbind.adb
blob9895362a16798e7977ef0ef1e727ec0299f43e98
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-2006, 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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, 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 Snames;
47 with Switch; use Switch;
48 with Switch.B; use Switch.B;
49 with Targparm; use Targparm;
50 with Types; use Types;
52 with System.Case_Util; use System.Case_Util;
54 procedure Gnatbind is
56 Total_Errors : Nat := 0;
57 -- Counts total errors in all files
59 Total_Warnings : Nat := 0;
60 -- Total warnings in all files
62 Main_Lib_File : File_Name_Type;
63 -- Current main library file
65 Std_Lib_File : File_Name_Type;
66 -- Standard library
68 Text : Text_Buffer_Ptr;
69 Next_Arg : Positive;
71 Output_File_Name_Seen : Boolean := False;
72 Output_File_Name : String_Ptr := new String'("");
74 L_Switch_Seen : Boolean := False;
76 Mapping_File : String_Ptr := null;
78 function Gnatbind_Supports_Auto_Init return Boolean;
79 -- Indicates if automatic initialization of elaboration procedure
80 -- through the constructor mechanism is possible on the platform.
82 procedure List_Applicable_Restrictions;
83 -- List restrictions that apply to this partition if option taken
85 procedure Scan_Bind_Arg (Argv : String);
86 -- Scan and process binder specific arguments. Argv is a single argument.
87 -- All the one character arguments are still handled by Switch. This
88 -- routine handles -aO -aI and -I-. The lower bound of Argv must be 1.
90 function Is_Cross_Compiler return Boolean;
91 -- Returns True iff this is a cross-compiler
93 ---------------------------------
94 -- Gnatbind_Supports_Auto_Init --
95 ---------------------------------
97 function Gnatbind_Supports_Auto_Init return Boolean is
98 function gnat_binder_supports_auto_init return Integer;
99 pragma Import (C, gnat_binder_supports_auto_init,
100 "__gnat_binder_supports_auto_init");
101 begin
102 return gnat_binder_supports_auto_init /= 0;
103 end Gnatbind_Supports_Auto_Init;
105 -----------------------
106 -- Is_Cross_Compiler --
107 -----------------------
109 function Is_Cross_Compiler return Boolean is
110 Cross_Compiler : Integer;
111 pragma Import (C, Cross_Compiler, "__gnat_is_cross_compiler");
112 begin
113 return Cross_Compiler = 1;
114 end Is_Cross_Compiler;
116 ----------------------------------
117 -- List_Applicable_Restrictions --
118 ----------------------------------
120 procedure List_Applicable_Restrictions is
122 -- Define those restrictions that should be output if the gnatbind
123 -- -r switch is used. Not all restrictions are output for the reasons
124 -- given above in the list, and this array is used to test whether
125 -- the corresponding pragma should be listed. True means that it
126 -- should not be listed.
128 No_Restriction_List : constant array (All_Restrictions) of Boolean :=
129 (No_Exceptions => True,
130 -- Has unexpected Suppress (All_Checks) effect
132 No_Implicit_Conditionals => True,
133 -- This could modify and pessimize generated code
135 No_Implicit_Dynamic_Code => True,
136 -- This could modify and pessimize generated code
138 No_Implicit_Loops => True,
139 -- This could modify and pessimize generated code
141 No_Recursion => True,
142 -- Not checkable at compile time
144 No_Reentrancy => True,
145 -- Not checkable at compile time
147 Max_Entry_Queue_Length => True,
148 -- Not checkable at compile time
150 Max_Storage_At_Blocking => True,
151 -- Not checkable at compile time
153 others => False);
155 Additional_Restrictions_Listed : Boolean := False;
156 -- Set True if we have listed header for restrictions
158 begin
159 -- Loop through restrictions
161 for R in All_Restrictions loop
162 if not No_Restriction_List (R) then
164 -- We list a restriction if it is not violated, or if
165 -- it is violated but the violation count is exactly known.
167 if Cumulative_Restrictions.Violated (R) = False
168 or else (R in All_Parameter_Restrictions
169 and then
170 Cumulative_Restrictions.Unknown (R) = False)
171 then
172 if not Additional_Restrictions_Listed then
173 Write_Eol;
174 Write_Line
175 ("The following additional restrictions may be" &
176 " applied to this partition:");
177 Additional_Restrictions_Listed := True;
178 end if;
180 Write_Str ("pragma Restrictions (");
182 declare
183 S : constant String := Restriction_Id'Image (R);
184 begin
185 Name_Len := S'Length;
186 Name_Buffer (1 .. Name_Len) := S;
187 end;
189 Set_Casing (Mixed_Case);
190 Write_Str (Name_Buffer (1 .. Name_Len));
192 if R in All_Parameter_Restrictions then
193 Write_Str (" => ");
194 Write_Int (Int (Cumulative_Restrictions.Count (R)));
195 end if;
197 Write_Str (");");
198 Write_Eol;
199 end if;
200 end if;
201 end loop;
202 end List_Applicable_Restrictions;
204 -------------------
205 -- Scan_Bind_Arg --
206 -------------------
208 procedure Scan_Bind_Arg (Argv : String) is
209 pragma Assert (Argv'First = 1);
211 begin
212 -- Now scan arguments that are specific to the binder and are not
213 -- handled by the common circuitry in Switch.
215 if Opt.Output_File_Name_Present
216 and then not Output_File_Name_Seen
217 then
218 Output_File_Name_Seen := True;
220 if Argv'Length = 0
221 or else (Argv'Length >= 1 and then Argv (1) = '-')
222 then
223 Fail ("output File_Name missing after -o");
225 else
226 Output_File_Name := new String'(Argv);
227 end if;
229 elsif Argv'Length >= 2 and then Argv (1) = '-' then
231 -- -I-
233 if Argv (2 .. Argv'Last) = "I-" then
234 Opt.Look_In_Primary_Dir := False;
236 -- -Idir
238 elsif Argv (2) = 'I' then
239 Add_Src_Search_Dir (Argv (3 .. Argv'Last));
240 Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
242 -- -Ldir
244 elsif Argv (2) = 'L' then
245 if Argv'Length >= 3 then
247 -- Remember that the -L switch was specified, so that if this
248 -- is on OpenVMS, the export names are put in uppercase.
249 -- This is not known before the target parameters are read.
251 L_Switch_Seen := True;
253 Opt.Bind_For_Library := True;
254 Opt.Ada_Init_Name :=
255 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Init_Suffix);
256 Opt.Ada_Final_Name :=
257 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Final_Suffix);
258 Opt.Ada_Main_Name :=
259 new String'(Argv (3 .. Argv'Last) & Opt.Ada_Main_Name_Suffix);
261 -- This option (-Lxxx) implies -n
263 Opt.Bind_Main_Program := False;
265 else
266 Fail
267 ("Prefix of initialization and finalization " &
268 "procedure names missing in -L");
269 end if;
271 -- -Sin -Slo -Shi -Sxx
273 elsif Argv'Length = 4
274 and then Argv (2) = 'S'
275 then
276 declare
277 C1 : Character := Argv (3);
278 C2 : Character := Argv (4);
280 begin
281 -- Fold to upper case
283 if C1 in 'a' .. 'z' then
284 C1 := Character'Val (Character'Pos (C1) - 32);
285 end if;
287 if C2 in 'a' .. 'z' then
288 C2 := Character'Val (Character'Pos (C2) - 32);
289 end if;
291 -- Test valid option and set mode accordingly
293 if C1 = 'E' and then C2 = 'V' then
294 null;
296 elsif C1 = 'I' and then C2 = 'N' then
297 null;
299 elsif C1 = 'L' and then C2 = 'O' then
300 null;
302 elsif C1 = 'H' and then C2 = 'I' then
303 null;
305 elsif (C1 in '0' .. '9' or else C1 in 'A' .. 'F')
306 and then
307 (C2 in '0' .. '9' or else C2 in 'A' .. 'F')
308 then
309 null;
311 -- Invalid -S switch, let Switch give error, set defalut of IN
313 else
314 Scan_Binder_Switches (Argv);
315 C1 := 'I';
316 C2 := 'N';
317 end if;
319 Initialize_Scalars_Mode1 := C1;
320 Initialize_Scalars_Mode2 := C2;
321 end;
323 -- -aIdir
325 elsif Argv'Length >= 3
326 and then Argv (2 .. 3) = "aI"
327 then
328 Add_Src_Search_Dir (Argv (4 .. Argv'Last));
330 -- -aOdir
332 elsif Argv'Length >= 3
333 and then Argv (2 .. 3) = "aO"
334 then
335 Add_Lib_Search_Dir (Argv (4 .. Argv'Last));
337 -- -nostdlib
339 elsif Argv (2 .. Argv'Last) = "nostdlib" then
340 Opt.No_Stdlib := True;
342 -- -nostdinc
344 elsif Argv (2 .. Argv'Last) = "nostdinc" then
345 Opt.No_Stdinc := True;
347 -- -static
349 elsif Argv (2 .. Argv'Last) = "static" then
350 Opt.Shared_Libgnat := False;
352 -- -shared
354 elsif Argv (2 .. Argv'Last) = "shared" then
355 Opt.Shared_Libgnat := True;
357 -- -F=mapping_file
359 elsif Argv'Length >= 4 and then Argv (2 .. 3) = "F=" then
360 if Mapping_File /= null then
361 Fail ("cannot specify several mapping files");
362 end if;
364 Mapping_File := new String'(Argv (4 .. Argv'Last));
366 -- -Mname
368 elsif Argv'Length >= 3 and then Argv (2) = 'M' then
369 if not Is_Cross_Compiler then
370 Write_Line
371 ("gnatbind: -M not expected to be used on native platforms");
372 end if;
374 Opt.Bind_Alternate_Main_Name := True;
375 Opt.Alternate_Main_Name := new String'(Argv (3 .. Argv'Last));
377 -- All other options are single character and are handled by
378 -- Scan_Binder_Switches.
380 else
381 Scan_Binder_Switches (Argv);
382 end if;
384 -- Not a switch, so must be a file name (if non-empty)
386 elsif Argv'Length /= 0 then
387 if Argv'Length > 4
388 and then Argv (Argv'Last - 3 .. Argv'Last) = ".ali"
389 then
390 Add_File (Argv);
391 else
392 Add_File (Argv & ".ali");
393 end if;
394 end if;
395 end Scan_Bind_Arg;
397 -- Start of processing for Gnatbind
399 begin
401 -- Set default for Shared_Libgnat option
403 declare
404 Shared_Libgnat_Default : Character;
405 pragma Import
406 (C, Shared_Libgnat_Default, "__gnat_shared_libgnat_default");
408 SHARED : constant Character := 'H';
409 STATIC : constant Character := 'T';
411 begin
412 pragma Assert
413 (Shared_Libgnat_Default = SHARED
414 or else
415 Shared_Libgnat_Default = STATIC);
416 Shared_Libgnat := (Shared_Libgnat_Default = SHARED);
417 end;
419 -- Use low level argument routines to avoid dragging in the secondary stack
421 Next_Arg := 1;
422 Scan_Args : while Next_Arg < Arg_Count loop
423 declare
424 Next_Argv : String (1 .. Len_Arg (Next_Arg));
425 begin
426 Fill_Arg (Next_Argv'Address, Next_Arg);
427 Scan_Bind_Arg (Next_Argv);
428 end;
430 Next_Arg := Next_Arg + 1;
431 end loop Scan_Args;
433 if Use_Pragma_Linker_Constructor then
434 if Bind_Main_Program then
435 Fail ("switch -a must be used in conjunction with -n or -Lxxx");
437 elsif not Gnatbind_Supports_Auto_Init then
438 Fail ("automatic initialisation of elaboration " &
439 "not supported on this platform");
440 end if;
441 end if;
443 -- Test for trailing -o switch
445 if Opt.Output_File_Name_Present
446 and then not Output_File_Name_Seen
447 then
448 Fail ("output file name missing after -o");
449 end if;
451 -- Output usage if requested
453 if Usage_Requested then
454 Bindusg.Display;
455 end if;
457 -- Check that the Ada binder file specified has extension .adb and that
458 -- the C binder file has extension .c
460 if Opt.Output_File_Name_Present
461 and then Output_File_Name_Seen
462 then
463 Check_Extensions : declare
464 Length : constant Natural := Output_File_Name'Length;
465 Last : constant Natural := Output_File_Name'Last;
467 begin
468 if Ada_Bind_File then
469 if Length <= 4
470 or else Output_File_Name (Last - 3 .. Last) /= ".adb"
471 then
472 Fail ("output file name should have .adb extension");
473 end if;
475 else
476 if Length <= 2
477 or else Output_File_Name (Last - 1 .. Last) /= ".c"
478 then
479 Fail ("output file name should have .c extension");
480 end if;
481 end if;
482 end Check_Extensions;
483 end if;
485 Osint.Add_Default_Search_Dirs;
487 -- Carry out package initializations. These are initializations which
488 -- might logically be performed at elaboration time, but Namet at least
489 -- can't be done that way (because it is used in the Compiler), and we
490 -- decide to be consistent. Like elaboration, the order in which these
491 -- calls are made is in some cases important.
493 Csets.Initialize;
494 Namet.Initialize;
495 Snames.Initialize;
497 -- Acquire target parameters
499 Targparm.Get_Target_Parameters;
501 -- Initialize Cumulative_Restrictions with the restrictions on the target
502 -- scanned from the system.ads file. Then as we read ALI files, we will
503 -- accumulate additional restrictions specified in other files.
505 Cumulative_Restrictions := Targparm.Restrictions_On_Target;
507 -- On OpenVMS, when -L is used, all external names used in pragmas Export
508 -- are in upper case. The reason is that on OpenVMS, the macro-assembler
509 -- MACASM-32, used to build Stand-Alone Libraries, only understands
510 -- uppercase.
512 if L_Switch_Seen and then OpenVMS_On_Target then
513 To_Upper (Opt.Ada_Init_Name.all);
514 To_Upper (Opt.Ada_Final_Name.all);
515 To_Upper (Opt.Ada_Main_Name.all);
516 end if;
518 -- Acquire configurable run-time mode
520 if Configurable_Run_Time_On_Target then
521 Configurable_Run_Time_Mode := True;
522 end if;
524 -- Output copyright notice if in verbose mode
526 if Verbose_Mode then
527 Write_Eol;
528 Write_Str ("GNATBIND ");
529 Write_Str (Gnat_Version_String);
530 Write_Eol;
531 Write_Str ("Copyright 1995-" &
532 Current_Year &
533 ", Free Software Foundation, Inc.");
534 Write_Eol;
535 end if;
537 -- Output usage information if no files
539 if not More_Lib_Files then
540 Bindusg.Display;
541 Exit_Program (E_Fatal);
542 end if;
544 -- If a mapping file was specified, initialize the file mapping
546 if Mapping_File /= null then
547 Fmap.Initialize (Mapping_File.all);
548 end if;
550 -- The block here is to catch the Unrecoverable_Error exception in the
551 -- case where we exceed the maximum number of permissible errors or some
552 -- other unrecoverable error occurs.
554 begin
555 -- Initialize binder packages
557 Initialize_Binderr;
558 Initialize_ALI;
559 Initialize_ALI_Source;
561 if Verbose_Mode then
562 Write_Eol;
563 end if;
565 -- Input ALI files
567 while More_Lib_Files loop
568 Main_Lib_File := Next_Main_Lib_File;
570 if Verbose_Mode then
571 if Check_Only then
572 Write_Str ("Checking: ");
573 else
574 Write_Str ("Binding: ");
575 end if;
577 Write_Name (Main_Lib_File);
578 Write_Eol;
579 end if;
581 Text := Read_Library_Info (Main_Lib_File, True);
583 declare
584 Id : ALI_Id;
585 pragma Warnings (Off, Id);
587 begin
588 Id := Scan_ALI
589 (F => Main_Lib_File,
590 T => Text,
591 Ignore_ED => False,
592 Err => False,
593 Ignore_Errors => Debug_Flag_I);
594 end;
596 Free (Text);
597 end loop;
599 -- No_Run_Time mode
601 if No_Run_Time_Mode then
603 -- Set standard configuration parameters
605 Suppress_Standard_Library_On_Target := True;
606 Configurable_Run_Time_Mode := True;
607 end if;
609 -- For main ALI files, even if they are interfaces, we get their
610 -- dependencies. To be sure, we reset the Interface flag for all main
611 -- ALI files.
613 for Index in ALIs.First .. ALIs.Last loop
614 ALIs.Table (Index).SAL_Interface := False;
615 end loop;
617 -- Add System.Standard_Library to list to ensure that these files are
618 -- included in the bind, even if not directly referenced from Ada code
619 -- This is suppressed if the appropriate targparm switch is set.
621 if not Suppress_Standard_Library_On_Target then
622 Name_Buffer (1 .. 12) := "s-stalib.ali";
623 Name_Len := 12;
624 Std_Lib_File := Name_Find;
625 Text := Read_Library_Info (Std_Lib_File, True);
627 declare
628 Id : ALI_Id;
629 pragma Warnings (Off, Id);
631 begin
632 Id :=
633 Scan_ALI
634 (F => Std_Lib_File,
635 T => Text,
636 Ignore_ED => False,
637 Err => False,
638 Ignore_Errors => Debug_Flag_I);
639 end;
641 Free (Text);
642 end if;
644 -- Acquire all information in ALI files that have been read in
646 for Index in ALIs.First .. ALIs.Last loop
647 Read_ALI (Index);
648 end loop;
650 -- Quit if some file needs compiling
652 if No_Object_Specified then
653 raise Unrecoverable_Error;
654 end if;
656 -- Build source file table from the ALI files we have read in
658 Set_Source_Table;
660 -- Check that main library file is a suitable main program
662 if Bind_Main_Program
663 and then ALIs.Table (ALIs.First).Main_Program = None
664 and then not No_Main_Subprogram
665 then
666 Error_Msg_Name_1 := Main_Lib_File;
667 Error_Msg ("% does not contain a unit that can be a main program");
668 end if;
670 -- Perform consistency and correctness checks
672 Check_Duplicated_Subunits;
673 Check_Versions;
674 Check_Consistency;
675 Check_Configuration_Consistency;
677 -- List restrictions that could be applied to this partition
679 if List_Restrictions then
680 List_Applicable_Restrictions;
681 end if;
683 -- Complete bind if no errors
685 if Errors_Detected = 0 then
686 Find_Elab_Order;
688 if Errors_Detected = 0 then
689 if Elab_Order_Output then
690 Write_Eol;
691 Write_Str ("ELABORATION ORDER");
692 Write_Eol;
694 for J in Elab_Order.First .. Elab_Order.Last loop
695 if not Units.Table (Elab_Order.Table (J)).SAL_Interface then
696 Write_Str (" ");
697 Write_Unit_Name
698 (Units.Table (Elab_Order.Table (J)).Uname);
699 Write_Eol;
700 end if;
701 end loop;
703 Write_Eol;
704 end if;
706 if not Check_Only then
707 Gen_Output_File (Output_File_Name.all);
708 end if;
709 end if;
710 end if;
712 Total_Errors := Total_Errors + Errors_Detected;
713 Total_Warnings := Total_Warnings + Warnings_Detected;
715 exception
716 when Unrecoverable_Error =>
717 Total_Errors := Total_Errors + Errors_Detected;
718 Total_Warnings := Total_Warnings + Warnings_Detected;
719 end;
721 -- All done. Set proper exit status
723 Finalize_Binderr;
724 Namet.Finalize;
726 if Total_Errors > 0 then
727 Exit_Program (E_Errors);
729 elsif Total_Warnings > 0 then
730 Exit_Program (E_Warnings);
732 else
733 -- Do not call Exit_Program (E_Success), so that finalization occurs
734 -- normally.
736 null;
737 end if;
739 end Gnatbind;