1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 -- Option switch scanning for both the compiler and the binder
31 -- Note: this version of the package should be usable in both Unix and DOS
33 with Debug; use Debug;
34 with Osint; use Osint;
36 with Validsw; use Validsw;
37 with Stylesw; use Stylesw;
38 with Types; use Types;
40 with System.WCh_Con; use System.WCh_Con;
42 package body Switch is
44 Bad_Switch : exception;
45 -- Exception raised if bad switch encountered
47 Bad_Switch_Value : exception;
48 -- Exception raised if bad switch value encountered
50 Missing_Switch_Value : exception;
51 -- Exception raised if no switch value encountered
53 Too_Many_Output_Files : exception;
54 -- Exception raised if the -o switch is encountered more than once
56 Switch_Max_Value : constant := 999;
57 -- Maximum value permitted in switches that take a value
60 (Switch_Chars : String;
64 -- Scan natural integer parameter for switch. On entry, Ptr points
65 -- just past the switch character, on exit it points past the last
66 -- digit of the integer value.
69 (Switch_Chars : String;
73 -- Scan positive integer parameter for switch. On entry, Ptr points
74 -- just past the switch character, on exit it points past the last
75 -- digit of the integer value.
77 -------------------------
78 -- Is_Front_End_Switch --
79 -------------------------
81 function Is_Front_End_Switch (Switch_Chars : String) return Boolean is
82 Ptr : constant Positive := Switch_Chars'First;
84 return Is_Switch (Switch_Chars)
86 (Switch_Chars (Ptr + 1) = 'I'
88 (Switch_Chars'Length >= 5
89 and then Switch_Chars (Ptr + 1 .. Ptr + 4) = "gnat"));
90 end Is_Front_End_Switch;
96 function Is_Switch (Switch_Chars : String) return Boolean is
98 return Switch_Chars'Length > 1
99 and then (Switch_Chars (Switch_Chars'First) = '-'
101 Switch_Chars (Switch_Chars'First) = Switch_Character);
104 --------------------------
105 -- Scan_Binder_Switches --
106 --------------------------
108 procedure Scan_Binder_Switches (Switch_Chars : String) is
109 Ptr : Integer := Switch_Chars'First;
110 Max : Integer := Switch_Chars'Last;
111 C : Character := ' ';
114 -- Skip past the initial character (must be the switch character)
122 -- A little check, "gnat" at the start of a switch is not allowed
123 -- except for the compiler
125 if Switch_Chars'Last >= Ptr + 3
126 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
128 Osint.Fail ("invalid switch: """, Switch_Chars, """"
129 & " (gnat not needed here)");
133 -- Loop to scan through switches given in switch string
135 while Ptr <= Max loop
136 C := Switch_Chars (Ptr);
140 -- Processing for A switch
145 Ada_Bind_File := True;
147 -- Processing for b switch
151 Brief_Output := True;
153 -- Processing for c switch
160 -- Processing for C switch
165 Ada_Bind_File := False;
167 -- Processing for d switch
171 -- Note: for the debug switch, the remaining characters in this
172 -- switch field must all be debug flags, since all valid switch
173 -- characters are also valid debug characters.
175 -- Loop to scan out debug flags
179 C := Switch_Chars (Ptr);
180 exit when C = ASCII.NUL or else C = '/' or else C = '-';
182 if C in '1' .. '9' or else
183 C in 'a' .. 'z' or else
192 -- Make sure Zero_Cost_Exceptions is set if gnatdX set. This
193 -- is for backwards compatibility with old versions and usage.
195 if Debug_Flag_XX then
196 Zero_Cost_Exceptions_Set := True;
197 Zero_Cost_Exceptions_Val := True;
202 -- Processing for e switch
206 Elab_Dependency_Output := True;
208 -- Processing for E switch
212 Exception_Tracebacks := True;
214 -- Processing for f switch
218 Force_RM_Elaboration_Order := True;
220 -- Processing for g switch
226 C := Switch_Chars (Ptr);
228 if C in '0' .. '3' then
231 (Switch_Chars (Ptr)) - Character'Pos ('0');
239 -- Processing for G switch
243 Print_Generated_Code := True;
245 -- Processing for h switch
249 Usage_Requested := True;
251 -- Processing for i switch
259 C := Switch_Chars (Ptr);
268 Identifier_Character_Set := C;
274 -- Processing for K switch
279 if Program = Binder then
280 Output_Linker_Option_List := True;
285 -- Processing for l switch
289 Elab_Order_Output := True;
291 -- Processing for m switch
295 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
297 -- Processing for n switch
301 Bind_Main_Program := False;
303 -- Note: The -L option of the binder also implies -n, so
304 -- any change here must also be reflected in the processing
305 -- for -L that is found in Gnatbind.Scan_Bind_Arg.
307 -- Processing for o switch
312 if Output_File_Name_Present then
313 raise Too_Many_Output_Files;
316 Output_File_Name_Present := True;
319 -- Processing for O switch
323 Output_Object_List := True;
325 -- Processing for p switch
329 Pessimistic_Elab_Order := True;
331 -- Processing for q switch
335 Quiet_Output := True;
337 -- Processing for s switch
342 Check_Source_Files := True;
344 -- Processing for t switch
348 Tolerate_Consistency_Errors := True;
350 -- Processing for T switch
354 Time_Slice_Set := True;
355 Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
357 -- Processing for v switch
361 Verbose_Mode := True;
363 -- Processing for w switch
367 -- For the binder we only allow suppress/error cases
371 case Switch_Chars (Ptr) is
374 Warning_Mode := Treat_As_Error;
377 Warning_Mode := Suppress;
385 -- Processing for W switch
390 for J in WC_Encoding_Method loop
391 if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
392 Wide_Character_Encoding_Method := J;
395 elsif J = WC_Encoding_Method'Last then
400 Upper_Half_Encoding :=
401 Wide_Character_Encoding_Method in
402 WC_Upper_Half_Encoding_Method;
406 -- Processing for x switch
410 All_Sources := False;
411 Check_Source_Files := False;
413 -- Processing for z switch
417 No_Main_Subprogram := True;
419 -- Ignore extra switch character
424 -- Anything else is an error (illegal switch character)
433 Osint.Fail ("invalid switch: ", (1 => C));
435 when Bad_Switch_Value =>
436 Osint.Fail ("numeric value too big for switch: ", (1 => C));
438 when Missing_Switch_Value =>
439 Osint.Fail ("missing numeric value for switch: ", (1 => C));
441 when Too_Many_Output_Files =>
442 Osint.Fail ("duplicate -o switch");
443 end Scan_Binder_Switches;
445 -----------------------------
446 -- Scan_Front_End_Switches --
447 -----------------------------
449 procedure Scan_Front_End_Switches (Switch_Chars : String) is
450 Switch_Starts_With_Gnat : Boolean;
451 Ptr : Integer := Switch_Chars'First;
452 Max : constant Integer := Switch_Chars'Last;
453 C : Character := ' ';
456 -- Skip past the initial character (must be the switch character)
465 -- A little check, "gnat" at the start of a switch is not allowed
466 -- except for the compiler (where it was already removed)
468 Switch_Starts_With_Gnat :=
469 Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
471 if Switch_Starts_With_Gnat then
475 -- Loop to scan through switches given in switch string
477 while Ptr <= Max loop
478 C := Switch_Chars (Ptr);
480 -- Processing for a switch
482 case Switch_Starts_With_Gnat is
485 -- There is only one front-end switch that
486 -- does not start with -gnat, namely -I
497 -- Find out whether this is a -I- or regular -Ixxx switch
499 if Ptr = Max and then Switch_Chars (Ptr) = '-' then
500 Look_In_Primary_Dir := False;
503 Add_Src_Search_Dir (Switch_Chars (Ptr .. Max));
509 -- Should not happen, as Scan_Switches is supposed
510 -- to be called for front-end switches only.
511 -- Still, it is safest to raise Bad_Switch error.
517 -- Process -gnat* options
523 Assertions_Enabled := True;
525 -- Processing for A switch
529 Config_File := False;
531 -- Processing for b switch
535 Brief_Output := True;
537 -- Processing for c switch
541 Operating_Mode := Check_Semantics;
543 -- Processing for C switch
547 Compress_Debug_Names := True;
549 -- Processing for d switch
553 -- Note: for the debug switch, the remaining characters in this
554 -- switch field must all be debug flags, since all valid switch
555 -- characters are also valid debug characters.
557 -- Loop to scan out debug flags
561 C := Switch_Chars (Ptr);
562 exit when C = ASCII.NUL or else C = '/' or else C = '-';
564 if C in '1' .. '9' or else
565 C in 'a' .. 'z' or else
575 -- Make sure Zero_Cost_Exceptions is set if gnatdX set. This
576 -- is for backwards compatibility with old versions and usage.
578 if Debug_Flag_XX then
579 Zero_Cost_Exceptions_Set := True;
580 Zero_Cost_Exceptions_Val := True;
585 -- Processing for D switch
590 -- Note: -gnatD also sets -gnatx (to turn off cross-reference
591 -- generation in the ali file) since otherwise this generation
592 -- gets confused by the "wrong" Sloc values put in the tree.
594 Debug_Generated_Code := True;
595 Xref_Active := False;
596 Set_Debug_Flag ('g');
598 -- Processing for e switch
607 case Switch_Chars (Ptr) is
612 Osint.Fail ("Invalid switch: ", "ec");
616 new String'(Switch_Chars (Ptr .. Max));
621 Osint.Fail ("Invalid switch: ",
622 (1 => 'e', 2 => Switch_Chars (Ptr)));
625 -- Processing for E switch
629 Dynamic_Elaboration_Checks := True;
631 -- Processing for f switch
635 All_Errors_Mode := True;
637 -- Processing for F switch
641 External_Name_Exp_Casing := Uppercase;
642 External_Name_Imp_Casing := Uppercase;
644 -- Processing for g switch
649 Identifier_Character_Set := 'n';
650 Warning_Mode := Treat_As_Error;
651 Check_Unreferenced := True;
654 Set_Default_Style_Check_Options;
656 -- Processing for G switch
660 Print_Generated_Code := True;
662 -- Processing for h switch
666 Usage_Requested := True;
668 -- Processing for H switch
674 -- Processing for i switch
682 C := Switch_Chars (Ptr);
691 Identifier_Character_Set := C;
698 -- Processing for k switch
702 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_File_Name_Length);
704 -- Processing for l switch
710 -- Processing for L switch
714 Zero_Cost_Exceptions_Set := True;
715 Zero_Cost_Exceptions_Val := False;
717 -- Processing for m switch
721 Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
723 -- Processing for n switch
727 Inline_Active := True;
729 -- Processing for N switch
733 Inline_Active := True;
734 Front_End_Inlining := True;
736 -- Processing for o switch
740 Suppress_Options.Overflow_Checks := False;
742 -- Processing for O switch
746 Output_File_Name_Present := True;
748 -- Processing for p switch
752 Suppress_Options.Access_Checks := True;
753 Suppress_Options.Accessibility_Checks := True;
754 Suppress_Options.Discriminant_Checks := True;
755 Suppress_Options.Division_Checks := True;
756 Suppress_Options.Elaboration_Checks := True;
757 Suppress_Options.Index_Checks := True;
758 Suppress_Options.Length_Checks := True;
759 Suppress_Options.Overflow_Checks := True;
760 Suppress_Options.Range_Checks := True;
761 Suppress_Options.Division_Checks := True;
762 Suppress_Options.Length_Checks := True;
763 Suppress_Options.Range_Checks := True;
764 Suppress_Options.Storage_Checks := True;
765 Suppress_Options.Tag_Checks := True;
767 Validity_Checks_On := False;
769 -- Processing for P switch
773 Polling_Required := True;
775 -- Processing for q switch
779 Try_Semantics := True;
781 -- Processing for q switch
785 Force_ALI_Tree_File := True;
786 Try_Semantics := True;
788 -- Processing for r switch
793 -- Temporarily allow -gnatr to mean -gnatyl (use RM layout)
794 -- for compatibility with pre 3.12 versions of GNAT,
795 -- to be removed for 3.13 ???
797 Set_Style_Check_Options ("l");
799 -- Processing for R switch
803 Back_Annotate_Rep_Info := True;
806 and then Switch_Chars (Ptr) in '0' .. '9'
808 C := Switch_Chars (Ptr);
810 if C in '4' .. '9' then
813 List_Representation_Info :=
814 Character'Pos (C) - Character'Pos ('0');
819 List_Representation_Info := 1;
822 -- Processing for s switch
826 Operating_Mode := Check_Syntax;
828 -- Processing for t switch
833 Back_Annotate_Rep_Info := True;
835 -- Processing for T switch
839 Time_Slice_Set := True;
840 Scan_Nat (Switch_Chars, Max, Ptr, Time_Slice_Value);
842 -- Processing for u switch
848 -- Processing for U switch
852 Unique_Error_Tag := True;
854 -- Processing for v switch
858 Verbose_Mode := True;
860 -- Processing for V switch
873 Set_Validity_Check_Options
874 (Switch_Chars (Ptr .. Max), OK, Ptr);
882 -- Processing for w switch
891 while Ptr <= Max loop
892 C := Switch_Chars (Ptr);
897 Constant_Condition_Warnings := True;
898 Elab_Warnings := True;
899 Check_Unreferenced := True;
901 Implementation_Unit_Warnings := True;
902 Ineffective_Inline_Warnings := True;
903 Warn_On_Redundant_Constructs := True;
906 Constant_Condition_Warnings := False;
907 Elab_Warnings := False;
908 Check_Unreferenced := False;
909 Check_Withs := False;
910 Implementation_Unit_Warnings := False;
911 Warn_On_Biased_Rounding := False;
912 Warn_On_Hiding := False;
913 Warn_On_Redundant_Constructs := False;
914 Ineffective_Inline_Warnings := False;
917 Constant_Condition_Warnings := True;
920 Constant_Condition_Warnings := False;
923 Warn_On_Biased_Rounding := True;
926 Warn_On_Biased_Rounding := False;
929 Warning_Mode := Treat_As_Error;
932 Warn_On_Hiding := True;
935 Warn_On_Hiding := False;
938 Implementation_Unit_Warnings := True;
941 Implementation_Unit_Warnings := False;
944 Elab_Warnings := True;
947 Elab_Warnings := False;
950 Address_Clause_Overlay_Warnings := True;
953 Address_Clause_Overlay_Warnings := False;
956 Ineffective_Inline_Warnings := True;
959 Ineffective_Inline_Warnings := False;
962 Warn_On_Redundant_Constructs := True;
965 Warn_On_Redundant_Constructs := False;
968 Warning_Mode := Suppress;
971 Check_Unreferenced := True;
975 Check_Unreferenced := False;
976 Check_Withs := False;
978 -- Allow and ignore 'w' so that the old
979 -- format (e.g. -gnatwuwl) will work.
993 -- Processing for W switch
998 for J in WC_Encoding_Method loop
999 if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
1000 Wide_Character_Encoding_Method := J;
1003 elsif J = WC_Encoding_Method'Last then
1008 Upper_Half_Encoding :=
1009 Wide_Character_Encoding_Method in
1010 WC_Upper_Half_Encoding_Method;
1014 -- Processing for x switch
1018 Xref_Active := False;
1020 -- Processing for X switch
1024 Extensions_Allowed := True;
1026 -- Processing for y switch
1032 Set_Default_Style_Check_Options;
1039 Set_Style_Check_Options
1040 (Switch_Chars (Ptr .. Max), OK, Ptr);
1048 -- Processing for z switch
1053 -- Allowed for compiler, only if this is the only
1054 -- -z switch, we do not allow multiple occurrences
1056 if Distribution_Stub_Mode = No_Stubs then
1057 case Switch_Chars (Ptr) is
1059 Distribution_Stub_Mode := Generate_Receiver_Stub_Body;
1062 Distribution_Stub_Mode := Generate_Caller_Stub_Body;
1072 -- Processing for Z switch
1076 Zero_Cost_Exceptions_Set := True;
1077 Zero_Cost_Exceptions_Val := True;
1079 -- Processing for 83 switch
1089 if Switch_Chars (Ptr) /= '3' then
1097 -- Ignore extra switch character
1102 -- Anything else is an error (illegal switch character)
1112 Osint.Fail ("invalid switch: ", (1 => C));
1114 when Bad_Switch_Value =>
1115 Osint.Fail ("numeric value too big for switch: ", (1 => C));
1117 when Missing_Switch_Value =>
1118 Osint.Fail ("missing numeric value for switch: ", (1 => C));
1120 end Scan_Front_End_Switches;
1122 ------------------------
1123 -- Scan_Make_Switches --
1124 ------------------------
1126 procedure Scan_Make_Switches (Switch_Chars : String) is
1127 Ptr : Integer := Switch_Chars'First;
1128 Max : Integer := Switch_Chars'Last;
1129 C : Character := ' ';
1132 -- Skip past the initial character (must be the switch character)
1141 -- A little check, "gnat" at the start of a switch is not allowed
1142 -- except for the compiler (where it was already removed)
1144 if Switch_Chars'Length >= Ptr + 3
1145 and then Switch_Chars (Ptr .. Ptr + 3) = "gnat"
1148 ("invalid switch: """, Switch_Chars, """ (gnat not needed here)");
1151 -- Loop to scan through switches given in switch string
1153 while Ptr <= Max loop
1154 C := Switch_Chars (Ptr);
1156 -- Processing for a switch
1162 Check_Readonly_Files := True;
1164 -- Processing for b switch
1170 -- Processing for c switch
1174 Compile_Only := True;
1178 -- Note: for the debug switch, the remaining characters in this
1179 -- switch field must all be debug flags, since all valid switch
1180 -- characters are also valid debug characters.
1182 -- Loop to scan out debug flags
1184 while Ptr < Max loop
1186 C := Switch_Chars (Ptr);
1187 exit when C = ASCII.NUL or else C = '/' or else C = '-';
1189 if C in '1' .. '9' or else
1190 C in 'a' .. 'z' or else
1199 -- Make sure Zero_Cost_Exceptions is set if gnatdX set. This
1200 -- is for backwards compatibility with old versions and usage.
1202 if Debug_Flag_XX then
1203 Zero_Cost_Exceptions_Set := True;
1204 Zero_Cost_Exceptions_Val := True;
1209 -- Processing for f switch
1213 Force_Compilations := True;
1215 -- Processing for G switch
1219 Print_Generated_Code := True;
1221 -- Processing for h switch
1225 Usage_Requested := True;
1227 -- Processing for i switch
1231 In_Place_Mode := True;
1233 -- Processing for j switch
1241 Scan_Pos (Switch_Chars, Max, Ptr, Max_Proc);
1242 Maximum_Processes := Positive (Max_Proc);
1245 -- Processing for k switch
1251 -- Processing for l switch
1259 List_Dependencies := True;
1261 -- Processing for n switch
1265 Do_Not_Execute := True;
1267 -- Processing for o switch
1272 if Output_File_Name_Present then
1273 raise Too_Many_Output_Files;
1275 Output_File_Name_Present := True;
1278 -- Processing for q switch
1282 Quiet_Output := True;
1284 -- Processing for s switch
1288 Check_Switches := True;
1290 -- Processing for v switch
1294 Verbose_Mode := True;
1296 -- Processing for z switch
1300 No_Main_Subprogram := True;
1302 -- Ignore extra switch character
1307 -- Anything else is an error (illegal switch character)
1317 Osint.Fail ("invalid switch: ", (1 => C));
1319 when Bad_Switch_Value =>
1320 Osint.Fail ("numeric value too big for switch: ", (1 => C));
1322 when Missing_Switch_Value =>
1323 Osint.Fail ("missing numeric value for switch: ", (1 => C));
1325 when Too_Many_Output_Files =>
1326 Osint.Fail ("duplicate -o switch");
1328 end Scan_Make_Switches;
1335 (Switch_Chars : String;
1337 Ptr : in out Integer;
1338 Result : out Nat) is
1341 if Ptr > Max or else Switch_Chars (Ptr) not in '0' .. '9' then
1342 raise Missing_Switch_Value;
1345 while Ptr <= Max and then Switch_Chars (Ptr) in '0' .. '9' loop
1346 Result := Result * 10 +
1347 Character'Pos (Switch_Chars (Ptr)) - Character'Pos ('0');
1350 if Result > Switch_Max_Value then
1351 raise Bad_Switch_Value;
1361 (Switch_Chars : String;
1363 Ptr : in out Integer;
1364 Result : out Pos) is
1367 Scan_Nat (Switch_Chars, Max, Ptr, Result);
1369 raise Bad_Switch_Value;