OSDN Git Service

* parser.c (cp_parser_class_specifier): Set class location to that
[pf3gnuchains/gcc-fork.git] / gcc / ada / switch-c.adb
index 837be56..7b19410 100644 (file)
@@ -6,35 +6,34 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2003 Free Software Foundation, Inc.          --
+--          Copyright (C) 2001-2009, 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 2,  or (at your option) any later ver- --
+-- 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 COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- 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.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with GNAT.OS_Lib; use GNAT.OS_Lib;
-
 with Debug;    use Debug;
 with Lib;      use Lib;
 with Osint;    use Osint;
 with Opt;      use Opt;
 with Prepcomp; use Prepcomp;
-with Types;    use Types;
 with Validsw;  use Validsw;
+with Sem_Warn; use Sem_Warn;
 with Stylesw;  use Stylesw;
 
+with System.OS_Lib; use System.OS_Lib;
+
 with System.WCh_Con; use System.WCh_Con;
 
 package body Switch.C is
@@ -47,159 +46,158 @@ package body Switch.C is
    -----------------------------
 
    procedure Scan_Front_End_Switches (Switch_Chars : String) is
-      Switch_Starts_With_Gnat : Boolean;
-      --  True if first four switch characters are "gnat"
-
       First_Switch : Boolean := True;
       --  False for all but first switch
 
-      Ptr : Integer := Switch_Chars'First;
-      Max : constant Integer := Switch_Chars'Last;
+      Max : constant Natural := Switch_Chars'Last;
+      Ptr : Natural;
       C   : Character := ' ';
       Dot : Boolean;
 
-      Store_Switch : Boolean  := True;
-      First_Char   : Integer  := Ptr;
-      Storing      : String   := Switch_Chars;
-      First_Stored : Positive := Ptr + 1;
-      --  The above need comments ???
+      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
 
    begin
+      Ptr := Switch_Chars'First;
+
       --  Skip past the initial character (must be the switch character)
 
       if Ptr = Max then
-         raise Bad_Switch;
+         Bad_Switch (C);
       else
          Ptr := Ptr + 1;
       end if;
 
-      --  Remove "gnat" from the switch, if present
+      --  Handle switches that do not start with -gnat
 
-      Switch_Starts_With_Gnat :=
-        Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "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_Starts_With_Gnat then
-         Ptr := Ptr + 4;
-         First_Stored := Ptr;
-      end if;
+         if Switch_Chars (Ptr) = 'I' then
 
-      --  Loop to scan through switches given in switch string
+            --  Set flag Search_Directory_Present if switch is "-I" only:
+            --  the directory will be the next argument.
 
-      while Ptr <= Max loop
-         Store_Switch := True;
-         First_Char := Ptr;
-         C := Switch_Chars (Ptr);
-
-         --  Processing for a switch
+            if Ptr = Max then
+               Search_Directory_Present := True;
+               return;
+            end if;
 
-         case Switch_Starts_With_Gnat is
+            Ptr := Ptr + 1;
 
-            when False =>
+            --  Find out whether this is a -I- or regular -Ixxx switch
 
-            --  There are few front-end switches that
-            --  do not start with -gnat: -I, --RTS, -nostdlib
+            --  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 Switch_Chars (Ptr) = 'I' then
-                  Store_Switch := False;
+            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;
 
-                  Ptr := Ptr + 1;
+         --  Processing of the --RTS switch. --RTS may have been modified by
+         --  gcc into -fRTS (for GCC targets).
 
-                  if Ptr > Max then
-                     raise Bad_Switch;
-                  end if;
+         elsif Ptr + 3 <= Max
+           and then (Switch_Chars (Ptr .. Ptr + 3) = "fRTS"
+                       or else
+                     Switch_Chars (Ptr .. Ptr + 3) = "-RTS")
+         then
+            Ptr := Ptr + 1;
 
-                  --  Find out whether this is a -I- or regular -Ixxx switch
+            if Ptr + 4 > Max
+              or else Switch_Chars (Ptr + 3) /= '='
+            then
+               Osint.Fail ("missing path for --RTS");
+            else
+               --  Check that this is the first time --RTS is specified or if
+               --  it is not the first time, the same path has been specified.
 
