OSDN Git Service

More improvements to sparc VIS vec_init code generation.
[pf3gnuchains/gcc-fork.git] / gcc / ada / switch-c.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S W I T C H - C                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 2001-2011, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
20 --                                                                          --
21 -- GNAT was originally developed  by the GNAT team at  New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
23 --                                                                          --
24 ------------------------------------------------------------------------------
25
26 --  This package is for switch processing and should not depend on higher level
27 --  packages such as those for the scanner, parser, etc. Doing so may cause
28 --  circularities, especially for back ends using Adabkend.
29
30 with Debug;    use Debug;
31 with Lib;      use Lib;
32 with Osint;    use Osint;
33 with Opt;      use Opt;
34 with Validsw;  use Validsw;
35 with Stylesw;  use Stylesw;
36 with Warnsw;   use Warnsw;
37
38 with Ada.Unchecked_Deallocation;
39 with System.WCh_Con; use System.WCh_Con;
40
41 package body Switch.C is
42
43    RTS_Specified : String_Access := null;
44    --  Used to detect multiple use of --RTS= flag
45
46    procedure Add_Symbol_Definition (Def : String);
47    --  Add a symbol definition from the command line
48
49    procedure Free is
50       new Ada.Unchecked_Deallocation (String_List, String_List_Access);
51    --  Avoid using System.Strings.Free, which also frees the designated strings
52
53    function Switch_Subsequently_Cancelled
54      (C        : String;
55       Args     : String_List;
56       Arg_Rank : Positive) return Boolean;
57    --  This function is called from Scan_Front_End_Switches. It determines if
58    --  the switch currently being scanned is followed by a switch of the form
59    --  "-gnat-" & C, where C is the argument. If so, then True is returned,
60    --  and Scan_Front_End_Switches will cancel the effect of the switch. If
61    --  no such switch is found, False is returned.
62
63    ---------------------------
64    -- Add_Symbol_Definition --
65    ---------------------------
66
67    procedure Add_Symbol_Definition (Def : String) is
68    begin
69       --  If Preprocessor_Symbol_Defs is not large enough, double its size
70
71       if Preprocessing_Symbol_Last = Preprocessing_Symbol_Defs'Last then
72          declare
73             New_Symbol_Definitions : constant String_List_Access :=
74               new String_List (1 .. 2 * Preprocessing_Symbol_Last);
75
76          begin
77             New_Symbol_Definitions (Preprocessing_Symbol_Defs'Range) :=
78               Preprocessing_Symbol_Defs.all;
79             Free (Preprocessing_Symbol_Defs);
80             Preprocessing_Symbol_Defs := New_Symbol_Definitions;
81          end;
82       end if;
83
84       Preprocessing_Symbol_Last := Preprocessing_Symbol_Last + 1;
85       Preprocessing_Symbol_Defs (Preprocessing_Symbol_Last) :=
86         new String'(Def);
87    end Add_Symbol_Definition;
88
89    -----------------------------
90    -- Scan_Front_End_Switches --
91    -----------------------------
92
93    procedure Scan_Front_End_Switches
94      (Switch_Chars : String;
95       Args         : String_List;
96       Arg_Rank     : Positive)
97    is
98       First_Switch : Boolean := True;
99       --  False for all but first switch
100
101       Max : constant Natural := Switch_Chars'Last;
102       Ptr : Natural;
103       C   : Character := ' ';
104       Dot : Boolean;
105
106       Store_Switch : Boolean;
107       --  For -gnatxx switches, the normal processing, signalled by this flag
108       --  being set to True, is to store the switch on exit from the case
109       --  statement, the switch stored is -gnat followed by the characters
110       --  from First_Char to Ptr-1. For cases like -gnaty, where the switch
111       --  is stored in separate pieces, this flag is set to False, and the
112       --  appropriate calls to Store_Compilation_Switch are made from within
113       --  the case branch.
114
115       First_Char : Positive;
116       --  Marks start of switch to be stored
117
118    begin
119       Ptr := Switch_Chars'First;
120
121       --  Skip past the initial character (must be the switch character)
122
123       if Ptr = Max then
124          Bad_Switch (C);
125       else
126          Ptr := Ptr + 1;
127       end if;
128
129       --  Handle switches that do not start with -gnat
130
131       if Ptr + 3 > Max
132         or else Switch_Chars (Ptr .. Ptr + 3) /= "gnat"
133       then
134          --  There are two front-end switches that do not start with -gnat:
135          --  -I, --RTS
136
137          if Switch_Chars (Ptr) = 'I' then
138
139             --  Set flag Search_Directory_Present if switch is "-I" only:
140             --  the directory will be the next argument.
141
142             if Ptr = Max then
143                Search_Directory_Present := True;
144                return;
145             end if;
146
147             Ptr := Ptr + 1;
148
149             --  Find out whether this is a -I- or regular -Ixxx switch
150
151             --  Note: -I switches are not recorded in the ALI file, since the
152             --  meaning of the program depends on the source files compiled,
153             --  not where they came from.
154
155             if Ptr = Max and then Switch_Chars (Ptr) = '-' then
156                Look_In_Primary_Dir := False;
157             else
158                Add_Src_Search_Dir (Switch_Chars (Ptr .. Max));
159             end if;
160
161          --  Processing of the --RTS switch. --RTS may have been modified by
162          --  gcc into -fRTS (for GCC targets).
163
164          elsif Ptr + 3 <= Max
165            and then (Switch_Chars (Ptr .. Ptr + 3) = "fRTS"
166                        or else
167                      Switch_Chars (Ptr .. Ptr + 3) = "-RTS")
168          then
169             Ptr := Ptr + 1;
170
171             if Ptr + 4 > Max
172               or else Switch_Chars (Ptr + 3) /= '='
173             then
174                Osint.Fail ("missing path for --RTS");
175             else
176                --  Check that this is the first time --RTS is specified or if
177                --  it is not the first time, the same path has been specified.
178
179                if RTS_Specified = null then
180                   RTS_Specified := new String'(Switch_Chars (Ptr + 4 .. Max));
181
182                elsif
183                  RTS_Specified.all /= Switch_Chars (Ptr + 4 .. Max)
184                then
185                   Osint.Fail ("--RTS cannot be specified multiple times");
186                end if;
187
188                --  Valid --RTS switch
189
190                Opt.No_Stdinc := True;
191                Opt.RTS_Switch := True;
192
193                RTS_Src_Path_Name :=
194                  Get_RTS_Search_Dir
195                    (Switch_Chars (Ptr + 4 .. Max), Include);
196
197                RTS_Lib_Path_Name :=
198                  Get_RTS_Search_Dir
199                    (Switch_Chars (Ptr + 4 .. Max), Objects);
200
201                if RTS_Src_Path_Name /= null
202                  and then RTS_Lib_Path_Name /= null
203                then
204                   --  Store the -fRTS switch (Note: Store_Compilation_Switch
205                   --  changes -fRTS back into --RTS for the actual output).
206
207                   Store_Compilation_Switch (Switch_Chars);
208
209                elsif RTS_Src_Path_Name = null
210                  and then RTS_Lib_Path_Name = null
211                then
212                   Osint.Fail ("RTS path not valid: missing " &
213                               "adainclude and adalib directories");
214
215                elsif RTS_Src_Path_Name = null then
216                   Osint.Fail ("RTS path not valid: missing " &
217                               "adainclude directory");
218
219                elsif RTS_Lib_Path_Name = null then
220                   Osint.Fail ("RTS path not valid: missing " &
221                               "adalib directory");
222                end if;
223             end if;
224
225             --  There are no other switches not starting with -gnat
226
227          else
228             Bad_Switch (Switch_Chars);
229          end if;
230
231       --  Case of switch starting with -gnat
232
233       else
234          Ptr := Ptr + 4;
235
236          --  Loop to scan through switches given in switch string
237
238          while Ptr <= Max loop
239             First_Char := Ptr;
240             Store_Switch := True;
241
242             C := Switch_Chars (Ptr);
243
244             case C is
245
246             when 'a' =>
247                Ptr := Ptr + 1;
248                Assertions_Enabled := True;
249                Debug_Pragmas_Enabled := True;
250
251             --  Processing for A switch
252
253             when 'A' =>
254                Ptr := Ptr + 1;
255                Config_File := False;
256
257             --  Processing for b switch
258
259             when 'b' =>
260                Ptr := Ptr + 1;
261                Brief_Output := True;
262
263             --  Processing for B switch
264
265             when 'B' =>
266                Ptr := Ptr + 1;
267                Assume_No_Invalid_Values := True;
268
269             --  Processing for c switch
270
271             when 'c' =>
272                if not First_Switch then
273                   Osint.Fail
274                     ("-gnatc must be first if combined with other switches");
275                end if;
276
277                Ptr := Ptr + 1;
278                Operating_Mode := Check_Semantics;
279
280             --  Processing for C switch
281
282             when 'C' =>
283                Ptr := Ptr + 1;
284
285                if not CodePeer_Mode then
286                   CodePeer_Mode := True;
287
288                   --  Suppress compiler warnings by default, since what we are
289                   --  interested in here is what CodePeer can find out. Note
290                   --  that if -gnatwxxx is specified after -gnatC on the
291                   --  command line, we do not want to override this setting in
292                   --  Adjust_Global_Switches, and assume that the user wants to
293                   --  get both warnings from GNAT and CodePeer messages.
294
295                   Warning_Mode := Suppress;
296                end if;
297
298             --  Processing for d switch
299
300             when 'd' =>
301                Store_Switch := False;
302                Dot := False;
303
304                --  Note: for the debug switch, the remaining characters in this
305                --  switch field must all be debug flags, since all valid switch
306                --  characters are also valid debug characters.
307
308                --  Loop to scan out debug flags
309
310                while Ptr < Max loop
311                   Ptr := Ptr + 1;
312                   C := Switch_Chars (Ptr);
313                   exit when C = ASCII.NUL or else C = '/' or else C = '-';
314
315                   if C in '1' .. '9' or else
316                      C in 'a' .. 'z' or else
317                      C in 'A' .. 'Z'
318                   then
319                      if Dot then
320                         Set_Dotted_Debug_Flag (C);
321                         Store_Compilation_Switch ("-gnatd." & C);
322                      else
323                         Set_Debug_Flag (C);
324                         Store_Compilation_Switch ("-gnatd" & C);
325                      end if;
326
327                   elsif C = '.' then
328                      Dot := True;
329
330                   elsif Dot then
331                      Bad_Switch ("-gnatd." & Switch_Chars (Ptr .. Max));
332                   else
333                      Bad_Switch ("-gnatd" & Switch_Chars (Ptr .. Max));
334                   end if;
335                end loop;
336
337                return;
338
339             --  Processing for D switch
340
341             when 'D' =>
342                Ptr := Ptr + 1;
343
344                --  Scan optional integer line limit value
345
346                if Nat_Present (Switch_Chars, Max, Ptr) then
347                   Scan_Nat (Switch_Chars, Max, Ptr, Sprint_Line_Limit, 'D');
348                   Sprint_Line_Limit := Nat'Max (Sprint_Line_Limit, 40);
349                end if;
350
351                --  Note: -gnatD also sets -gnatx (to turn off cross-reference
352                --  generation in the ali file) since otherwise this generation
353                --  gets confused by the "wrong" Sloc values put in the tree.
354
355                Debug_Generated_Code := True;
356                Xref_Active := False;
357                Set_Debug_Flag ('g');
358
359             --  -gnate? (extended switches)
360
361             when 'e' =>
362                Ptr := Ptr + 1;
363
364                --  The -gnate? switches are all double character switches
365                --  so we must always have a character after the e.
366
367                if Ptr > Max then
368                   Bad_Switch ("-gnate");
369                end if;
370
371                case Switch_Chars (Ptr) is
372
373                   --  -gnatea (initial delimiter of explicit switches)
374
375                   --  All switches that come before -gnatea have been added by
376                   --  the GCC driver and are not stored in the ALI file.
377                   --  See also -gnatez below.
378
379                   when 'a' =>
380                      Store_Switch := False;
381                      Enable_Switch_Storing;
382                      Ptr := Ptr + 1;
383
384                   --  -gnatec (configuration pragmas)
385
386                   when 'c' =>
387                      Store_Switch := False;
388                      Ptr := Ptr + 1;
389
390                      --  There may be an equal sign between -gnatec and
391                      --  the path name of the config file.
392
393                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
394                         Ptr := Ptr + 1;
395                      end if;
396
397                      if Ptr > Max then
398                         Bad_Switch ("-gnatec");
399                      end if;
400
401                      declare
402                         Config_File_Name : constant String_Access :=
403                                              new String'
404                                                   (Switch_Chars (Ptr .. Max));
405
406                      begin
407                         if Config_File_Names = null then
408                            Config_File_Names :=
409                              new String_List'(1 => Config_File_Name);
410
411                         else
412                            declare
413                               New_Names : constant String_List_Access :=
414                                             new String_List
415                                               (1 ..
416                                                Config_File_Names'Length + 1);
417
418                            begin
419                               for Index in Config_File_Names'Range loop
420                                  New_Names (Index) :=
421                                    Config_File_Names (Index);
422                                  Config_File_Names (Index) := null;
423                               end loop;
424
425                               New_Names (New_Names'Last) := Config_File_Name;
426                               Free (Config_File_Names);
427                               Config_File_Names := New_Names;
428                            end;
429                         end if;
430                      end;
431
432                      return;
433
434                   --  -gnateC switch (CodePeer SCIL generation)
435
436                   --  Not enabled for now, keep it for later???
437                   --  use -gnatd.I only for now
438
439                   --  when 'C' =>
440                   --     Ptr := Ptr + 1;
441                   --     Generate_SCIL := True;
442
443                   --  -gnated switch (disable atomic synchronization)
444
445                   when 'd' =>
446                      Suppress_Options (Atomic_Synchronization) := True;
447
448                   --  -gnateD switch (preprocessing symbol definition)
449
450                   when 'D' =>
451                      Store_Switch := False;
452                      Ptr := Ptr + 1;
453
454                      if Ptr > Max then
455                         Bad_Switch ("-gnateD");
456                      end if;
457
458                      Add_Symbol_Definition (Switch_Chars (Ptr .. Max));
459
460                      --  Store the switch
461
462                      Store_Compilation_Switch
463                        ("-gnateD" & Switch_Chars (Ptr .. Max));
464                      Ptr := Max + 1;
465
466                   --  -gnateE (extra exception information)
467
468                   when 'E' =>
469                      Exception_Extra_Info := True;
470                      Ptr := Ptr + 1;
471
472                   --  -gnatef (full source path for brief error messages)
473
474                   when 'f' =>
475                      Store_Switch := False;
476                      Ptr := Ptr + 1;
477                      Full_Path_Name_For_Brief_Errors := True;
478
479                   --  -gnateG (save preprocessor output)
480
481                   when 'G' =>
482                      Generate_Processed_File := True;
483                      Ptr := Ptr + 1;
484
485                   --  -gnateI (index of unit in multi-unit source)
486
487                   when 'I' =>
488                      Ptr := Ptr + 1;
489                      Scan_Pos (Switch_Chars, Max, Ptr, Multiple_Unit_Index, C);
490
491                   --  -gnatem (mapping file)
492
493                   when 'm' =>
494                      Store_Switch := False;
495                      Ptr := Ptr + 1;
496
497                      --  There may be an equal sign between -gnatem and
498                      --  the path name of the mapping file.
499
500                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
501                         Ptr := Ptr + 1;
502                      end if;
503
504                      if Ptr > Max then
505                         Bad_Switch ("-gnatem");
506                      end if;
507
508                      Mapping_File_Name :=
509                        new String'(Switch_Chars (Ptr .. Max));
510                      return;
511
512                   --  -gnatep (preprocessing data file)
513
514                   when 'p' =>
515                      Store_Switch := False;
516                      Ptr := Ptr + 1;
517
518                      --  There may be an equal sign between -gnatep and
519                      --  the path name of the mapping file.
520
521                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
522                         Ptr := Ptr + 1;
523                      end if;
524
525                      if Ptr > Max then
526                         Bad_Switch ("-gnatep");
527                      end if;
528
529                      Preprocessing_Data_File :=
530                        new String'(Switch_Chars (Ptr .. Max));
531
532                      --  Store the switch, normalizing to -gnatep=
533
534                      Store_Compilation_Switch
535                        ("-gnatep=" & Preprocessing_Data_File.all);
536
537                      Ptr := Max + 1;
538
539                   --  -gnateP (Treat pragma Pure/Preelaborate errs as warnings)
540
541                   when 'P' =>
542                      Treat_Categorization_Errors_As_Warnings := True;
543
544                   --  -gnatez (final delimiter of explicit switches)
545
546                   --  All switches that come after -gnatez have been added by
547                   --  the GCC driver and are not stored in the ALI file. See
548                   --  also -gnatea above.
549
550                   when 'z' =>
551                      Store_Switch := False;
552                      Disable_Switch_Storing;
553                      Ptr := Ptr + 1;
554
555                   --  -gnateS (generate SCO information)
556
557                   --  Include Source Coverage Obligation information in ALI
558                   --  files for the benefit of source coverage analysis tools
559                   --  (xcov).
560
561                   when 'S' =>
562                      Generate_SCO := True;
563                      Ptr := Ptr + 1;
564
565                   --  All other -gnate? switches are unassigned
566
567                   when others =>
568                      Bad_Switch ("-gnate" & Switch_Chars (Ptr .. Max));
569                end case;
570
571             --  -gnatE (dynamic elaboration checks)
572
573             when 'E' =>
574                Ptr := Ptr + 1;
575                Dynamic_Elaboration_Checks := True;
576
577             --  -gnatf (full error messages)
578
579             when 'f' =>
580                Ptr := Ptr + 1;
581                All_Errors_Mode := True;
582
583             --  Processing for F switch
584
585             when 'F' =>
586                Ptr := Ptr + 1;
587                External_Name_Exp_Casing := Uppercase;
588                External_Name_Imp_Casing := Uppercase;
589
590             --  Processing for g switch
591
592             when 'g' =>
593                Ptr := Ptr + 1;
594                GNAT_Mode := True;
595                Identifier_Character_Set := 'n';
596                System_Extend_Unit := Empty;
597                Warning_Mode := Treat_As_Error;
598
599                --  Set Ada 2012 mode explicitly. We don't want to rely on the
600                --  implicit setting here, since for example, we want
601                --  Preelaborate_05 treated as Preelaborate
602
603                Ada_Version := Ada_2012;
604                Ada_Version_Explicit := Ada_Version;
605
606                --  Set default warnings and style checks for -gnatg
607
608                Set_GNAT_Mode_Warnings;
609                Set_GNAT_Style_Check_Options;
610
611             --  Processing for G switch
612
613             when 'G' =>
614                Ptr := Ptr + 1;
615                Print_Generated_Code := True;
616
617                --  Scan optional integer line limit value
618
619                if Nat_Present (Switch_Chars, Max, Ptr) then
620                   Scan_Nat (Switch_Chars, Max, Ptr, Sprint_Line_Limit, 'G');
621                   Sprint_Line_Limit := Nat'Max (Sprint_Line_Limit, 40);
622                end if;
623
624             --  Processing for h switch
625
626             when 'h' =>
627                Ptr := Ptr + 1;
628                Usage_Requested := True;
629
630             --  Processing for H switch
631
632             when 'H' =>
633                Ptr := Ptr + 1;
634                HLO_Active := True;
635
636             --  Processing for i switch
637
638             when 'i' =>
639                if Ptr = Max then
640                   Bad_Switch ("-gnati");
641                end if;
642
643                Ptr := Ptr + 1;
644                C := Switch_Chars (Ptr);
645
646                if C in '1' .. '5'
647                  or else C = '8'
648                  or else C = '9'
649                  or else C = 'p'
650                  or else C = 'f'
651                  or else C = 'n'
652                  or else C = 'w'
653                then
654                   Identifier_Character_Set := C;
655                   Ptr := Ptr + 1;
656
657                else
658                   Bad_Switch ("-gnati" & Switch_Chars (Ptr .. Max));
659                end if;
660
661             --  Processing for I switch
662
663             when 'I' =>
664                Ptr := Ptr + 1;
665                Ignore_Rep_Clauses := True;
666
667             --  Processing for j switch
668
669             when 'j' =>
670                Ptr := Ptr + 1;
671                Scan_Nat (Switch_Chars, Max, Ptr, Error_Msg_Line_Length, C);
672
673             --  Processing for k switch
674
675             when 'k' =>
676                Ptr := Ptr + 1;
677                   Scan_Pos
678                     (Switch_Chars, Max, Ptr, Maximum_File_Name_Length, C);
679
680             --  Processing for l switch
681
682             when 'l' =>
683                Ptr := Ptr + 1;
684                Full_List := True;
685
686                --  There may be an equal sign between -gnatl and a file name
687
688                if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
689                   if Ptr = Max then
690                      Osint.Fail ("file name for -gnatl= is null");
691                   else
692                      Opt.Full_List_File_Name :=
693                        new String'(Switch_Chars (Ptr + 1 .. Max));
694                      Ptr := Max + 1;
695                   end if;
696                end if;
697
698             --  Processing for L switch
699
700             when 'L' =>
701                Ptr := Ptr + 1;
702                Dump_Source_Text := True;
703
704             --  Processing for m switch
705
706             when 'm' =>
707                Ptr := Ptr + 1;
708                Scan_Nat (Switch_Chars, Max, Ptr, Maximum_Messages, C);
709
710             --  Processing for n switch
711
712             when 'n' =>
713                Ptr := Ptr + 1;
714                Inline_Active := True;
715
716             --  Processing for N switch
717
718             when 'N' =>
719                Ptr := Ptr + 1;
720                Inline_Active := True;
721                Front_End_Inlining := True;
722
723             --  Processing for o switch
724
725             when 'o' =>
726                Ptr := Ptr + 1;
727                Suppress_Options (Overflow_Check) := False;
728                Opt.Enable_Overflow_Checks := True;
729
730             --  Processing for O switch
731
732             when 'O' =>
733                Store_Switch := False;
734                Ptr := Ptr + 1;
735                Output_File_Name_Present := True;
736
737             --  Processing for p switch
738
739             when 'p' =>
740                Ptr := Ptr + 1;
741
742                --  Skip processing if cancelled by subsequent -gnat-p
743
744                if Switch_Subsequently_Cancelled ("p", Args, Arg_Rank) then
745                   Store_Switch := False;
746
747                else
748                   --  Set all specific options as well as All_Checks in the
749                   --  Suppress_Options array, excluding Elaboration_Check,
750                   --  since this is treated specially because we do not want
751                   --  -gnatp to disable static elaboration processing. Also
752                   --  exclude Atomic_Synchronization, since this is not a real
753                   --  check.
754
755                   for J in Suppress_Options'Range loop
756                      if J /= Elaboration_Check
757                        and then J /= Atomic_Synchronization
758                      then
759                         Suppress_Options (J) := True;
760                      end if;
761                   end loop;
762
763                   Validity_Checks_On         := False;
764                   Opt.Suppress_Checks        := True;
765                   Opt.Enable_Overflow_Checks := False;
766                end if;
767
768             --  Processing for P switch
769
770             when 'P' =>
771                Ptr := Ptr + 1;
772                Polling_Required := True;
773
774             --  Processing for q switch
775
776             when 'q' =>
777                Ptr := Ptr + 1;
778                Try_Semantics := True;
779
780             --  Processing for Q switch
781
782             when 'Q' =>
783                Ptr := Ptr + 1;
784                Force_ALI_Tree_File := True;
785                Try_Semantics := True;
786
787                --  Processing for r switch
788
789             when 'r' =>
790                Ptr := Ptr + 1;
791                Treat_Restrictions_As_Warnings := True;
792
793             --  Processing for R switch
794
795             when 'R' =>
796                Back_Annotate_Rep_Info := True;
797                List_Representation_Info := 1;
798
799                Ptr := Ptr + 1;
800                while Ptr <= Max loop
801                   C := Switch_Chars (Ptr);
802
803                   if C in '1' .. '3' then
804                      List_Representation_Info :=
805                        Character'Pos (C) - Character'Pos ('0');
806
807                   elsif Switch_Chars (Ptr) = 's' then
808                      List_Representation_Info_To_File := True;
809
810                   elsif Switch_Chars (Ptr) = 'm' then
811                      List_Representation_Info_Mechanisms := True;
812
813                   else
814                      Bad_Switch ("-gnatR" & Switch_Chars (Ptr .. Max));
815                   end if;
816
817                   Ptr := Ptr + 1;
818                end loop;
819
820             --  Processing for s switch
821
822             when 's' =>
823                if not First_Switch then
824                   Osint.Fail
825                     ("-gnats must be first if combined with other switches");
826                end if;
827
828                Ptr := Ptr + 1;
829                Operating_Mode := Check_Syntax;
830
831             --  Processing for S switch
832
833             when 'S' =>
834                Print_Standard := True;
835                Ptr := Ptr + 1;
836
837             --  Processing for t switch
838
839             when 't' =>
840                Ptr := Ptr + 1;
841                Tree_Output := True;
842                Back_Annotate_Rep_Info := True;
843
844             --  Processing for T switch
845
846             when 'T' =>
847                Ptr := Ptr + 1;
848                Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor, C);
849
850             --  Processing for u switch
851
852             when 'u' =>
853                Ptr := Ptr + 1;
854                List_Units := True;
855
856             --  Processing for U switch
857
858             when 'U' =>
859                Ptr := Ptr + 1;
860                Unique_Error_Tag := True;
861
862             --  Processing for v switch
863
864             when 'v' =>
865                Ptr := Ptr + 1;
866                Verbose_Mode := True;
867
868             --  Processing for V switch
869
870             when 'V' =>
871                Store_Switch := False;
872                Ptr := Ptr + 1;
873
874                if Ptr > Max then
875                   Bad_Switch ("-gnatV");
876
877                else
878                   declare
879                      OK  : Boolean;
880
881                   begin
882                      Set_Validity_Check_Options
883                        (Switch_Chars (Ptr .. Max), OK, Ptr);
884
885                      if not OK then
886                         Bad_Switch ("-gnatV" & Switch_Chars (Ptr .. Max));
887                      end if;
888
889                      for Index in First_Char + 1 .. Max loop
890                         Store_Compilation_Switch
891                           ("-gnatV" & Switch_Chars (Index));
892                      end loop;
893                   end;
894                end if;
895
896                Ptr := Max + 1;
897
898             --  Processing for w switch
899
900             when 'w' =>
901                Store_Switch := False;
902                Ptr := Ptr + 1;
903
904                if Ptr > Max then
905                   Bad_Switch ("-gnatw");
906                end if;
907
908                while Ptr <= Max loop
909                   C := Switch_Chars (Ptr);
910
911                   --  Case of dot switch
912
913                   if C = '.' and then Ptr < Max then
914                      Ptr := Ptr + 1;
915                      C := Switch_Chars (Ptr);
916
917                      if Set_Dot_Warning_Switch (C) then
918                         Store_Compilation_Switch ("-gnatw." & C);
919                      else
920                         Bad_Switch ("-gnatw." & Switch_Chars (Ptr .. Max));
921                      end if;
922
923                      --  Normal case, no dot
924
925                   else
926                      if Set_Warning_Switch (C) then
927                         Store_Compilation_Switch ("-gnatw" & C);
928                      else
929                         Bad_Switch ("-gnatw" & Switch_Chars (Ptr .. Max));
930                      end if;
931                   end if;
932
933                   Ptr := Ptr + 1;
934                end loop;
935
936                return;
937
938             --  Processing for W switch
939
940             when 'W' =>
941                Ptr := Ptr + 1;
942
943                if Ptr > Max then
944                   Bad_Switch ("-gnatW");
945                end if;
946
947                begin
948                   Wide_Character_Encoding_Method :=
949                     Get_WC_Encoding_Method (Switch_Chars (Ptr));
950                exception
951                   when Constraint_Error =>
952                      Bad_Switch ("-gnatW" & Switch_Chars (Ptr .. Max));
953                end;
954
955                Wide_Character_Encoding_Method_Specified := True;
956
957                Upper_Half_Encoding :=
958                  Wide_Character_Encoding_Method in
959                    WC_Upper_Half_Encoding_Method;
960
961                Ptr := Ptr + 1;
962
963             --  Processing for x switch
964
965             when 'x' =>
966                Ptr := Ptr + 1;
967                Xref_Active := False;
968
969             --  Processing for X switch
970
971             when 'X' =>
972                Ptr := Ptr + 1;
973                Extensions_Allowed   := True;
974                Ada_Version          := Ada_Version_Type'Last;
975                Ada_Version_Explicit := Ada_Version_Type'Last;
976
977             --  Processing for y switch
978
979             when 'y' =>
980                Ptr := Ptr + 1;
981
982                if Ptr > Max then
983                   Set_Default_Style_Check_Options;
984
985                else
986                   Store_Switch := False;
987
988                   declare
989                      OK  : Boolean;
990
991                   begin
992                      Set_Style_Check_Options
993                        (Switch_Chars (Ptr .. Max), OK, Ptr);
994
995                      if not OK then
996                         Osint.Fail
997                           ("bad -gnaty switch (" &
998                            Style_Msg_Buf (1 .. Style_Msg_Len) & ')');
999                      end if;
1000
1001                      Ptr := First_Char + 1;
1002                      while Ptr <= Max loop
1003                         if Switch_Chars (Ptr) = 'M' then
1004                            First_Char := Ptr;
1005                            loop
1006                               Ptr := Ptr + 1;
1007                               exit when Ptr > Max
1008                                 or else Switch_Chars (Ptr) not in '0' .. '9';
1009                            end loop;
1010
1011                            Store_Compilation_Switch
1012                              ("-gnaty" & Switch_Chars (First_Char .. Ptr - 1));
1013
1014                         else
1015                            Store_Compilation_Switch
1016                              ("-gnaty" & Switch_Chars (Ptr));
1017                            Ptr := Ptr + 1;
1018                         end if;
1019                      end loop;
1020                   end;
1021                end if;
1022
1023             --  Processing for z switch
1024
1025             when 'z' =>
1026
1027                --  -gnatz must be the first and only switch in Switch_Chars,
1028                --  and is a two-letter switch.
1029
1030                if Ptr /= Switch_Chars'First + 5
1031                  or else (Max - Ptr + 1) > 2
1032                then
1033                   Osint.Fail
1034                     ("-gnatz* may not be combined with other switches");
1035                end if;
1036
1037                if Ptr = Max then
1038                   Bad_Switch ("-gnatz");
1039                end if;
1040
1041                Ptr := Ptr + 1;
1042
1043                --  Only one occurrence of -gnat* is permitted
1044
1045                if Distribution_Stub_Mode = No_Stubs then
1046                   case Switch_Chars (Ptr) is
1047                      when 'r' =>
1048                         Distribution_Stub_Mode := Generate_Receiver_Stub_Body;
1049
1050                      when 'c' =>
1051                         Distribution_Stub_Mode := Generate_Caller_Stub_Body;
1052
1053                      when others =>
1054                         Bad_Switch ("-gnatz" & Switch_Chars (Ptr .. Max));
1055                   end case;
1056
1057                   Ptr := Ptr + 1;
1058
1059                else
1060                   Osint.Fail ("only one -gnatz* switch allowed");
1061                end if;
1062
1063             --  Processing for Z switch
1064
1065             when 'Z' =>
1066                Ptr := Ptr + 1;
1067                Osint.Fail
1068                  ("-gnatZ is no longer supported: consider using --RTS=zcx");
1069
1070             --  Note on language version switches: whenever a new language
1071             --  version switch is added, Switch.M.Normalize_Compiler_Switches
1072             --  must be updated.
1073
1074             --  Processing for 83 switch
1075
1076             when '8' =>
1077                if Ptr = Max then
1078                   Bad_Switch ("-gnat8");
1079                end if;
1080
1081                Ptr := Ptr + 1;
1082
1083                if Switch_Chars (Ptr) /= '3' then
1084                   Bad_Switch ("-gnat8" & Switch_Chars (Ptr .. Max));
1085                else
1086                   Ptr := Ptr + 1;
1087                   Ada_Version := Ada_83;
1088                   Ada_Version_Explicit := Ada_Version;
1089                end if;
1090
1091             --  Processing for 95 switch
1092
1093             when '9' =>
1094                if Ptr = Max then
1095                   Bad_Switch ("-gnat9");
1096                end if;
1097
1098                Ptr := Ptr + 1;
1099
1100                if Switch_Chars (Ptr) /= '5' then
1101                   Bad_Switch ("-gnat9" & Switch_Chars (Ptr .. Max));
1102                else
1103                   Ptr := Ptr + 1;
1104                   Ada_Version := Ada_95;
1105                   Ada_Version_Explicit := Ada_Version;
1106                end if;
1107
1108             --  Processing for 05 switch
1109
1110             when '0' =>
1111                if Ptr = Max then
1112                   Bad_Switch ("-gnat0");
1113                end if;
1114
1115                Ptr := Ptr + 1;
1116
1117                if Switch_Chars (Ptr) /= '5' then
1118                   Bad_Switch ("-gnat0" & Switch_Chars (Ptr .. Max));
1119                else
1120                   Ptr := Ptr + 1;
1121                   Ada_Version := Ada_2005;
1122                   Ada_Version_Explicit := Ada_Version;
1123                end if;
1124
1125             --  Processing for 12 switch
1126
1127             when '1' =>
1128                if Ptr = Max then
1129                   Bad_Switch ("-gnat1");
1130                end if;
1131
1132                Ptr := Ptr + 1;
1133
1134                if Switch_Chars (Ptr) /= '2' then
1135                   Bad_Switch ("-gnat1" & Switch_Chars (Ptr .. Max));
1136                else
1137                   Ptr := Ptr + 1;
1138                   Ada_Version := Ada_2012;
1139                   Ada_Version_Explicit := Ada_Version;
1140                end if;
1141
1142             --  Processing for 2005 and 2012 switches
1143
1144             when '2' =>
1145                if Ptr > Max - 3 then
1146                   Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Max));
1147
1148                elsif Switch_Chars (Ptr .. Ptr + 3) = "2005" then
1149                   Ada_Version := Ada_2005;
1150
1151                elsif Switch_Chars (Ptr .. Ptr + 3) = "2012" then
1152                   Ada_Version := Ada_2012;
1153
1154                else
1155                   Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Ptr + 3));
1156                end if;
1157
1158                Ada_Version_Explicit := Ada_Version;
1159                Ptr := Ptr + 4;
1160
1161             --  Switch cancellation, currently only -gnat-p is allowed.
1162             --  All we do here is the error checking, since the actual
1163             --  processing for switch cancellation is done by calls to
1164             --  Switch_Subsequently_Cancelled at the appropriate point.
1165
1166             when '-' =>
1167
1168                --  Simple ignore -gnat-p
1169
1170                if Switch_Chars = "-gnat-p" then
1171                   return;
1172
1173                --  Any other occurrence of minus is ignored. This is for
1174                --  maximum compatibility with previous version which ignored
1175                --  all occurrences of minus.
1176
1177                else
1178                   Store_Switch := False;
1179                   Ptr := Ptr + 1;
1180                end if;
1181
1182             --  We ignore '/' in switches, this is historical, still needed???
1183
1184             when '/' =>
1185                Store_Switch := False;
1186
1187             --  Anything else is an error (illegal switch character)
1188
1189             when others =>
1190                Bad_Switch ("-gnat" & Switch_Chars (Ptr .. Max));
1191             end case;
1192
1193             if Store_Switch then
1194                Store_Compilation_Switch
1195                  ("-gnat" & Switch_Chars (First_Char .. Ptr - 1));
1196             end if;
1197
1198             First_Switch := False;
1199          end loop;
1200       end if;
1201    end Scan_Front_End_Switches;
1202
1203    -----------------------------------
1204    -- Switch_Subsequently_Cancelled --
1205    -----------------------------------
1206
1207    function Switch_Subsequently_Cancelled
1208      (C        : String;
1209       Args     : String_List;
1210       Arg_Rank : Positive) return Boolean
1211    is
1212    begin
1213       --  Loop through arguments following the current one
1214
1215       for Arg in Arg_Rank + 1 .. Args'Last loop
1216          if Args (Arg).all = "-gnat-" & C then
1217             return True;
1218          end if;
1219       end loop;
1220
1221       --  No match found, not cancelled
1222
1223       return False;
1224    end Switch_Subsequently_Cancelled;
1225
1226 end Switch.C;