OSDN Git Service

2004-03-29 Javier Miranda <miranda@gnat.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-2004 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 2,  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 COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with GNAT.OS_Lib; use GNAT.OS_Lib;
28
29 with Debug;    use Debug;
30 with Lib;      use Lib;
31 with Osint;    use Osint;
32 with Opt;      use Opt;
33 with Prepcomp; use Prepcomp;
34 with Types;    use Types;
35 with Validsw;  use Validsw;
36 with Stylesw;  use Stylesw;
37
38 with System.WCh_Con; use System.WCh_Con;
39
40 package body Switch.C is
41
42    RTS_Specified : String_Access := null;
43    --  Used to detect multiple use of --RTS= flag
44
45    -----------------------------
46    -- Scan_Front_End_Switches --
47    -----------------------------
48
49    procedure Scan_Front_End_Switches (Switch_Chars : String) is
50       Switch_Starts_With_Gnat : Boolean;
51       --  True if first four switch characters are "gnat"
52
53       First_Switch : Boolean := True;
54       --  False for all but first switch
55
56       Ptr : Integer := Switch_Chars'First;
57       Max : constant Integer := Switch_Chars'Last;
58       C   : Character := ' ';
59       Dot : Boolean;
60
61       Store_Switch : Boolean  := True;
62       First_Char   : Integer  := Ptr;
63       Storing      : String   := Switch_Chars;
64       First_Stored : Positive := Ptr + 1;
65       --  The above need comments ???
66
67    begin
68       --  Skip past the initial character (must be the switch character)
69
70       if Ptr = Max then
71          raise Bad_Switch;
72       else
73          Ptr := Ptr + 1;
74       end if;
75
76       --  Remove "gnat" from the switch, if present
77
78       Switch_Starts_With_Gnat :=
79         Ptr + 3 <= Max and then Switch_Chars (Ptr .. Ptr + 3) = "gnat";
80
81       if Switch_Starts_With_Gnat then
82          Ptr := Ptr + 4;
83          First_Stored := Ptr;
84       end if;
85
86       --  Loop to scan through switches given in switch string
87
88       while Ptr <= Max loop
89          Store_Switch := True;
90          First_Char := Ptr;
91          C := Switch_Chars (Ptr);
92
93          --  Processing for a switch
94
95          case Switch_Starts_With_Gnat is
96
97             when False =>
98
99             --  There are few front-end switches that
100             --  do not start with -gnat: -I, --RTS
101
102                if Switch_Chars (Ptr) = 'I' then
103                   Store_Switch := False;
104
105                   Ptr := Ptr + 1;
106
107                   if Ptr > Max then
108                      raise Bad_Switch;
109                   end if;
110
111                   --  Find out whether this is a -I- or regular -Ixxx switch
112
113                   if Ptr = Max and then Switch_Chars (Ptr) = '-' then
114                      Look_In_Primary_Dir := False;
115
116                   else
117                      Add_Src_Search_Dir (Switch_Chars (Ptr .. Max));
118                   end if;
119
120                   Ptr := Max + 1;
121
122                --  Processing of the --RTS switch. --RTS has been modified by
123                --  gcc and is now of the form -fRTS
124
125                elsif Ptr + 3 <= Max
126                  and then Switch_Chars (Ptr .. Ptr + 3) = "fRTS"
127                then
128                   Ptr := Ptr + 1;
129
130                   if Ptr + 4 > Max
131                     or else Switch_Chars (Ptr + 3) /= '='
132                   then
133                      Osint.Fail ("missing path for --RTS");
134                   else
135                      --  Check that this is the first time --RTS is specified
136                      --  or if it is not the first time, the same path has
137                      --  been specified.
138
139                      if RTS_Specified = null then
140                         RTS_Specified :=
141                           new String'(Switch_Chars (Ptr + 4 .. Max));
142
143                      elsif
144                        RTS_Specified.all /= Switch_Chars (Ptr + 4 .. Max)
145                      then
146                         Osint.Fail
147                           ("--RTS cannot be specified multiple times");
148                      end if;
149
150                      --  Valid --RTS switch
151
152                      Opt.No_Stdinc := True;
153                      Opt.RTS_Switch := True;
154
155                      RTS_Src_Path_Name := Get_RTS_Search_Dir
156                                             (Switch_Chars (Ptr + 4 .. Max),
157                                              Include);
158                      RTS_Lib_Path_Name := Get_RTS_Search_Dir
159                                             (Switch_Chars (Ptr + 4 .. Max),
160                                              Objects);
161
162                      if RTS_Src_Path_Name /= null and then
163                         RTS_Lib_Path_Name /= null
164                      then
165                         Ptr := Max + 1;
166
167                      elsif RTS_Src_Path_Name = null and then
168                            RTS_Lib_Path_Name = null
169                      then
170                         Osint.Fail ("RTS path not valid: missing " &
171                                     "adainclude and adalib directories");
172
173                      elsif RTS_Src_Path_Name = null then
174                         Osint.Fail ("RTS path not valid: missing " &
175                                     "adainclude directory");
176
177                      elsif RTS_Lib_Path_Name = null then
178                         Osint.Fail ("RTS path not valid: missing " &
179                                     "adalib directory");
180                      end if;
181                   end if;
182                else
183                   raise Bad_Switch;
184                end if;
185
186          when True =>
187
188             --  Process -gnat* options
189
190             case C is
191
192             when 'a' =>
193                Ptr := Ptr + 1;
194                Assertions_Enabled := True;
195
196             --  Processing for A switch
197
198             when 'A' =>
199                Ptr := Ptr + 1;
200                Config_File := False;
201
202             --  Processing for b switch
203
204             when 'b' =>
205                Ptr := Ptr + 1;
206                Brief_Output := True;
207
208             --  Processing for c switch
209
210             when 'c' =>
211                if not First_Switch then
212                   Osint.Fail
213                     ("-gnatc must be first if combined with other switches");
214                end if;
215
216                Ptr := Ptr + 1;
217                Operating_Mode := Check_Semantics;
218
219                if Tree_Output then
220                   ASIS_Mode := True;
221                end if;
222
223             --  Processing for C switch
224
225             when 'C' =>
226                Ptr := Ptr + 1;
227                Scan_Pos (Switch_Chars, 999, Ptr, Multiple_Unit_Index);
228
229             --  Processing for d switch
230
231             when 'd' =>
232                Store_Switch := False;
233                Storing (First_Stored) := 'd';
234                Dot := False;
235
236                --  Note: for the debug switch, the remaining characters in this
237                --  switch field must all be debug flags, since all valid switch
238                --  characters are also valid debug characters.
239
240                --  Loop to scan out debug flags
241
242                while Ptr < Max loop
243                   Ptr := Ptr + 1;
244                   C := Switch_Chars (Ptr);
245                   exit when C = ASCII.NUL or else C = '/' or else C = '-';
246
247                   if C in '1' .. '9' or else
248                      C in 'a' .. 'z' or else
249                      C in 'A' .. 'Z'
250                   then
251                      if Dot then
252                         Set_Dotted_Debug_Flag (C);
253                         Storing (First_Stored + 1) := '.';
254                         Storing (First_Stored + 2) := C;
255                         Store_Compilation_Switch
256                           (Storing (Storing'First .. First_Stored + 2));
257                         Dot := False;
258
259                      else
260                         Set_Debug_Flag (C);
261                         Storing (First_Stored + 1) := C;
262                         Store_Compilation_Switch
263                           (Storing (Storing'First .. First_Stored + 1));
264                      end if;
265
266                   elsif C = '.' then
267                      Dot := True;
268
269                   else
270                      raise Bad_Switch;
271                   end if;
272                end loop;
273
274                --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
275                --  is for backwards compatibility with old versions and usage.
276
277                if Debug_Flag_XX then
278                   Zero_Cost_Exceptions_Set := True;
279                   Zero_Cost_Exceptions_Val := True;
280                end if;
281
282                return;
283
284             --  Processing for D switch
285
286             when 'D' =>
287                Ptr := Ptr + 1;
288
289                --  Note: -gnatD also sets -gnatx (to turn off cross-reference
290                --  generation in the ali file) since otherwise this generation
291                --  gets confused by the "wrong" Sloc values put in the tree.
292
293                Debug_Generated_Code := True;
294                Xref_Active := False;
295                Set_Debug_Flag ('g');
296
297             --  -gnate? (extended switches)
298
299             when 'e' =>
300                Ptr := Ptr + 1;
301
302                --  The -gnate? switches are all double character switches
303                --  so we must always have a character after the e.
304
305                if Ptr > Max then
306                   raise Bad_Switch;
307                end if;
308
309                case Switch_Chars (Ptr) is
310
311                   --  -gnatec (configuration pragmas)
312
313                   when 'c' =>
314                      Store_Switch := False;
315                      Ptr := Ptr + 1;
316
317                      --  There may be an equal sign between -gnatec and
318                      --  the path name of the config file.
319
320                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
321                         Ptr := Ptr + 1;
322                      end if;
323
324                      if Ptr > Max then
325                         raise Bad_Switch;
326                      end if;
327
328                      declare
329                         Config_File_Name : constant String_Access :=
330                                              new String'
331                                                   (Switch_Chars (Ptr .. Max));
332
333                      begin
334                         if Config_File_Names = null then
335                            Config_File_Names :=
336                              new String_List'(1 => Config_File_Name);
337
338                         else
339                            declare
340                               New_Names : constant String_List_Access :=
341                                             new String_List
342                                               (1 ..
343                                                Config_File_Names'Length + 1);
344
345                            begin
346                               for Index in Config_File_Names'Range loop
347                                  New_Names (Index) :=
348                                    Config_File_Names (Index);
349                                  Config_File_Names (Index) := null;
350                               end loop;
351
352                               New_Names (New_Names'Last) := Config_File_Name;
353                               Free (Config_File_Names);
354                               Config_File_Names := New_Names;
355                            end;
356                         end if;
357                      end;
358
359                      return;
360
361                   --  -gnateD switch (symbol definition)
362
363                   when 'D' =>
364                      Store_Switch := False;
365                      Ptr := Ptr + 1;
366
367                      if Ptr > Max then
368                         raise Bad_Switch;
369                      end if;
370
371                      Add_Symbol_Definition (Switch_Chars (Ptr .. Max));
372
373                      --  Store the switch
374
375                      Storing (First_Stored .. First_Stored + 1) := "eD";
376                      Storing
377                        (First_Stored + 2 .. First_Stored + Max - Ptr + 2) :=
378                        Switch_Chars (Ptr .. Max);
379                      Store_Compilation_Switch (Storing
380                               (Storing'First .. First_Stored + Max - Ptr + 2));
381                      return;
382
383                   --  -gnatef (full source path for brief error messages)
384
385                   when 'f' =>
386                      Store_Switch := False;
387                      Ptr := Ptr + 1;
388                      Full_Path_Name_For_Brief_Errors := True;
389                      return;
390
391                   --  -gnatem (mapping file)
392
393                   when 'm' =>
394                      Store_Switch := False;
395                      Ptr := Ptr + 1;
396
397                      --  There may be an equal sign between -gnatem and
398                      --  the path name of the mapping file.
399
400                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
401                         Ptr := Ptr + 1;
402                      end if;
403
404                      if Ptr > Max then
405                         raise Bad_Switch;
406                      end if;
407
408                      Mapping_File_Name :=
409                        new String'(Switch_Chars (Ptr .. Max));
410                      return;
411
412                   --  -gnatep (preprocessing data file)
413
414                   when 'p' =>
415                      Store_Switch := False;
416                      Ptr := Ptr + 1;
417
418                      --  There may be an equal sign between -gnatep and
419                      --  the path name of the mapping file.
420
421                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
422                         Ptr := Ptr + 1;
423                      end if;
424
425                      if Ptr > Max then
426                         raise Bad_Switch;
427                      end if;
428
429                      Preprocessing_Data_File :=
430                        new String'(Switch_Chars (Ptr .. Max));
431
432                      --  Store the switch.
433                      --  Because we may store a longer switch (we normalize
434                      --  to -gnatep=), use a local variable.
435
436                      declare
437                         To_Store : String
438                           (1 .. Preprocessing_Data_File'Length + 8);
439
440                      begin
441                         To_Store (1 .. 8) := "-gnatep=";
442                         To_Store (9 .. Preprocessing_Data_File'Length + 8) :=
443                           Preprocessing_Data_File.all;
444                         Store_Compilation_Switch (To_Store);
445                      end;
446
447                   return;
448
449                   --  All other -gnate? switches are unassigned
450
451                   when others =>
452                      raise Bad_Switch;
453                end case;
454
455             --  -gnatE (dynamic elaboration checks)
456
457             when 'E' =>
458                Ptr := Ptr + 1;
459                Dynamic_Elaboration_Checks := True;
460
461             --  -gnatf (full error messages)
462
463             when 'f' =>
464                Ptr := Ptr + 1;
465                All_Errors_Mode := True;
466
467             --  Processing for F switch
468
469             when 'F' =>
470                Ptr := Ptr + 1;
471                External_Name_Exp_Casing := Uppercase;
472                External_Name_Imp_Casing := Uppercase;
473
474             --  Processing for g switch
475
476             when 'g' =>
477                Ptr := Ptr + 1;
478                GNAT_Mode := True;
479                Identifier_Character_Set := 'n';
480                System_Extend_Unit := Empty;
481                Warning_Mode := Treat_As_Error;
482
483                --  Set default warnings (basically -gnatwa)
484
485                Check_Unreferenced           := True;
486                Check_Unreferenced_Formals   := True;
487                Check_Withs                  := True;
488                Constant_Condition_Warnings  := True;
489                Implementation_Unit_Warnings := True;
490                Ineffective_Inline_Warnings  := True;
491                Warn_On_Constant             := True;
492                Warn_On_Export_Import        := True;
493                Warn_On_Modified_Unread      := True;
494                Warn_On_No_Value_Assigned    := True;
495                Warn_On_Obsolescent_Feature  := True;
496                Warn_On_Redundant_Constructs := True;
497                Warn_On_Unchecked_Conversion := True;
498                Warn_On_Unrecognized_Pragma  := True;
499
500                Set_Default_Style_Check_Options;
501
502             --  Processing for G switch
503
504             when 'G' =>
505                Ptr := Ptr + 1;
506                Print_Generated_Code := True;
507
508             --  Processing for h switch
509
510             when 'h' =>
511                Ptr := Ptr + 1;
512                Usage_Requested := True;
513
514             --  Processing for H switch
515
516             when 'H' =>
517                Ptr := Ptr + 1;
518                HLO_Active := True;
519
520             --  Processing for i switch
521
522             when 'i' =>
523                if Ptr = Max then
524                   raise Bad_Switch;
525                end if;
526
527                Ptr := Ptr + 1;
528                C := Switch_Chars (Ptr);
529
530                if C in '1' .. '5'
531                  or else C = '8'
532                  or else C = '9'
533                  or else C = 'p'
534                  or else C = 'f'
535                  or else C = 'n'
536                  or else C = 'w'
537                then
538                   Identifier_Character_Set := C;
539                   Ptr := Ptr + 1;
540
541                else
542                   raise Bad_Switch;
543                end if;
544
545             --  Processing for k switch
546
547             when 'k' =>
548                Ptr := Ptr + 1;
549                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_File_Name_Length);
550
551             --  Processing for l switch
552
553             when 'l' =>
554                Ptr := Ptr + 1;
555                Full_List := True;
556
557             --  Processing for L switch
558
559             when 'L' =>
560                Ptr := Ptr + 1;
561                Zero_Cost_Exceptions_Set := True;
562                Zero_Cost_Exceptions_Val := False;
563
564             --  Processing for m switch
565
566             when 'm' =>
567                Ptr := Ptr + 1;
568                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
569
570             --  Processing for n switch
571
572             when 'n' =>
573                Ptr := Ptr + 1;
574                Inline_Active := True;
575
576             --  Processing for N switch
577
578             when 'N' =>
579                Ptr := Ptr + 1;
580                Inline_Active := True;
581                Front_End_Inlining := True;
582
583             --  Processing for o switch
584
585             when 'o' =>
586                Ptr := Ptr + 1;
587                Suppress_Options (Overflow_Check) := False;
588                Opt.Enable_Overflow_Checks := True;
589
590             --  Processing for O switch
591
592             when 'O' =>
593                Store_Switch := False;
594                Ptr := Ptr + 1;
595                Output_File_Name_Present := True;
596
597             --  Processing for p switch
598
599             when 'p' =>
600                Ptr := Ptr + 1;
601                Suppress_Options           := (others => True);
602                Validity_Checks_On         := False;
603                Opt.Suppress_Checks        := True;
604                Opt.Enable_Overflow_Checks := False;
605
606             --  Processing for P switch
607
608             when 'P' =>
609                Ptr := Ptr + 1;
610                Polling_Required := True;
611
612             --  Processing for q switch
613
614             when 'q' =>
615                Ptr := Ptr + 1;
616                Try_Semantics := True;
617
618             --  Processing for q switch
619
620             when 'Q' =>
621                Ptr := Ptr + 1;
622                Force_ALI_Tree_File := True;
623                Try_Semantics := True;
624
625             --  Processing for R switch
626
627             when 'R' =>
628                Ptr := Ptr + 1;
629                Back_Annotate_Rep_Info := True;
630                List_Representation_Info := 1;
631
632                while Ptr <= Max loop
633                   C := Switch_Chars (Ptr);
634
635                   if C in '1' .. '3' then
636                      List_Representation_Info :=
637                        Character'Pos (C) - Character'Pos ('0');
638
639                   elsif Switch_Chars (Ptr) = 's' then
640                      List_Representation_Info_To_File := True;
641
642                   elsif Switch_Chars (Ptr) = 'm' then
643                      List_Representation_Info_Mechanisms := True;
644
645                   else
646                      raise Bad_Switch;
647                   end if;
648
649                   Ptr := Ptr + 1;
650                end loop;
651
652             --  Processing for s switch
653
654             when 's' =>
655                if not First_Switch then
656                   Osint.Fail
657                     ("-gnats must be first if combined with other switches");
658                end if;
659
660                Ptr := Ptr + 1;
661                Operating_Mode := Check_Syntax;
662
663             --  Processing for S switch
664
665             when 'S' =>
666                Print_Standard := True;
667                Ptr := Ptr + 1;
668
669             --  Processing for t switch
670
671             when 't' =>
672                Ptr := Ptr + 1;
673                Tree_Output := True;
674
675                if Operating_Mode = Check_Semantics then
676                   ASIS_Mode := True;
677                end if;
678
679                Back_Annotate_Rep_Info := True;
680
681             --  Processing for T switch
682
683             when 'T' =>
684                Ptr := Ptr + 1;
685                Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor);
686
687             --  Processing for u switch
688
689             when 'u' =>
690                Ptr := Ptr + 1;
691                List_Units := True;
692
693             --  Processing for U switch
694
695             when 'U' =>
696                Ptr := Ptr + 1;
697                Unique_Error_Tag := True;
698
699             --  Processing for v switch
700
701             when 'v' =>
702                Ptr := Ptr + 1;
703                Verbose_Mode := True;
704
705             --  Processing for V switch
706
707             when 'V' =>
708                Store_Switch := False;
709                Storing (First_Stored) := 'V';
710                Ptr := Ptr + 1;
711
712                if Ptr > Max then
713                   raise Bad_Switch;
714
715                else
716                   declare
717                      OK  : Boolean;
718
719                   begin
720                      Set_Validity_Check_Options
721                        (Switch_Chars (Ptr .. Max), OK, Ptr);
722
723                      if not OK then
724                         raise Bad_Switch;
725                      end if;
726
727                      for Index in First_Char + 1 .. Max loop
728                         Storing (First_Stored + 1) :=
729                           Switch_Chars (Index);
730                         Store_Compilation_Switch
731                           (Storing (Storing'First .. First_Stored + 1));
732                      end loop;
733                   end;
734                end if;
735
736                Ptr := Max + 1;
737
738             --  Processing for w switch
739
740             when 'w' =>
741                Store_Switch := False;
742                Storing (First_Stored) := 'w';
743                Ptr := Ptr + 1;
744
745                if Ptr > Max then
746                   raise Bad_Switch;
747                end if;
748
749                while Ptr <= Max loop
750                   C := Switch_Chars (Ptr);
751
752                   case C is
753                      when 'a' =>
754                         Check_Unreferenced              := True;
755                         Check_Unreferenced_Formals      := True;
756                         Check_Withs                     := True;
757                         Constant_Condition_Warnings     := True;
758                         Implementation_Unit_Warnings    := True;
759                         Ineffective_Inline_Warnings     := True;
760                         Warn_On_Constant                := True;
761                         Warn_On_Export_Import           := True;
762                         Warn_On_Modified_Unread         := True;
763                         Warn_On_No_Value_Assigned       := True;
764                         Warn_On_Obsolescent_Feature     := True;
765                         Warn_On_Redundant_Constructs    := True;
766                         Warn_On_Unchecked_Conversion    := True;
767                         Warn_On_Unrecognized_Pragma     := True;
768
769                      when 'A' =>
770                         Check_Unreferenced              := False;
771                         Check_Unreferenced_Formals      := False;
772                         Check_Withs                     := False;
773                         Constant_Condition_Warnings     := False;
774                         Elab_Warnings                   := False;
775                         Implementation_Unit_Warnings    := False;
776                         Ineffective_Inline_Warnings     := False;
777                         Warn_On_Constant                := False;
778                         Warn_On_Dereference             := False;
779                         Warn_On_Export_Import           := False;
780                         Warn_On_Hiding                  := False;
781                         Warn_On_Modified_Unread         := False;
782                         Warn_On_No_Value_Assigned       := False;
783                         Warn_On_Obsolescent_Feature     := False;
784                         Warn_On_Redundant_Constructs    := False;
785                         Warn_On_Unchecked_Conversion    := False;
786                         Warn_On_Unrecognized_Pragma     := False;
787
788                      when 'c' =>
789                         Constant_Condition_Warnings     := True;
790
791                      when 'C' =>
792                         Constant_Condition_Warnings     := False;
793
794                      when 'd' =>
795                         Warn_On_Dereference             := True;
796
797                      when 'D' =>
798                         Warn_On_Dereference             := False;
799
800                      when 'e' =>
801                         Warning_Mode                    := Treat_As_Error;
802
803                      when 'f' =>
804                         Check_Unreferenced_Formals      := True;
805
806                      when 'F' =>
807                         Check_Unreferenced_Formals      := False;
808
809                      when 'g' =>
810                         Warn_On_Unrecognized_Pragma     := True;
811
812                      when 'G' =>
813                         Warn_On_Unrecognized_Pragma     := False;
814
815                      when 'h' =>
816                         Warn_On_Hiding                  := True;
817
818                      when 'H' =>
819                         Warn_On_Hiding                  := False;
820
821                      when 'i' =>
822                         Implementation_Unit_Warnings    := True;
823
824                      when 'I' =>
825                         Implementation_Unit_Warnings    := False;
826
827                      when 'j' =>
828                         Warn_On_Obsolescent_Feature     := True;
829
830                      when 'J' =>
831                         Warn_On_Obsolescent_Feature     := False;
832
833                      when 'k' =>
834                         Warn_On_Constant                := True;
835
836                      when 'K' =>
837                         Warn_On_Constant                := False;
838
839                      when 'l' =>
840                         Elab_Warnings                   := True;
841
842                      when 'L' =>
843                         Elab_Warnings                   := False;
844
845                      when 'm' =>
846                         Warn_On_Modified_Unread         := True;
847
848                      when 'M' =>
849                         Warn_On_Modified_Unread         := False;
850
851                      when 'n' =>
852                         Warning_Mode                    := Normal;
853
854                      when 'o' =>
855                         Address_Clause_Overlay_Warnings := True;
856
857                      when 'O' =>
858                         Address_Clause_Overlay_Warnings := False;
859
860                      when 'p' =>
861                         Ineffective_Inline_Warnings     := True;
862
863                      when 'P' =>
864                         Ineffective_Inline_Warnings     := False;
865
866                      when 'r' =>
867                         Warn_On_Redundant_Constructs    := True;
868
869                      when 'R' =>
870                         Warn_On_Redundant_Constructs    := False;
871
872                      when 's' =>
873                         Warning_Mode                    := Suppress;
874
875                      when 'u' =>
876                         Check_Unreferenced              := True;
877                         Check_Withs                     := True;
878                         Check_Unreferenced_Formals      := True;
879
880                      when 'U' =>
881                         Check_Unreferenced              := False;
882                         Check_Withs                     := False;
883                         Check_Unreferenced_Formals      := False;
884
885                      when 'v' =>
886                         Warn_On_No_Value_Assigned       := True;
887
888                      when 'V' =>
889                         Warn_On_No_Value_Assigned       := False;
890
891                      when 'x' =>
892                         Warn_On_Export_Import           := True;
893
894                      when 'X' =>
895                         Warn_On_Export_Import           := False;
896
897                      when 'z' =>
898                         Warn_On_Unchecked_Conversion    := True;
899
900                      when 'Z' =>
901                         Warn_On_Unchecked_Conversion    := False;
902
903                         --  Allow and ignore 'w' so that the old
904                         --  format (e.g. -gnatwuwl) will work.
905
906                      when 'w' =>
907                         null;
908
909                      when others =>
910                         raise Bad_Switch;
911                   end case;
912
913                   if C /= 'w' then
914                      Storing (First_Stored + 1) := C;
915                      Store_Compilation_Switch
916                        (Storing (Storing'First .. First_Stored + 1));
917                   end if;
918
919                   Ptr := Ptr + 1;
920                end loop;
921
922                return;
923
924             --  Processing for W switch
925
926             when 'W' =>
927                Ptr := Ptr + 1;
928
929                if Ptr > Max then
930                   raise Bad_Switch;
931                end if;
932
933                for J in WC_Encoding_Method loop
934                   if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
935                      Wide_Character_Encoding_Method := J;
936                      exit;
937
938                   elsif J = WC_Encoding_Method'Last then
939                      raise Bad_Switch;
940                   end if;
941                end loop;
942
943                Upper_Half_Encoding :=
944                  Wide_Character_Encoding_Method in
945                  WC_Upper_Half_Encoding_Method;
946
947                Ptr := Ptr + 1;
948
949             --  Processing for x switch
950
951             when 'x' =>
952                Ptr := Ptr + 1;
953                Xref_Active := False;
954
955             --  Processing for X switch
956
957             when 'X' =>
958                Ptr := Ptr + 1;
959                Extensions_Allowed := True;
960
961             --  Processing for y switch
962
963             when 'y' =>
964                Ptr := Ptr + 1;
965
966                if Ptr > Max then
967                   Set_Default_Style_Check_Options;
968
969                else
970                   Store_Switch := False;
971                   Storing (First_Stored) := 'y';
972
973                   declare
974                      OK  : Boolean;
975                      Last_Stored : Integer;
976
977                   begin
978                      Set_Style_Check_Options
979                        (Switch_Chars (Ptr .. Max), OK, Ptr);
980
981                      if not OK then
982                         raise Bad_Switch;
983                      end if;
984
985                      Ptr := First_Char + 1;
986
987                      while Ptr <= Max loop
988                         Last_Stored := First_Stored + 1;
989                         Storing (Last_Stored) := Switch_Chars (Ptr);
990
991                         if Switch_Chars (Ptr) = 'M' then
992                            loop
993                               Ptr := Ptr + 1;
994                               exit when Ptr > Max
995                                 or else Switch_Chars (Ptr) not in '0' .. '9';
996                               Last_Stored := Last_Stored + 1;
997                               Storing (Last_Stored) := Switch_Chars (Ptr);
998                            end loop;
999
1000                         else
1001                            Ptr := Ptr + 1;
1002                         end if;
1003
1004                         Store_Compilation_Switch
1005                           (Storing (Storing'First .. Last_Stored));
1006                      end loop;
1007                   end;
1008                end if;
1009
1010             --  Processing for z switch
1011
1012             when 'z' =>
1013                Ptr := Ptr + 1;
1014
1015                --  Allowed for compiler only if this is the only
1016                --  -z switch, we do not allow multiple occurrences
1017
1018                if Distribution_Stub_Mode = No_Stubs then
1019                   case Switch_Chars (Ptr) is
1020                      when 'r' =>
1021                         Distribution_Stub_Mode := Generate_Receiver_Stub_Body;
1022
1023                      when 'c' =>
1024                         Distribution_Stub_Mode := Generate_Caller_Stub_Body;
1025
1026                      when others =>
1027                         raise Bad_Switch;
1028                   end case;
1029
1030                   Ptr := Ptr + 1;
1031
1032                end if;
1033
1034             --  Processing for Z switch
1035
1036             when 'Z' =>
1037                Ptr := Ptr + 1;
1038                Zero_Cost_Exceptions_Set := True;
1039                Zero_Cost_Exceptions_Val := True;
1040
1041             --  Processing for 83 switch
1042
1043             when '8' =>
1044
1045                if Ptr = Max then
1046                   raise Bad_Switch;
1047                end if;
1048
1049                Ptr := Ptr + 1;
1050
1051                if Switch_Chars (Ptr) /= '3' then
1052                   raise Bad_Switch;
1053                else
1054                   Ptr := Ptr + 1;
1055                   Ada_95 := False;
1056                   Ada_83 := True;
1057                end if;
1058
1059             --  Ignore extra switch character
1060
1061             when '/' | '-' =>
1062                Ptr := Ptr + 1;
1063
1064             --  Anything else is an error (illegal switch character)
1065
1066             when others =>
1067                raise Bad_Switch;
1068             end case;
1069          end case;
1070
1071          if Store_Switch then
1072             Storing (First_Stored .. First_Stored + Ptr - First_Char - 1) :=
1073               Switch_Chars (First_Char .. Ptr - 1);
1074             Store_Compilation_Switch
1075               (Storing (Storing'First .. First_Stored + Ptr - First_Char - 1));
1076          end if;
1077
1078          First_Switch := False;
1079       end loop;
1080
1081    exception
1082       when Bad_Switch =>
1083          Osint.Fail ("invalid switch: ", (1 => C));
1084
1085       when Bad_Switch_Value =>
1086          Osint.Fail ("numeric value out of range for switch: ", (1 => C));
1087
1088       when Missing_Switch_Value =>
1089          Osint.Fail ("missing numeric value for switch: ", (1 => C));
1090
1091    end Scan_Front_End_Switches;
1092
1093 end Switch.C;