-                  if Ptr = Max and then Switch_Chars (Ptr) = '-' then
-                     Look_In_Primary_Dir := False;
+               if RTS_Specified = null then
+                  RTS_Specified := new String'(Switch_Chars (Ptr + 4 .. Max));
 
-                  else
-                     Add_Src_Search_Dir (Switch_Chars (Ptr .. Max));
-                  end if;
+               elsif
+                 RTS_Specified.all /= Switch_Chars (Ptr + 4 .. Max)
+               then
+                  Osint.Fail ("--RTS cannot be specified multiple times");
+               end if;
 
-                  Ptr := Max + 1;
+               --  Valid --RTS switch
 
-               --  Processing of -nostdlib
+               Opt.No_Stdinc := True;
+               Opt.RTS_Switch := True;
 
-               elsif Ptr + 7 = Max
-                 and then Switch_Chars (Ptr .. Ptr + 7) = "nostdlib"
-               then
-                  Opt.No_Stdlib := True;
-                  Ptr := Max + 1;
+               RTS_Src_Path_Name :=
+                 Get_RTS_Search_Dir
+                   (Switch_Chars (Ptr + 4 .. Max), Include);
 
-               --  Processing of the --RTS switch. --RTS has been modified by
-               --  gcc and is now of the form -fRTS
+               RTS_Lib_Path_Name :=
+                 Get_RTS_Search_Dir
+                   (Switch_Chars (Ptr + 4 .. Max), Objects);
 
-               elsif Ptr + 3 <= Max
-                 and then Switch_Chars (Ptr .. Ptr + 3) = "fRTS"
+               if RTS_Src_Path_Name /= null
+                 and then RTS_Lib_Path_Name /= null
                then
-                  Ptr := Ptr + 1;
-
-                  if Ptr + 4 > Max
-                    or else Switch_Chars (Ptr + 3) /= '='
-                  then
-                     Osint.Fail ("missing path for --RTS");
-                  else
-                     --  Check that this is the first time --RTS is specified
-                     --  or if it is not the first time, the same path has
-                     --  been specified.
+                  --  Store the -fRTS switch (Note: Store_Compilation_Switch
+                  --  changes -fRTS back into --RTS for the actual output).
 
-                     if RTS_Specified = null then
-                        RTS_Specified :=
-                          new String'(Switch_Chars (Ptr + 4 .. Max));
+                  Store_Compilation_Switch (Switch_Chars);
 
-                     elsif
-                       RTS_Specified.all /= Switch_Chars (Ptr + 4 .. Max)
-                     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
+                  Osint.Fail ("RTS path not valid: missing " &
+                              "adainclude and adalib directories");
 
-                     --  Valid --RTS switch
+               elsif RTS_Src_Path_Name = null then
+                  Osint.Fail ("RTS path not valid: missing " &
+                              "adainclude directory");
 
-                     Opt.No_Stdinc := True;
-                     Opt.RTS_Switch := True;
+               elsif RTS_Lib_Path_Name = null then
+                  Osint.Fail ("RTS path not valid: missing " &
+                              "adalib directory");
+               end if;
+            end if;
 
-                     RTS_Src_Path_Name := Get_RTS_Search_Dir
-                                            (Switch_Chars (Ptr + 4 .. Max),
-                                             Include);
-                     RTS_Lib_Path_Name := Get_RTS_Search_Dir
-                                            (Switch_Chars (Ptr + 4 .. Max),
-                                             Objects);
+            --  There are no other switches not starting with -gnat
 
-                     if RTS_Src_Path_Name /= null and then
-                        RTS_Lib_Path_Name /= null
-                     then
-                        Ptr := Max + 1;
+         else
+            Bad_Switch (Switch_Chars);
+         end if;
 
-                     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");
+      --  Case of switch starting with -gnat
 
-                     elsif RTS_Src_Path_Name = null then
-                        Osint.Fail ("RTS path not valid: missing " &
-                                    "adainclude directory");
+      else
+         Ptr := Ptr + 4;
 
