OSDN Git Service

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