| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- S W I T C H - C -- |
| -- -- |
| -- B o d y -- |
| -- -- |
| -- Copyright (C) 2001-2015, Free Software Foundation, Inc. -- |
| -- -- |
| -- GNAT is free software; you can redistribute it and/or modify it under -- |
| -- terms of the GNU General Public License as published by the Free Soft- -- |
| -- ware Foundation; either version 3, or (at your option) any later ver- -- |
| -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
| -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
| -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- |
| -- for more details. You should have received a copy of the GNU General -- |
| -- Public License distributed with GNAT; see file COPYING3. If not, go to -- |
| -- http://www.gnu.org/licenses for a complete copy of the license. -- |
| -- -- |
| -- GNAT was originally developed by the GNAT team at New York University. -- |
| -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
| -- -- |
| ------------------------------------------------------------------------------ |
| |
| -- This package is for switch processing and should not depend on higher level |
| -- packages such as those for the scanner, parser, etc. Doing so may cause |
| -- circularities, especially for back ends using Adabkend. |
| |
| with Debug; use Debug; |
| with Lib; use Lib; |
| with Osint; use Osint; |
| with Opt; use Opt; |
| with Stylesw; use Stylesw; |
| with Targparm; use Targparm; |
| with Ttypes; use Ttypes; |
| with Validsw; use Validsw; |
| with Warnsw; use Warnsw; |
| |
| with Ada.Unchecked_Deallocation; |
| |
| with System.WCh_Con; use System.WCh_Con; |
| with System.OS_Lib; |
| |
| package body Switch.C is |
| |
| RTS_Specified : String_Access := null; |
| -- Used to detect multiple use of --RTS= flag |
| |
| procedure Add_Symbol_Definition (Def : String); |
| -- Add a symbol definition from the command line |
| |
| procedure Free is |
| new Ada.Unchecked_Deallocation (String_List, String_List_Access); |
| -- Avoid using System.Strings.Free, which also frees the designated strings |
| |
| function Get_Overflow_Mode (C : Character) return Overflow_Mode_Type; |
| -- Given a digit in the range 0 .. 3, returns the corresponding value of |
| -- Overflow_Mode_Type. Raises Program_Error if C is outside this range. |
| |
| function Switch_Subsequently_Cancelled |
| (C : String; |
| Args : String_List; |
| Arg_Rank : Positive) return Boolean; |
| -- This function is called from Scan_Front_End_Switches. It determines if |
| -- the switch currently being scanned is followed by a switch of the form |
| -- "-gnat-" & C, where C is the argument. If so, then True is returned, |
| -- and Scan_Front_End_Switches will cancel the effect of the switch. If |
| -- no such switch is found, False is returned. |
| |
| --------------------------- |
| -- Add_Symbol_Definition -- |
| --------------------------- |
| |
| procedure Add_Symbol_Definition (Def : String) is |
| begin |
| -- If Preprocessor_Symbol_Defs is not large enough, double its size |
| |
| if Preprocessing_Symbol_Last = Preprocessing_Symbol_Defs'Last then |
| declare |
| New_Symbol_Definitions : constant String_List_Access := |
| new String_List (1 .. 2 * Preprocessing_Symbol_Last); |
| begin |
| New_Symbol_Definitions (Preprocessing_Symbol_Defs'Range) := |
| Preprocessing_Symbol_Defs.all; |
| Free (Preprocessing_Symbol_Defs); |
| Preprocessing_Symbol_Defs := New_Symbol_Definitions; |
| end; |
| end if; |
| |
| Preprocessing_Symbol_Last := Preprocessing_Symbol_Last + 1; |
| Preprocessing_Symbol_Defs (Preprocessing_Symbol_Last) := |
| new String'(Def); |
| end Add_Symbol_Definition; |
| |
| ----------------------- |
| -- Get_Overflow_Mode -- |
| ----------------------- |
| |
| function Get_Overflow_Mode (C : Character) return Overflow_Mode_Type is |
| begin |
| case C is |
| when '1' => |
| return Strict; |
| |
| when '2' => |
| return Minimized; |
| |
| -- Eliminated allowed only if Long_Long_Integer is 64 bits (since |
| -- the current implementation of System.Bignums assumes this). |
| |
| when '3' => |
| if Standard_Long_Long_Integer_Size /= 64 then |
| Bad_Switch ("-gnato3 not implemented for this configuration"); |
| else |
| return Eliminated; |
| end if; |
| |
| when others => |
| raise Program_Error; |
| end case; |
| end Get_Overflow_Mode; |
| |
| ----------------------------- |
| -- Scan_Front_End_Switches -- |
| ----------------------------- |
| |
| procedure Scan_Front_End_Switches |
| (Switch_Chars : String; |
| Args : String_List; |
| Arg_Rank : Positive) |
| is |
| First_Switch : Boolean := True; |
| -- False for all but first switch |
| |
| Max : constant Natural := Switch_Chars'Last; |
| Ptr : Natural; |
| C : Character := ' '; |
| Dot : Boolean; |
| |
| Store_Switch : Boolean; |
| -- For -gnatxx switches, the normal processing, signalled by this flag |
| -- being set to True, is to store the switch on exit from the case |
| -- statement, the switch stored is -gnat followed by the characters |
| -- from First_Char to Ptr-1. For cases like -gnaty, where the switch |
| -- is stored in separate pieces, this flag is set to False, and the |
| -- appropriate calls to Store_Compilation_Switch are made from within |
| -- the case branch. |
| |
| First_Char : Positive; |
| -- Marks start of switch to be stored |
| |
| First_Ptr : Positive; |
| -- Save position of first character after -gnatd (for checking that |
| -- debug flags that must come first are first, in particular -gnatd.b), |
| |
| begin |
| Ptr := Switch_Chars'First; |
| |
| -- Skip past the initial character (must be the switch character) |
| |
| if Ptr = Max then |
| Bad_Switch (C); |
| else |
| Ptr := Ptr + 1; |
| end if; |
| |
| -- Handle switches that do not start with -gnat |
| |
| if Ptr + 3 > Max or else Switch_Chars (Ptr .. Ptr + 3) /= "gnat" then |
| |
| -- There are two front-end switches that do not start with -gnat: |
| -- -I, --RTS |
| |
| if Switch_Chars (Ptr) = 'I' then |
| |
| -- Set flag Search_Directory_Present if switch is "-I" only: |
| -- the directory will be the next argument. |
| |
| if Ptr = Max then |
| Search_Directory_Present := True; |
| return; |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| -- Find out whether this is a -I- or regular -Ixxx switch |
| |
| -- Note: -I switches are not recorded in the ALI file, since the |
| -- meaning of the program depends on the source files compiled, |
| -- not where they came from. |
| |
| if Ptr = Max and then Switch_Chars (Ptr) = '-' then |
| Look_In_Primary_Dir := False; |
| else |
| Add_Src_Search_Dir (Switch_Chars (Ptr .. Max)); |
| end if; |
| |
| -- Processing of the --RTS switch. --RTS may have been modified by |
| -- gcc into -fRTS (for GCC targets). |
| |
| elsif Ptr + 3 <= Max |
| and then (Switch_Chars (Ptr .. Ptr + 3) = "fRTS" |
| or else |
| Switch_Chars (Ptr .. Ptr + 3) = "-RTS") |
| then |
| Ptr := Ptr + 1; |
| |
| if Ptr + 4 > Max |
| or else Switch_Chars (Ptr + 3) /= '=' |
| then |
| Osint.Fail ("missing path for --RTS"); |
| |
| else |
| declare |
| Runtime_Dir : String_Access; |
| begin |
| if System.OS_Lib.Is_Absolute_Path |
| (Switch_Chars (Ptr + 4 .. Max)) |
| then |
| Runtime_Dir := |
| new String'(System.OS_Lib.Normalize_Pathname |
| (Switch_Chars (Ptr + 4 .. Max))); |
| else |
| Runtime_Dir := |
| new String'(Switch_Chars (Ptr + 4 .. Max)); |
| end if; |
| |
| -- Valid --RTS switch |
| |
| Opt.No_Stdinc := True; |
| Opt.RTS_Switch := True; |
| |
| RTS_Src_Path_Name := |
| Get_RTS_Search_Dir (Runtime_Dir.all, Include); |
| |
| RTS_Lib_Path_Name := |
| Get_RTS_Search_Dir (Runtime_Dir.all, Objects); |
| |
| if RTS_Specified /= null then |
| if RTS_Src_Path_Name = null |
| or else RTS_Lib_Path_Name = null |
| or else |
| System.OS_Lib.Normalize_Pathname |
| (RTS_Specified.all) /= |
| System.OS_Lib.Normalize_Pathname |
| (RTS_Lib_Path_Name.all) |
| then |
| Osint.Fail |
| ("--RTS cannot be specified multiple times"); |
| end if; |
| |
| elsif RTS_Src_Path_Name /= null |
| and then RTS_Lib_Path_Name /= null |
| then |
| -- Store the -fRTS switch (Note: Store_Compilation_Switch |
| -- changes -fRTS back into --RTS for the actual output). |
| |
| Store_Compilation_Switch (Switch_Chars); |
| RTS_Specified := new String'(RTS_Lib_Path_Name.all); |
| |
| elsif RTS_Src_Path_Name = null |
| and then RTS_Lib_Path_Name = null |
| then |
| Osint.Fail ("RTS path not valid: missing " |
| & "adainclude and adalib directories"); |
| |
| elsif RTS_Src_Path_Name = null then |
| Osint.Fail ("RTS path not valid: missing " |
| & "adainclude directory"); |
| |
| elsif RTS_Lib_Path_Name = null then |
| Osint.Fail ("RTS path not valid: missing " |
| & "adalib directory"); |
| end if; |
| end; |
| end if; |
| |
| -- There are no other switches not starting with -gnat |
| |
| else |
| Bad_Switch (Switch_Chars); |
| end if; |
| |
| -- Case of switch starting with -gnat |
| |
| else |
| Ptr := Ptr + 4; |
| |
| -- Loop to scan through switches given in switch string |
| |
| while Ptr <= Max loop |
| First_Char := Ptr; |
| Store_Switch := True; |
| |
| C := Switch_Chars (Ptr); |
| |
| case C is |
| |
| -- -gnata (assertions enabled) |
| |
| when 'a' => |
| Ptr := Ptr + 1; |
| Assertions_Enabled := True; |
| |
| -- -gnatA (disregard gnat.adc) |
| |
| when 'A' => |
| Ptr := Ptr + 1; |
| Config_File := False; |
| |
| -- -gnatb (brief messages to stderr) |
| |
| when 'b' => |
| Ptr := Ptr + 1; |
| Brief_Output := True; |
| |
| -- -gnatB (assume no invalid values) |
| |
| when 'B' => |
| Ptr := Ptr + 1; |
| Assume_No_Invalid_Values := True; |
| |
| -- -gnatc (check syntax and semantics only) |
| |
| when 'c' => |
| if not First_Switch then |
| Osint.Fail |
| ("-gnatc must be first if combined with other switches"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| Operating_Mode := Check_Semantics; |
| |
| -- -gnatC (Generate CodePeer information) |
| |
| when 'C' => |
| Ptr := Ptr + 1; |
| |
| if not CodePeer_Mode then |
| CodePeer_Mode := True; |
| |
| -- Suppress compiler warnings by default, since what we are |
| -- interested in here is what CodePeer can find out. Note |
| -- that if -gnatwxxx is specified after -gnatC on the |
| -- command line, we do not want to override this setting in |
| -- Adjust_Global_Switches, and assume that the user wants to |
| -- get both warnings from GNAT and CodePeer messages. |
| |
| Warning_Mode := Suppress; |
| end if; |
| |
| -- -gnatd (compiler debug options) |
| |
| when 'd' => |
| Store_Switch := False; |
| Dot := False; |
| First_Ptr := Ptr + 1; |
| |
| -- Note: for the debug switch, the remaining characters in this |
| -- switch field must all be debug flags, since all valid switch |
| -- characters are also valid debug characters. |
| |
| -- Loop to scan out debug flags |
| |
| while Ptr < Max loop |
| Ptr := Ptr + 1; |
| C := Switch_Chars (Ptr); |
| exit when C = ASCII.NUL or else C = '/' or else C = '-'; |
| |
| if C in '1' .. '9' or else |
| C in 'a' .. 'z' or else |
| C in 'A' .. 'Z' |
| then |
| -- Case of dotted flag |
| |
| if Dot then |
| Set_Dotted_Debug_Flag (C); |
| Store_Compilation_Switch ("-gnatd." & C); |
| |
| -- Special check, -gnatd.b must come first |
| |
| if C = 'b' |
| and then (Ptr /= First_Ptr + 1 |
| or else not First_Switch) |
| then |
| Osint.Fail |
| ("-gnatd.b must be first if combined " |
| & "with other switches"); |
| end if; |
| |
| -- Not a dotted flag |
| |
| else |
| Set_Debug_Flag (C); |
| Store_Compilation_Switch ("-gnatd" & C); |
| end if; |
| |
| elsif C = '.' then |
| Dot := True; |
| |
| elsif Dot then |
| Bad_Switch ("-gnatd." & Switch_Chars (Ptr .. Max)); |
| else |
| Bad_Switch ("-gnatd" & Switch_Chars (Ptr .. Max)); |
| end if; |
| end loop; |
| |
| return; |
| |
| -- -gnatD (debug expanded code) |
| |
| when 'D' => |
| Ptr := Ptr + 1; |
| |
| -- Not allowed if previous -gnatR given |
| |
| -- The reason for this prohibition is that the rewriting of |
| -- Sloc values causes strange malfunctions in the tests of |
| -- whether units belong to the main source. This is really a |
| -- bug, but too hard to fix for a marginal capability ??? |
| |
| -- The proper fix is to completely redo -gnatD processing so |
| -- that the tree is not messed with, and instead a separate |
| -- table is built on the side for debug information generation. |
| |
| if List_Representation_Info /= 0 then |
| Osint.Fail |
| ("-gnatD not permitted since -gnatR given previously"); |
| end if; |
| |
| -- Scan optional integer line limit value |
| |
| if Nat_Present (Switch_Chars, Max, Ptr) then |
| Scan_Nat (Switch_Chars, Max, Ptr, Sprint_Line_Limit, 'D'); |
| Sprint_Line_Limit := Nat'Max (Sprint_Line_Limit, 40); |
| end if; |
| |
| -- Note: -gnatD also sets -gnatx (to turn off cross-reference |
| -- generation in the ali file) since otherwise this generation |
| -- gets confused by the "wrong" Sloc values put in the tree. |
| |
| Debug_Generated_Code := True; |
| Xref_Active := False; |
| Set_Debug_Flag ('g'); |
| |
| -- -gnate? (extended switches) |
| |
| when 'e' => |
| Ptr := Ptr + 1; |
| |
| -- The -gnate? switches are all double character switches |
| -- so we must always have a character after the e. |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnate"); |
| end if; |
| |
| case Switch_Chars (Ptr) is |
| |
| -- -gnatea (initial delimiter of explicit switches) |
| |
| -- This is an internal switch |
| |
| -- All switches that come before -gnatea have been added by |
| -- the GCC driver and are not stored in the ALI file. |
| -- See also -gnatez below. |
| |
| when 'a' => |
| Store_Switch := False; |
| Enable_Switch_Storing; |
| Ptr := Ptr + 1; |
| |
| -- -gnateA (aliasing checks on parameters) |
| |
| when 'A' => |
| Ptr := Ptr + 1; |
| Check_Aliasing_Of_Parameters := True; |
| |
| -- -gnatec (configuration pragmas) |
| |
| when 'c' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| -- There may be an equal sign between -gnatec and |
| -- the path name of the config file. |
| |
| if Ptr <= Max and then Switch_Chars (Ptr) = '=' then |
| Ptr := Ptr + 1; |
| end if; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatec"); |
| end if; |
| |
| declare |
| Config_File_Name : constant String_Access := |
| new String' |
| (Switch_Chars (Ptr .. Max)); |
| |
| begin |
| if Config_File_Names = null then |
| Config_File_Names := |
| new String_List'(1 => Config_File_Name); |
| |
| else |
| declare |
| New_Names : constant String_List_Access := |
| new String_List |
| (1 .. |
| Config_File_Names'Length + 1); |
| |
| begin |
| for Index in Config_File_Names'Range loop |
| New_Names (Index) := |
| Config_File_Names (Index); |
| Config_File_Names (Index) := null; |
| end loop; |
| |
| New_Names (New_Names'Last) := Config_File_Name; |
| Free (Config_File_Names); |
| Config_File_Names := New_Names; |
| end; |
| end if; |
| end; |
| |
| return; |
| |
| -- -gnateC switch (generate CodePeer messages) |
| |
| when 'C' => |
| Ptr := Ptr + 1; |
| Generate_CodePeer_Messages := True; |
| |
| -- -gnated switch (disable atomic synchronization) |
| |
| when 'd' => |
| Suppress_Options.Suppress (Atomic_Synchronization) := |
| True; |
| |
| -- -gnateD switch (preprocessing symbol definition) |
| |
| when 'D' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnateD"); |
| end if; |
| |
| Add_Symbol_Definition (Switch_Chars (Ptr .. Max)); |
| |
| -- Store the switch |
| |
| Store_Compilation_Switch |
| ("-gnateD" & Switch_Chars (Ptr .. Max)); |
| Ptr := Max + 1; |
| |
| -- -gnateE (extra exception information) |
| |
| when 'E' => |
| Exception_Extra_Info := True; |
| Ptr := Ptr + 1; |
| |
| -- -gnatef (full source path for brief error messages) |
| |
| when 'f' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| Full_Path_Name_For_Brief_Errors := True; |
| |
| -- -gnateF (Check_Float_Overflow) |
| |
| when 'F' => |
| Ptr := Ptr + 1; |
| Check_Float_Overflow := not Machine_Overflows_On_Target; |
| |
| -- -gnateG (save preprocessor output) |
| |
| when 'G' => |
| Generate_Processed_File := True; |
| Ptr := Ptr + 1; |
| |
| -- -gnatei (max number of instantiations) |
| |
| when 'i' => |
| Ptr := Ptr + 1; |
| Scan_Pos |
| (Switch_Chars, Max, Ptr, Maximum_Instantiations, C); |
| |
| -- -gnateI (index of unit in multi-unit source) |
| |
| when 'I' => |
| Ptr := Ptr + 1; |
| Scan_Pos (Switch_Chars, Max, Ptr, Multiple_Unit_Index, C); |
| |
| -- -gnatel |
| |
| when 'l' => |
| Ptr := Ptr + 1; |
| Elab_Info_Messages := True; |
| |
| -- -gnateL |
| |
| when 'L' => |
| Ptr := Ptr + 1; |
| Elab_Info_Messages := False; |
| |
| -- -gnatem (mapping file) |
| |
| when 'm' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| -- There may be an equal sign between -gnatem and |
| -- the path name of the mapping file. |
| |
| if Ptr <= Max and then Switch_Chars (Ptr) = '=' then |
| Ptr := Ptr + 1; |
| end if; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatem"); |
| end if; |
| |
| Mapping_File_Name := |
| new String'(Switch_Chars (Ptr .. Max)); |
| return; |
| |
| -- -gnateO= (object path file) |
| |
| -- This is an internal switch |
| |
| when 'O' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| -- Check for '=' |
| |
| if Ptr >= Max or else Switch_Chars (Ptr) /= '=' then |
| Bad_Switch ("-gnateO"); |
| else |
| Object_Path_File_Name := |
| new String'(Switch_Chars (Ptr + 1 .. Max)); |
| end if; |
| |
| return; |
| |
| -- -gnatep (preprocessing data file) |
| |
| when 'p' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| -- There may be an equal sign between -gnatep and |
| -- the path name of the mapping file. |
| |
| if Ptr <= Max and then Switch_Chars (Ptr) = '=' then |
| Ptr := Ptr + 1; |
| end if; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatep"); |
| end if; |
| |
| Preprocessing_Data_File := |
| new String'(Switch_Chars (Ptr .. Max)); |
| |
| -- Store the switch, normalizing to -gnatep= |
| |
| Store_Compilation_Switch |
| ("-gnatep=" & Preprocessing_Data_File.all); |
| |
| Ptr := Max + 1; |
| |
| -- -gnateP (Treat pragma Pure/Preelaborate errs as warnings) |
| |
| when 'P' => |
| Treat_Categorization_Errors_As_Warnings := True; |
| |
| -- -gnates=file (specify extra file switches for gnat2why) |
| |
| -- This is an internal switch |
| |
| when 's' => |
| if not First_Switch then |
| Osint.Fail |
| ("-gnates must not be combined with other switches"); |
| end if; |
| |
| -- Check for '=' |
| |
| Ptr := Ptr + 1; |
| |
| if Ptr >= Max or else Switch_Chars (Ptr) /= '=' then |
| Bad_Switch ("-gnates"); |
| else |
| SPARK_Switches_File_Name := |
| new String'(Switch_Chars (Ptr + 1 .. Max)); |
| end if; |
| |
| return; |
| |
| -- -gnateS (generate SCO information) |
| |
| -- Include Source Coverage Obligation information in ALI |
| -- files for use by source coverage analysis tools |
| -- (gnatcov) (equivalent to -fdump-scos, provided for |
| -- backwards compatibility). |
| |
| when 'S' => |
| Generate_SCO := True; |
| Generate_SCO_Instance_Table := True; |
| Ptr := Ptr + 1; |
| |
| -- -gnatet (write target dependent information) |
| |
| when 't' => |
| if not First_Switch then |
| Osint.Fail |
| ("-gnatet must not be combined with other switches"); |
| end if; |
| |
| -- Check for '=' |
| |
| Ptr := Ptr + 1; |
| |
| if Ptr >= Max or else Switch_Chars (Ptr) /= '=' then |
| Bad_Switch ("-gnatet"); |
| else |
| Target_Dependent_Info_Write_Name := |
| new String'(Switch_Chars (Ptr + 1 .. Max)); |
| end if; |
| |
| return; |
| |
| -- -gnateT (read target dependent information) |
| |
| when 'T' => |
| if not First_Switch then |
| Osint.Fail |
| ("-gnateT must not be combined with other switches"); |
| end if; |
| |
| -- Check for '=' |
| |
| Ptr := Ptr + 1; |
| |
| if Ptr >= Max or else Switch_Chars (Ptr) /= '=' then |
| Bad_Switch ("-gnateT"); |
| else |
| -- This parameter was stored by Set_Targ earlier |
| |
| pragma Assert |
| (Target_Dependent_Info_Read_Name.all = |
| Switch_Chars (Ptr + 1 .. Max)); |
| null; |
| end if; |
| |
| return; |
| |
| -- -gnateu (unrecognized y,V,w switches) |
| |
| when 'u' => |
| Ptr := Ptr + 1; |
| Ignore_Unrecognized_VWY_Switches := True; |
| |
| -- -gnateV (validity checks on parameters) |
| |
| when 'V' => |
| Ptr := Ptr + 1; |
| Check_Validity_Of_Parameters := True; |
| |
| -- -gnateY (ignore Style_Checks pragmas) |
| |
| when 'Y' => |
| Ignore_Style_Checks_Pragmas := True; |
| Ptr := Ptr + 1; |
| |
| -- -gnatez (final delimiter of explicit switches) |
| |
| -- This is an internal switch |
| |
| -- All switches that come after -gnatez have been added by |
| -- the GCC driver and are not stored in the ALI file. See |
| -- also -gnatea above. |
| |
| when 'z' => |
| Store_Switch := False; |
| Disable_Switch_Storing; |
| Ptr := Ptr + 1; |
| |
| -- All other -gnate? switches are unassigned |
| |
| when others => |
| Bad_Switch ("-gnate" & Switch_Chars (Ptr .. Max)); |
| end case; |
| |
| -- -gnatE (dynamic elaboration checks) |
| |
| when 'E' => |
| Ptr := Ptr + 1; |
| Dynamic_Elaboration_Checks := True; |
| |
| -- -gnatf (full error messages) |
| |
| when 'f' => |
| Ptr := Ptr + 1; |
| All_Errors_Mode := True; |
| |
| -- -gnatF (overflow of predefined float types) |
| |
| when 'F' => |
| Ptr := Ptr + 1; |
| External_Name_Exp_Casing := Uppercase; |
| External_Name_Imp_Casing := Uppercase; |
| |
| -- -gnatg (GNAT implementation mode) |
| |
| when 'g' => |
| Ptr := Ptr + 1; |
| GNAT_Mode := True; |
| GNAT_Mode_Config := True; |
| Identifier_Character_Set := 'n'; |
| System_Extend_Unit := Empty; |
| Warning_Mode := Treat_As_Error; |
| Style_Check_Main := True; |
| Ada_Version := Ada_2012; |
| Ada_Version_Explicit := Ada_2012; |
| Ada_Version_Pragma := Empty; |
| |
| -- Set default warnings and style checks for -gnatg |
| |
| Set_GNAT_Mode_Warnings; |
| Set_GNAT_Style_Check_Options; |
| |
| -- -gnatG (output generated code) |
| |
| when 'G' => |
| Ptr := Ptr + 1; |
| Print_Generated_Code := True; |
| |
| -- Scan optional integer line limit value |
| |
| if Nat_Present (Switch_Chars, Max, Ptr) then |
| Scan_Nat (Switch_Chars, Max, Ptr, Sprint_Line_Limit, 'G'); |
| Sprint_Line_Limit := Nat'Max (Sprint_Line_Limit, 40); |
| end if; |
| |
| -- -gnath (help information) |
| |
| when 'h' => |
| Ptr := Ptr + 1; |
| Usage_Requested := True; |
| |
| -- -gnati (character set) |
| |
| when 'i' => |
| if Ptr = Max then |
| Bad_Switch ("-gnati"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| C := Switch_Chars (Ptr); |
| |
| if C in '1' .. '5' |
| or else C = '8' |
| or else C = '9' |
| or else C = 'p' |
| or else C = 'f' |
| or else C = 'n' |
| or else C = 'w' |
| then |
| Identifier_Character_Set := C; |
| Ptr := Ptr + 1; |
| |
| else |
| Bad_Switch ("-gnati" & Switch_Chars (Ptr .. Max)); |
| end if; |
| |
| -- -gnatI (ignore representation clauses) |
| |
| when 'I' => |
| Ptr := Ptr + 1; |
| Ignore_Rep_Clauses := True; |
| |
| -- -gnatj (messages in limited length lines) |
| |
| when 'j' => |
| Ptr := Ptr + 1; |
| Scan_Nat (Switch_Chars, Max, Ptr, Error_Msg_Line_Length, C); |
| |
| -- -gnatk (limit file name length) |
| |
| when 'k' => |
| Ptr := Ptr + 1; |
| Scan_Pos |
| (Switch_Chars, Max, Ptr, Maximum_File_Name_Length, C); |
| |
| -- -gnatl (output full source) |
| |
| when 'l' => |
| Ptr := Ptr + 1; |
| Full_List := True; |
| |
| -- There may be an equal sign between -gnatl and a file name |
| |
| if Ptr <= Max and then Switch_Chars (Ptr) = '=' then |
| if Ptr = Max then |
| Osint.Fail ("file name for -gnatl= is null"); |
| else |
| Opt.Full_List_File_Name := |
| new String'(Switch_Chars (Ptr + 1 .. Max)); |
| Ptr := Max + 1; |
| end if; |
| end if; |
| |
| -- -gnatL (corresponding source text) |
| |
| when 'L' => |
| Ptr := Ptr + 1; |
| Dump_Source_Text := True; |
| |
| -- -gnatm (max number or errors/warnings) |
| |
| when 'm' => |
| Ptr := Ptr + 1; |
| Scan_Nat (Switch_Chars, Max, Ptr, Maximum_Messages, C); |
| |
| -- -gnatn (enable pragma Inline) |
| |
| when 'n' => |
| Ptr := Ptr + 1; |
| Inline_Active := True; |
| |
| -- There may be a digit (1 or 2) appended to the switch |
| |
| if Ptr <= Max then |
| C := Switch_Chars (Ptr); |
| |
| if C in '1' .. '2' then |
| Ptr := Ptr + 1; |
| Inline_Level := Character'Pos (C) - Character'Pos ('0'); |
| end if; |
| end if; |
| |
| -- -gnatN (obsolescent) |
| |
| when 'N' => |
| Ptr := Ptr + 1; |
| Inline_Active := True; |
| Front_End_Inlining := True; |
| |
| -- -gnato (overflow checks) |
| |
| when 'o' => |
| Ptr := Ptr + 1; |
| |
| -- Case of -gnato0 (overflow checking turned off) |
| |
| if Ptr <= Max and then Switch_Chars (Ptr) = '0' then |
| Ptr := Ptr + 1; |
| Suppress_Options.Suppress (Overflow_Check) := True; |
| |
| -- We set strict mode in case overflow checking is turned |
| -- on locally (also records that we had a -gnato switch). |
| |
| Suppress_Options.Overflow_Mode_General := Strict; |
| Suppress_Options.Overflow_Mode_Assertions := Strict; |
| |
| -- All cases other than -gnato0 (overflow checking turned on) |
| |
| else |
| Suppress_Options.Suppress (Overflow_Check) := False; |
| |
| -- Case of no digits after the -gnato |
| |
| if Ptr > Max |
| or else Switch_Chars (Ptr) not in '1' .. '3' |
| then |
| Suppress_Options.Overflow_Mode_General := Strict; |
| Suppress_Options.Overflow_Mode_Assertions := Strict; |
| |
| -- At least one digit after the -gnato |
| |
| else |
| -- Handle first digit after -gnato |
| |
| Suppress_Options.Overflow_Mode_General := |
| Get_Overflow_Mode (Switch_Chars (Ptr)); |
| Ptr := Ptr + 1; |
| |
| -- Only one digit after -gnato, set assertions mode to be |
| -- the same as general mode. |
| |
| if Ptr > Max |
| or else Switch_Chars (Ptr) not in '1' .. '3' |
| then |
| Suppress_Options.Overflow_Mode_Assertions := |
| Suppress_Options.Overflow_Mode_General; |
| |
| -- Process second digit after -gnato |
| |
| else |
| Suppress_Options.Overflow_Mode_Assertions := |
| Get_Overflow_Mode (Switch_Chars (Ptr)); |
| Ptr := Ptr + 1; |
| end if; |
| end if; |
| end if; |
| |
| -- -gnatO (specify name of the object file) |
| |
| -- This is an internal switch |
| |
| when 'O' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| Output_File_Name_Present := True; |
| |
| -- -gnatp (suppress all checks) |
| |
| when 'p' => |
| Ptr := Ptr + 1; |
| |
| -- Skip processing if cancelled by subsequent -gnat-p |
| |
| if Switch_Subsequently_Cancelled ("p", Args, Arg_Rank) then |
| Store_Switch := False; |
| |
| else |
| -- Set all specific options as well as All_Checks in the |
| -- Suppress_Options array, excluding Elaboration_Check, |
| -- since this is treated specially because we do not want |
| -- -gnatp to disable static elaboration processing. Also |
| -- exclude Atomic_Synchronization, since this is not a real |
| -- check. |
| |
| for J in Suppress_Options.Suppress'Range loop |
| if J /= Elaboration_Check |
| and then |
| J /= Atomic_Synchronization |
| then |
| Suppress_Options.Suppress (J) := True; |
| end if; |
| end loop; |
| |
| Validity_Checks_On := False; |
| Opt.Suppress_Checks := True; |
| |
| -- Set overflow mode checking to strict in case it gets |
| -- turned on locally (also signals that overflow checking |
| -- has been specifically turned off). |
| |
| Suppress_Options.Overflow_Mode_General := Strict; |
| Suppress_Options.Overflow_Mode_Assertions := Strict; |
| end if; |
| |
| -- -gnatP (periodic poll) |
| |
| when 'P' => |
| Ptr := Ptr + 1; |
| Polling_Required := True; |
| |
| -- -gnatq (don't quit) |
| |
| when 'q' => |
| Ptr := Ptr + 1; |
| Try_Semantics := True; |
| |
| -- -gnatQ (always write ALI file) |
| |
| when 'Q' => |
| Ptr := Ptr + 1; |
| Force_ALI_Tree_File := True; |
| Try_Semantics := True; |
| |
| -- -gnatr (restrictions as warnings) |
| |
| when 'r' => |
| Ptr := Ptr + 1; |
| Treat_Restrictions_As_Warnings := True; |
| |
| -- -gnatR (list rep. info) |
| |
| when 'R' => |
| |
| -- Not allowed if previous -gnatD given. See more extensive |
| -- comments in the 'D' section for the inverse test. |
| |
| if Debug_Generated_Code then |
| Osint.Fail |
| ("-gnatR not permitted since -gnatD given previously"); |
| end if; |
| |
| -- Set to annotate rep info, and set default -gnatR mode |
| |
| Back_Annotate_Rep_Info := True; |
| List_Representation_Info := 1; |
| |
| -- Scan possible parameter |
| |
| Ptr := Ptr + 1; |
| while Ptr <= Max loop |
| C := Switch_Chars (Ptr); |
| |
| if C in '1' .. '3' then |
| List_Representation_Info := |
| Character'Pos (C) - Character'Pos ('0'); |
| |
| elsif Switch_Chars (Ptr) = 's' then |
| List_Representation_Info_To_File := True; |
| |
| elsif Switch_Chars (Ptr) = 'm' then |
| List_Representation_Info_Mechanisms := True; |
| |
| else |
| Bad_Switch ("-gnatR" & Switch_Chars (Ptr .. Max)); |
| end if; |
| |
| Ptr := Ptr + 1; |
| end loop; |
| |
| -- -gnats (syntax check only) |
| |
| when 's' => |
| if not First_Switch then |
| Osint.Fail |
| ("-gnats must be first if combined with other switches"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| Operating_Mode := Check_Syntax; |
| |
| -- -gnatS (print package Standard) |
| |
| when 'S' => |
| Print_Standard := True; |
| Ptr := Ptr + 1; |
| |
| -- -gnatt (output tree) |
| |
| when 't' => |
| Ptr := Ptr + 1; |
| Tree_Output := True; |
| Back_Annotate_Rep_Info := True; |
| |
| -- -gnatT (change start of internal table sizes) |
| |
| when 'T' => |
| Ptr := Ptr + 1; |
| Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor, C); |
| |
| -- -gnatu (list units for compilation) |
| |
| when 'u' => |
| Ptr := Ptr + 1; |
| List_Units := True; |
| |
| -- -gnatU (unique tags) |
| |
| when 'U' => |
| Ptr := Ptr + 1; |
| Unique_Error_Tag := True; |
| |
| -- -gnatv (verbose mode) |
| |
| when 'v' => |
| Ptr := Ptr + 1; |
| Verbose_Mode := True; |
| |
| -- -gnatV (validity checks) |
| |
| when 'V' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatV"); |
| |
| else |
| declare |
| OK : Boolean; |
| |
| begin |
| Set_Validity_Check_Options |
| (Switch_Chars (Ptr .. Max), OK, Ptr); |
| |
| if not OK then |
| Bad_Switch ("-gnatV" & Switch_Chars (Ptr .. Max)); |
| end if; |
| |
| for Index in First_Char + 1 .. Max loop |
| Store_Compilation_Switch |
| ("-gnatV" & Switch_Chars (Index)); |
| end loop; |
| end; |
| end if; |
| |
| Ptr := Max + 1; |
| |
| -- -gnatw (warning modes) |
| |
| when 'w' => |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatw"); |
| end if; |
| |
| while Ptr <= Max loop |
| C := Switch_Chars (Ptr); |
| |
| -- Case of dot switch |
| |
| if C = '.' and then Ptr < Max then |
| Ptr := Ptr + 1; |
| C := Switch_Chars (Ptr); |
| |
| if Set_Dot_Warning_Switch (C) then |
| Store_Compilation_Switch ("-gnatw." & C); |
| else |
| Bad_Switch ("-gnatw." & Switch_Chars (Ptr .. Max)); |
| end if; |
| |
| -- Normal case, no dot |
| |
| else |
| if Set_Warning_Switch (C) then |
| Store_Compilation_Switch ("-gnatw" & C); |
| else |
| Bad_Switch ("-gnatw" & Switch_Chars (Ptr .. Max)); |
| end if; |
| end if; |
| |
| Ptr := Ptr + 1; |
| end loop; |
| |
| return; |
| |
| -- -gnatW (wide character encoding method) |
| |
| when 'W' => |
| Ptr := Ptr + 1; |
| |
| if Ptr > Max then |
| Bad_Switch ("-gnatW"); |
| end if; |
| |
| begin |
| Wide_Character_Encoding_Method := |
| Get_WC_Encoding_Method (Switch_Chars (Ptr)); |
| exception |
| when Constraint_Error => |
| Bad_Switch ("-gnatW" & Switch_Chars (Ptr .. Max)); |
| end; |
| |
| Wide_Character_Encoding_Method_Specified := True; |
| |
| Upper_Half_Encoding := |
| Wide_Character_Encoding_Method in |
| WC_Upper_Half_Encoding_Method; |
| |
| Ptr := Ptr + 1; |
| |
| -- -gnatx (suppress cross-ref information) |
| |
| when 'x' => |
| Ptr := Ptr + 1; |
| Xref_Active := False; |
| |
| -- -gnatX (language extensions) |
| |
| when 'X' => |
| Ptr := Ptr + 1; |
| Extensions_Allowed := True; |
| Ada_Version := Ada_Version_Type'Last; |
| Ada_Version_Explicit := Ada_Version_Type'Last; |
| Ada_Version_Pragma := Empty; |
| |
| -- -gnaty (style checks) |
| |
| when 'y' => |
| Ptr := Ptr + 1; |
| Style_Check_Main := True; |
| |
| if Ptr > Max then |
| Set_Default_Style_Check_Options; |
| |
| else |
| Store_Switch := False; |
| |
| declare |
| OK : Boolean; |
| |
| begin |
| Set_Style_Check_Options |
| (Switch_Chars (Ptr .. Max), OK, Ptr); |
| |
| if not OK then |
| Osint.Fail |
| ("bad -gnaty switch (" & |
| Style_Msg_Buf (1 .. Style_Msg_Len) & ')'); |
| end if; |
| |
| Ptr := First_Char + 1; |
| while Ptr <= Max loop |
| if Switch_Chars (Ptr) = 'M' then |
| First_Char := Ptr; |
| loop |
| Ptr := Ptr + 1; |
| exit when Ptr > Max |
| or else Switch_Chars (Ptr) not in '0' .. '9'; |
| end loop; |
| |
| Store_Compilation_Switch |
| ("-gnaty" & Switch_Chars (First_Char .. Ptr - 1)); |
| |
| else |
| Store_Compilation_Switch |
| ("-gnaty" & Switch_Chars (Ptr)); |
| Ptr := Ptr + 1; |
| end if; |
| end loop; |
| end; |
| end if; |
| |
| -- -gnatz (stub generation) |
| |
| when 'z' => |
| |
| -- -gnatz must be the first and only switch in Switch_Chars, |
| -- and is a two-letter switch. |
| |
| if Ptr /= Switch_Chars'First + 5 |
| or else (Max - Ptr + 1) > 2 |
| then |
| Osint.Fail |
| ("-gnatz* may not be combined with other switches"); |
| end if; |
| |
| if Ptr = Max then |
| Bad_Switch ("-gnatz"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| -- Only one occurrence of -gnat* is permitted |
| |
| if Distribution_Stub_Mode = No_Stubs then |
| case Switch_Chars (Ptr) is |
| when 'r' => |
| Distribution_Stub_Mode := Generate_Receiver_Stub_Body; |
| |
| when 'c' => |
| Distribution_Stub_Mode := Generate_Caller_Stub_Body; |
| |
| when others => |
| Bad_Switch ("-gnatz" & Switch_Chars (Ptr .. Max)); |
| end case; |
| |
| Ptr := Ptr + 1; |
| |
| else |
| Osint.Fail ("only one -gnatz* switch allowed"); |
| end if; |
| |
| -- -gnatZ (obsolescent) |
| |
| when 'Z' => |
| Ptr := Ptr + 1; |
| Osint.Fail |
| ("-gnatZ is no longer supported: consider using --RTS=zcx"); |
| |
| -- Note on language version switches: whenever a new language |
| -- version switch is added, Switch.M.Normalize_Compiler_Switches |
| -- must be updated. |
| |
| -- -gnat83 |
| |
| when '8' => |
| if Ptr = Max then |
| Bad_Switch ("-gnat8"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| if Switch_Chars (Ptr) /= '3' then |
| Bad_Switch ("-gnat8" & Switch_Chars (Ptr .. Max)); |
| else |
| Ptr := Ptr + 1; |
| Ada_Version := Ada_83; |
| Ada_Version_Explicit := Ada_83; |
| Ada_Version_Pragma := Empty; |
| end if; |
| |
| -- -gnat95 |
| |
| when '9' => |
| if Ptr = Max then |
| Bad_Switch ("-gnat9"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| if Switch_Chars (Ptr) /= '5' then |
| Bad_Switch ("-gnat9" & Switch_Chars (Ptr .. Max)); |
| else |
| Ptr := Ptr + 1; |
| Ada_Version := Ada_95; |
| Ada_Version_Explicit := Ada_95; |
| Ada_Version_Pragma := Empty; |
| end if; |
| |
| -- -gnat05 |
| |
| when '0' => |
| if Ptr = Max then |
| Bad_Switch ("-gnat0"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| if Switch_Chars (Ptr) /= '5' then |
| Bad_Switch ("-gnat0" & Switch_Chars (Ptr .. Max)); |
| else |
| Ptr := Ptr + 1; |
| Ada_Version := Ada_2005; |
| Ada_Version_Explicit := Ada_2005; |
| Ada_Version_Pragma := Empty; |
| end if; |
| |
| -- -gnat12 |
| |
| when '1' => |
| if Ptr = Max then |
| Bad_Switch ("-gnat1"); |
| end if; |
| |
| Ptr := Ptr + 1; |
| |
| if Switch_Chars (Ptr) /= '2' then |
| Bad_Switch ("-gnat1" & Switch_Chars (Ptr .. Max)); |
| else |
| Ptr := Ptr + 1; |
| Ada_Version := Ada_2012; |
| Ada_Version_Explicit := Ada_2012; |
| Ada_Version_Pragma := Empty; |
| end if; |
| |
| -- -gnat2005 and -gnat2012 |
| |
| when '2' => |
| if Ptr > Max - 3 then |
| Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Max)); |
| |
| elsif Switch_Chars (Ptr .. Ptr + 3) = "2005" then |
| Ada_Version := Ada_2005; |
| |
| elsif Switch_Chars (Ptr .. Ptr + 3) = "2012" then |
| Ada_Version := Ada_2012; |
| |
| else |
| Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Ptr + 3)); |
| end if; |
| |
| Ada_Version_Explicit := Ada_Version; |
| Ada_Version_Pragma := Empty; |
| Ptr := Ptr + 4; |
| |
| -- Switch cancellation, currently only -gnat-p is allowed. |
| -- All we do here is the error checking, since the actual |
| -- processing for switch cancellation is done by calls to |
| -- Switch_Subsequently_Cancelled at the appropriate point. |
| |
| when '-' => |
| |
| -- Simple ignore -gnat-p |
| |
| if Switch_Chars = "-gnat-p" then |
| return; |
| |
| -- Any other occurrence of minus is ignored. This is for |
| -- maximum compatibility with previous version which ignored |
| -- all occurrences of minus. |
| |
| else |
| Store_Switch := False; |
| Ptr := Ptr + 1; |
| end if; |
| |
| -- We ignore '/' in switches, this is historical, still needed??? |
| |
| when '/' => |
| Store_Switch := False; |
| |
| -- Anything else is an error (illegal switch character) |
| |
| when others => |
| Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Max)); |
| end case; |
| |
| if Store_Switch then |
| Store_Compilation_Switch |
| ("-gnat" & Switch_Chars (First_Char .. Ptr - 1)); |
| end if; |
| |
| First_Switch := False; |
| end loop; |
| end if; |
| end Scan_Front_End_Switches; |
| |
| ----------------------------------- |
| -- Switch_Subsequently_Cancelled -- |
| ----------------------------------- |
| |
| function Switch_Subsequently_Cancelled |
| (C : String; |
| Args : String_List; |
| Arg_Rank : Positive) return Boolean |
| is |
| begin |
| -- Loop through arguments following the current one |
| |
| for Arg in Arg_Rank + 1 .. Args'Last loop |
| if Args (Arg).all = "-gnat-" & C then |
| return True; |
| end if; |
| end loop; |
| |
| -- No match found, not cancelled |
| |
| return False; |
| end Switch_Subsequently_Cancelled; |
| |
| end Switch.C; |