-                     elsif RTS_Lib_Path_Name = null then
-                        Osint.Fail ("RTS path not valid: missing " &
-                                    "adalib directory");
-                     end if;
-                  end if;
-               else
-                  raise Bad_Switch;
-               end if;
+         --  Loop to scan through switches given in switch string
 
-         when True =>
+         while Ptr <= Max loop
+            First_Char := Ptr;
+            Store_Switch := True;
 
-            --  Process -gnat* options
+            C := Switch_Chars (Ptr);
 
             case C is
 
             when 'a' =>
                Ptr := Ptr + 1;
                Assertions_Enabled := True;
+               Debug_Pragmas_Enabled := True;
 
             --  Processing for A switch
 
@@ -213,6 +211,12 @@ package body Switch.C is
                Ptr := Ptr + 1;
                Brief_Output := True;
 
+            --  Processing for B switch
+
+            when 'B' =>
+               Ptr := Ptr + 1;
+               Assume_No_Invalid_Values := True;
+
             --  Processing for c switch
 
             when 'c' =>
@@ -224,15 +228,16 @@ package body Switch.C is
                Ptr := Ptr + 1;
                Operating_Mode := Check_Semantics;
 
-               if Tree_Output then
-                  ASIS_Mode := True;
-               end if;
+            --  Processing for C switch
+
+            when 'C' =>
+               Ptr := Ptr + 1;
+               CodePeer_Mode := True;
 
             --  Processing for d switch
 
             when 'd' =>
                Store_Switch := False;
-               Storing (First_Stored) := 'd';
                Dot := False;
 
                --  Note: for the debug switch, the remaining characters in this
@@ -252,35 +257,22 @@ package body Switch.C is
                   then
                      if Dot then
                         Set_Dotted_Debug_Flag (C);
-                        Storing (First_Stored + 1) := '.';
-                        Storing (First_Stored + 2) := C;
-                        Store_Compilation_Switch
-                          (Storing (Storing'First .. First_Stored + 2));
-                        Dot := False;
-
+                        Store_Compilation_Switch ("-gnatd." & C);
                      else
                         Set_Debug_Flag (C);
-                        Storing (First_Stored + 1) := C;
-                        Store_Compilation_Switch
-                          (Storing (Storing'First .. First_Stored + 1));
+                        Store_Compilation_Switch ("-gnatd" & C);
                      end if;
 
                   elsif C = '.' then
                      Dot := True;
 
+                  elsif Dot then
+                     Bad_Switch ("-gnatd." & Switch_Chars (Ptr .. Max));
                   else
-                     raise Bad_Switch;
+                     Bad_Switch ("-gnatd" & Switch_Chars (Ptr .. Max));
                   end if;
                end loop;
 
-               --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
-               --  is for backwards compatibility with old versions and usage.
-
-               if Debug_Flag_XX then
-                  Zero_Cost_Exceptions_Set := True;
-                  Zero_Cost_Exceptions_Val := True;
-               end if;
-
                return;
 
             --  Processing for D switch
@@ -288,6 +280,13 @@ package body Switch.C is
             when 'D' =>
                Ptr := Ptr + 1;
 
+               --  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.
@@ -305,11 +304,22 @@ package body Switch.C is
                --  so we must always have a character after the e.
 
                if Ptr > Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnate");
                end if;
 
                case Switch_Chars (Ptr) is
 
+                  --  -gnatea (initial delimiter of explicit switches)
+
+                  --  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;
+
                   --  -gnatec (configuration pragmas)
 
                   when 'c' =>
@@ -324,7 +334,7 @@ package body Switch.C is
                      end if;
 
                      if Ptr > Max then
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnatec");
                      end if;
 
                      declare
@@ -360,27 +370,32 @@ package body Switch.C is
 
                      return;
 
-                  --  -gnateD switch (symbol definition)
+                  --  -gnateC switch (CodePeer SCIL generation)
+
+                  --  Not enabled for now, keep it for later???
+                  --  use -gnatd.I only for now
+
+                  --  when 'C' =>
+                  --     Ptr := Ptr + 1;
+                  --     Generate_SCIL := True;
+
+                  --  -gnateD switch (preprocessing symbol definition)
 
                   when 'D' =>
                      Store_Switch := False;
                      Ptr := Ptr + 1;
 
                      if Ptr > Max then
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnateD");
                      end if;
 
                      Add_Symbol_Definition (Switch_Chars (Ptr .. Max));
 
                      --  Store the switch
 
-                     Storing (First_Stored .. First_Stored + 1) := "eD";
-                     Storing
-                       (First_Stored + 2 .. First_Stored + Max - Ptr + 2) :=
-                       Switch_Chars (Ptr .. Max);
-                     Store_Compilation_Switch (Storing
-                              (Storing'First .. First_Stored + Max - Ptr + 2));
-                     return;
+                     Store_Compilation_Switch
+                       ("-gnateD" & Switch_Chars (Ptr .. Max));
+                     Ptr := Max + 1;
 
                   --  -gnatef (full source path for brief error messages)
 
@@ -388,7 +403,18 @@ package body Switch.C is
                      Store_Switch := False;
                      Ptr := Ptr + 1;
                      Full_Path_Name_For_Brief_Errors := True;
-                     return;
+
+                  --  -gnateG (save preprocessor output)
+
+                  when 'G' =>
+                     Generate_Processed_File := True;
+                     Ptr := Ptr + 1;
+
+                  --  -gnateI (index of unit in multi-unit source)
+
+                  when 'I' =>
+                     Ptr := Ptr + 1;
+                     Scan_Pos (Switch_Chars, Max, Ptr, Multiple_Unit_Index, C);
 
                   --  -gnatem (mapping file)
 
@@ -404,7 +430,7 @@ package body Switch.C is
                      end if;
 
                      if Ptr > Max then
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnatem");
                      end if;
 
                      Mapping_File_Name :=
@@ -425,33 +451,44 @@ package body Switch.C is
                      end if;
 
                      if Ptr > Max then
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnatep");
                      end if;
 
                      Preprocessing_Data_File :=
                        new String'(Switch_Chars (Ptr .. Max));
 
-                     --  Store the switch.
-                     --  Because we may store a longer switch (we normalize
-                     --  to -gnatep=), use a local variable.
+                     --  Store the switch, normalizing to -gnatep=
 
-                     declare
-                        To_Store : String
-                          (1 .. Preprocessing_Data_File'Length + 8);
+                     Store_Compilation_Switch
+                       ("-gnatep=" & Preprocessing_Data_File.all);
 
-                     begin
-                        To_Store (1 .. 8) := "-gnatep=";
-                        To_Store (9 .. Preprocessing_Data_File'Length + 8) :=
-                          Preprocessing_Data_File.all;
-                        Store_Compilation_Switch (To_Store);
-                     end;
+                     Ptr := Max + 1;
+
+                  --  -gnatez (final delimiter of explicit switches)
+
+                  --  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;
+
+                  --  -gnateS (generate SCO information)
+
+                  --  Include Source Coverage Obligation information in ALI
+                  --  files for the benefit of source coverage analysis tools
+                  --  (xcov).
 
-                  return;
+                  when 'S' =>
+                     Generate_SCO := True;
+                     Ptr := Ptr + 1;
 
                   --  All other -gnate? switches are unassigned
 
                   when others =>
-                     raise Bad_Switch;
+                     Bad_Switch ("-gnate" & Switch_Chars (Ptr .. Max));
                end case;
 
             --  -gnatE (dynamic elaboration checks)
@@ -477,15 +514,22 @@ package body Switch.C is
 
             when 'g' =>
                Ptr := Ptr + 1;
-               GNAT_Mode                  := True;
-               Identifier_Character_Set   := 'n';
-               Warning_Mode               := Treat_As_Error;
-               Check_Unreferenced         := True;
-               Check_Withs                := True;
-               Check_Unreferenced_Formals := True;
-               System_Extend_Unit         := Empty;
+               GNAT_Mode := True;
+               Identifier_Character_Set := 'n';
+               System_Extend_Unit := Empty;
+               Warning_Mode := Treat_As_Error;
+
+               --  Set Ada 2005 mode explicitly. We don't want to rely on the
+               --  implicit setting here, since for example, we want
+               --  Preelaborate_05 treated as Preelaborate
+
+               Ada_Version := Ada_05;
+               Ada_Version_Explicit := Ada_Version;
+
+               --  Set default warnings and style checks for -gnatg
 
-               Set_Default_Style_Check_Options;
+               Set_GNAT_Mode_Warnings;
+               Set_GNAT_Style_Check_Options;
 
             --  Processing for G switch
 
@@ -493,6 +537,13 @@ package body Switch.C is
                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;
+
             --  Processing for h switch
 
             when 'h' =>
@@ -509,7 +560,7 @@ package body Switch.C is
 
             when 'i' =>
                if Ptr = Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnati");
                end if;
 
                Ptr := Ptr + 1;
@@ -527,14 +578,27 @@ package body Switch.C is
                   Ptr := Ptr + 1;
 
                else
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnati" & Switch_Chars (Ptr .. Max));
                end if;
 
+            --  Processing for I switch
+
+            when 'I' =>
+               Ptr := Ptr + 1;
+               Ignore_Rep_Clauses := True;
+
+            --  Processing for j switch
+
+            when 'j' =>
+               Ptr := Ptr + 1;
+               Scan_Nat (Switch_Chars, Max, Ptr, Error_Msg_Line_Length, C);
+
             --  Processing for k switch
 
             when 'k' =>
                Ptr := Ptr + 1;
-               Scan_Pos (Switch_Chars, Max, Ptr, Maximum_File_Name_Length);
+                  Scan_Pos
+                    (Switch_Chars, Max, Ptr, Maximum_File_Name_Length, C);
 
             --  Processing for l switch
 
@@ -542,18 +606,29 @@ package body Switch.C is
                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;
+
             --  Processing for L switch
 
             when 'L' =>
                Ptr := Ptr + 1;
-               Zero_Cost_Exceptions_Set := True;
-               Zero_Cost_Exceptions_Val := False;
+               Dump_Source_Text := True;
 
             --  Processing for m switch
 
             when 'm' =>
                Ptr := Ptr + 1;
-               Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
+               Scan_Nat (Switch_Chars, Max, Ptr, Maximum_Messages, C);
 
             --  Processing for n switch
 
@@ -586,7 +661,18 @@ package body Switch.C is
 
             when 'p' =>
                Ptr := Ptr + 1;
-               Suppress_Options           := (others => True);
+
+               --  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.
+
+               for J in Suppress_Options'Range loop
+                  if J /= Elaboration_Check then
+                     Suppress_Options (J) := True;
+                  end if;
+               end loop;
+
                Validity_Checks_On         := False;
                Opt.Suppress_Checks        := True;
                Opt.Enable_Overflow_Checks := False;
@@ -603,20 +689,26 @@ package body Switch.C is
                Ptr := Ptr + 1;
                Try_Semantics := True;
 
-            --  Processing for q switch
+            --  Processing for Q switch
 
             when 'Q' =>
                Ptr := Ptr + 1;
                Force_ALI_Tree_File := True;
                Try_Semantics := True;
 
+               --  Processing for r switch
+
+            when 'r' =>
+               Ptr := Ptr + 1;
+               Treat_Restrictions_As_Warnings := True;
+
             --  Processing for R switch
 
             when 'R' =>
-               Ptr := Ptr + 1;
                Back_Annotate_Rep_Info := True;
                List_Representation_Info := 1;
 
+               Ptr := Ptr + 1;
                while Ptr <= Max loop
                   C := Switch_Chars (Ptr);
 
@@ -631,7 +723,7 @@ package body Switch.C is
                      List_Representation_Info_Mechanisms := True;
 
                   else
-                     raise Bad_Switch;
+                     Bad_Switch ("-gnatR" & Switch_Chars (Ptr .. Max));
                   end if;
 
                   Ptr := Ptr + 1;
@@ -659,18 +751,13 @@ package body Switch.C is
             when 't' =>
                Ptr := Ptr + 1;
                Tree_Output := True;
-
-               if Operating_Mode = Check_Semantics then
-                  ASIS_Mode := True;
-               end if;
-
                Back_Annotate_Rep_Info := True;
 
             --  Processing for T switch
 
             when 'T' =>
                Ptr := Ptr + 1;
-               Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor);
+               Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor, C);
 
             --  Processing for u switch
 
@@ -694,11 +781,10 @@ package body Switch.C is
 
             when 'V' =>
                Store_Switch := False;
-               Storing (First_Stored) := 'V';
                Ptr := Ptr + 1;
 
                if Ptr > Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnatV");
 
                else
                   declare
@@ -709,14 +795,12 @@ package body Switch.C is
                        (Switch_Chars (Ptr .. Max), OK, Ptr);
 
                      if not OK then
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnatV" & Switch_Chars (Ptr .. Max));
                      end if;
 
                      for Index in First_Char + 1 .. Max loop
-                        Storing (First_Stored + 1) :=
-                          Switch_Chars (Index);
                         Store_Compilation_Switch
-                          (Storing (Storing'First .. First_Stored + 1));
+                          ("-gnatV" & Switch_Chars (Index));
                      end loop;
                   end;
                end if;
@@ -727,181 +811,35 @@ package body Switch.C is
 
             when 'w' =>
                Store_Switch := False;
-               Storing (First_Stored) := 'w';
                Ptr := Ptr + 1;
 
                if Ptr > Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnatw");
                end if;
 
                while Ptr <= Max loop
                   C := Switch_Chars (Ptr);
 
-                  case C is
-                     when 'a' =>
-                        Check_Unreferenced              := True;
-                        Check_Unreferenced_Formals      := True;
-                        Check_Withs                     := True;
-                        Constant_Condition_Warnings     := True;
-                        Implementation_Unit_Warnings    := True;
-                        Ineffective_Inline_Warnings     := True;
-                        Warn_On_Constant                := True;
-                        Warn_On_Export_Import           := True;
-                        Warn_On_Modified_Unread         := True;
-                        Warn_On_No_Value_Assigned       := True;
-                        Warn_On_Obsolescent_Feature     := True;
-                        Warn_On_Redundant_Constructs    := True;
-                        Warn_On_Unchecked_Conversion    := True;
-                        Warn_On_Unrecognized_Pragma     := True;
-
-                     when 'A' =>
-                        Check_Unreferenced              := False;
-                        Check_Unreferenced_Formals      := False;
-                        Check_Withs                     := False;
-                        Constant_Condition_Warnings     := False;
-                        Elab_Warnings                   := False;
-                        Implementation_Unit_Warnings    := False;
-                        Ineffective_Inline_Warnings     := False;
-                        Warn_On_Constant                := False;
-                        Warn_On_Dereference             := False;
-                        Warn_On_Export_Import           := False;
-                        Warn_On_Hiding                  := False;
-                        Warn_On_Modified_Unread         := False;
-                        Warn_On_No_Value_Assigned       := False;
-                        Warn_On_Obsolescent_Feature     := False;
-                        Warn_On_Redundant_Constructs    := False;
-                        Warn_On_Unchecked_Conversion    := False;
-                        Warn_On_Unrecognized_Pragma     := False;
-
-                     when 'c' =>
-                        Constant_Condition_Warnings     := True;
-
-                     when 'C' =>
-                        Constant_Condition_Warnings     := False;
-
-                     when 'd' =>
-                        Warn_On_Dereference             := True;
-
-                     when 'D' =>
-                        Warn_On_Dereference             := False;
-
-                     when 'e' =>
-                        Warning_Mode                    := Treat_As_Error;
-
-                     when 'f' =>
-                        Check_Unreferenced_Formals      := True;
-
-                     when 'F' =>
-                        Check_Unreferenced_Formals      := False;
-
-                     when 'g' =>
-                        Warn_On_Unrecognized_Pragma     := True;
-
-                     when 'G' =>
-                        Warn_On_Unrecognized_Pragma     := False;
-
-                     when 'h' =>
-                        Warn_On_Hiding                  := True;
-
-                     when 'H' =>
-                        Warn_On_Hiding                  := False;
-
-                     when 'i' =>
-                        Implementation_Unit_Warnings    := True;
-
-                     when 'I' =>
-                        Implementation_Unit_Warnings    := False;
-
-                     when 'j' =>
-                        Warn_On_Obsolescent_Feature     := True;
-
-                     when 'J' =>
-                        Warn_On_Obsolescent_Feature     := False;
-
-                     when 'k' =>
-                        Warn_On_Constant                := True;
-
-                     when 'K' =>
-                        Warn_On_Constant                := False;
+                  --  Case of dot switch
 
-                     when 'l' =>
-                        Elab_Warnings                   := True;
-
-                     when 'L' =>
-                        Elab_Warnings                   := False;
-
-                     when 'm' =>
-                        Warn_On_Modified_Unread         := True;
-
-                     when 'M' =>
-                        Warn_On_Modified_Unread         := False;
-
-                     when 'n' =>
-                        Warning_Mode                    := Normal;
-
-                     when 'o' =>
-                        Address_Clause_Overlay_Warnings := True;
-
-                     when 'O' =>
-                        Address_Clause_Overlay_Warnings := False;
-
-                     when 'p' =>
-                        Ineffective_Inline_Warnings     := True;
-
-                     when 'P' =>
-                        Ineffective_Inline_Warnings     := False;
-
-                     when 'r' =>
-                        Warn_On_Redundant_Constructs    := True;
-
-                     when 'R' =>
-                        Warn_On_Redundant_Constructs    := False;
-
-                     when 's' =>
-                        Warning_Mode                    := Suppress;
-
-                     when 'u' =>
-                        Check_Unreferenced              := True;
-                        Check_Withs                     := True;
-                        Check_Unreferenced_Formals      := True;
-
-                     when 'U' =>
-                        Check_Unreferenced              := False;
-                        Check_Withs                     := False;
-                        Check_Unreferenced_Formals      := False;
-
-                     when 'v' =>
-                        Warn_On_No_Value_Assigned       := True;
-
-                     when 'V' =>
-                        Warn_On_No_Value_Assigned       := False;
-
-                     when 'x' =>
-                        Warn_On_Export_Import           := True;
-
-                     when 'X' =>
-                        Warn_On_Export_Import           := False;
-
-                     when 'z' =>
-                        Warn_On_Unchecked_Conversion    := True;
-
-                     when 'Z' =>
-                        Warn_On_Unchecked_Conversion    := False;
+                  if C = '.' and then Ptr < Max then
+                     Ptr := Ptr + 1;
+                     C := Switch_Chars (Ptr);
 
-                        --  Allow and ignore 'w' so that the old
-                        --  format (e.g. -gnatwuwl) will work.
+                     if Set_Dot_Warning_Switch (C) then
+                        Store_Compilation_Switch ("-gnatw." & C);
+                     else
+                        Bad_Switch ("-gnatw." & Switch_Chars (Ptr .. Max));
+                     end if;
 
-                     when 'w' =>
-                        null;
+                     --  Normal case, no dot
 
-                     when others =>
-                        raise Bad_Switch;
-                  end case;
-
-                  if C /= 'w' then
-                     Storing (First_Stored + 1) := C;
-                     Store_Compilation_Switch
-                       (Storing (Storing'First .. First_Stored + 1));
+                  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;
@@ -915,22 +853,22 @@ package body Switch.C is
                Ptr := Ptr + 1;
 
                if Ptr > Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnatW");
                end if;
 
-               for J in WC_Encoding_Method loop
-                  if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
-                     Wide_Character_Encoding_Method := J;
-                     exit;
+               begin
+                  Wide_Character_Encoding_Method :=
+                    Get_WC_Encoding_Method (Switch_Chars (Ptr));
+               exception
+                  when Constraint_Error =>
+                     Bad_Switch ("-gnatW" & Switch_Chars (Ptr .. Max));
+               end;
 
-                  elsif J = WC_Encoding_Method'Last then
-                     raise Bad_Switch;
-                  end if;
-               end loop;
+               Wide_Character_Encoding_Method_Specified := True;
 
                Upper_Half_Encoding :=
                  Wide_Character_Encoding_Method in
-                 WC_Upper_Half_Encoding_Method;
+                   WC_Upper_Half_Encoding_Method;
 
                Ptr := Ptr + 1;
 
@@ -956,41 +894,38 @@ package body Switch.C is
 
                else
                   Store_Switch := False;
-                  Storing (First_Stored) := 'y';
 
                   declare
                      OK  : Boolean;
-                     Last_Stored : Integer;
 
                   begin
                      Set_Style_Check_Options
                        (Switch_Chars (Ptr .. Max), OK, Ptr);
 
                      if not OK then
-                        raise Bad_Switch;
+                        Osint.Fail
+                          ("bad -gnaty switch (" &
+                           Style_Msg_Buf (1 .. Style_Msg_Len) & ')');
                      end if;
 
                      Ptr := First_Char + 1;
-
                      while Ptr <= Max loop
-                        Last_Stored := First_Stored + 1;
-                        Storing (Last_Stored) := Switch_Chars (Ptr);
-
                         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';
-                              Last_Stored := Last_Stored + 1;
-                              Storing (Last_Stored) := Switch_Chars (Ptr);
                            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;
-
-                        Store_Compilation_Switch
-                          (Storing (Storing'First .. Last_Stored));
                      end loop;
                   end;
                end if;
@@ -998,10 +933,23 @@ package body Switch.C is
             --  Processing for z switch
 
             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;
 
-               --  Allowed for compiler only if this is the only
-               --  -z switch, we do not allow multiple occurrences
+               --  Only one occurrence of -gnat* is permitted
 
                if Distribution_Stub_Mode = No_Stubs then
                   case Switch_Chars (Ptr) is
@@ -1012,36 +960,71 @@ package body Switch.C is
                         Distribution_Stub_Mode := Generate_Caller_Stub_Body;
 
                      when others =>
-                        raise Bad_Switch;
+                        Bad_Switch ("-gnatz" & Switch_Chars (Ptr .. Max));
                   end case;
 
                   Ptr := Ptr + 1;
 
+               else
+                  Osint.Fail ("only one -gnatz* switch allowed");
                end if;
 
             --  Processing for Z switch
 
             when 'Z' =>
                Ptr := Ptr + 1;
-               Zero_Cost_Exceptions_Set := True;
-               Zero_Cost_Exceptions_Val := True;
+               Osint.Fail
+                 ("-gnatZ is no longer supported: consider using --RTS=zcx");
 
             --  Processing for 83 switch
 
             when '8' =>
-
                if Ptr = Max then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnat8");
                end if;
 
                Ptr := Ptr + 1;
 
                if Switch_Chars (Ptr) /= '3' then
-                  raise Bad_Switch;
+                  Bad_Switch ("-gnat8" & Switch_Chars (Ptr .. Max));
                else
                   Ptr := Ptr + 1;
-                  Ada_95 := False;
-                  Ada_83 := True;
+                  Ada_Version := Ada_83;
+                  Ada_Version_Explicit := Ada_Version;
+               end if;
+
+            --  Processing for 95 switch
+
+            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_Version;
+               end if;
+
+            --  Processing for 05 switch
+
+            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_05;
+                  Ada_Version_Explicit := Ada_Version;
                end if;
 
             --  Ignore extra switch character
@@ -1052,30 +1035,17 @@ package body Switch.C is
             --  Anything else is an error (illegal switch character)
 
             when others =>
-               raise Bad_Switch;
+               Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Max));
             end case;
-         end case;
 
-         if Store_Switch then
-            Storing (First_Stored .. First_Stored + Ptr - First_Char - 1) :=
-              Switch_Chars (First_Char .. Ptr - 1);
-            Store_Compilation_Switch
-              (Storing (Storing'First .. First_Stored + Ptr - First_Char - 1));
-         end if;
-
-         First_Switch := False;
-      end loop;
-
-   exception
-      when Bad_Switch =>
-         Osint.Fail ("invalid switch: ", (1 => C));
-
-      when Bad_Switch_Value =>
-         Osint.Fail ("numeric value out of range for switch: ", (1 => C));
-
-      when Missing_Switch_Value =>
-         Osint.Fail ("missing numeric value for switch: ", (1 => C));
+            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;
 
 end Switch.C;