OSDN Git Service

2005-03-29 Robert Dewar <dewar@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-2005 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 d switch
224
225             when 'd' =>
226                Store_Switch := False;
227                Storing (First_Stored) := 'd';
228                Dot := False;
229
230                --  Note: for the debug switch, the remaining characters in this
231                --  switch field must all be debug flags, since all valid switch
232                --  characters are also valid debug characters.
233
234                --  Loop to scan out debug flags
235
236                while Ptr < Max loop
237                   Ptr := Ptr + 1;
238                   C := Switch_Chars (Ptr);
239                   exit when C = ASCII.NUL or else C = '/' or else C = '-';
240
241                   if C in '1' .. '9' or else
242                      C in 'a' .. 'z' or else
243                      C in 'A' .. 'Z'
244                   then
245                      if Dot then
246                         Set_Dotted_Debug_Flag (C);
247                         Storing (First_Stored + 1) := '.';
248                         Storing (First_Stored + 2) := C;
249                         Store_Compilation_Switch
250                           (Storing (Storing'First .. First_Stored + 2));
251                         Dot := False;
252
253                      else
254                         Set_Debug_Flag (C);
255                         Storing (First_Stored + 1) := C;
256                         Store_Compilation_Switch
257                           (Storing (Storing'First .. First_Stored + 1));
258                      end if;
259
260                   elsif C = '.' then
261                      Dot := True;
262
263                   else
264                      raise Bad_Switch;
265                   end if;
266                end loop;
267
268                --  Make sure Zero_Cost_Exceptions is set if gnatdX set. This
269                --  is for backwards compatibility with old versions and usage.
270
271                if Debug_Flag_XX then
272                   Zero_Cost_Exceptions_Set := True;
273                   Zero_Cost_Exceptions_Val := True;
274                end if;
275
276                return;
277
278             --  Processing for D switch
279
280             when 'D' =>
281                Ptr := Ptr + 1;
282
283                --  Note: -gnatD also sets -gnatx (to turn off cross-reference
284                --  generation in the ali file) since otherwise this generation
285                --  gets confused by the "wrong" Sloc values put in the tree.
286
287                Debug_Generated_Code := True;
288                Xref_Active := False;
289                Set_Debug_Flag ('g');
290
291             --  -gnate? (extended switches)
292
293             when 'e' =>
294                Ptr := Ptr + 1;
295
296                --  The -gnate? switches are all double character switches
297                --  so we must always have a character after the e.
298
299                if Ptr > Max then
300                   raise Bad_Switch;
301                end if;
302
303                case Switch_Chars (Ptr) is
304
305                   --  -gnatec (configuration pragmas)
306
307                   when 'c' =>
308                      Store_Switch := False;
309                      Ptr := Ptr + 1;
310
311                      --  There may be an equal sign between -gnatec and
312                      --  the path name of the config file.
313
314                      if Ptr <= Max and then Switch_Chars (Ptr) = '=' then
315                         Ptr := Ptr + 1;
316                      end if;
317
318                      if Ptr > Max then
319                         raise Bad_Switch;
320                      end if;
321
322                      declare
323                         Config_File_Name : constant String_Access :=
324                                              new String'
325                                                   (Switch_Chars (Ptr .. Max));
326
327                      begin
328                         if Config_File_Names = null then
329                            Config_File_Names :=
330                              new String_List'(1 => Config_File_Name);
331
332                         else
333                            declare
334                               New_Names : constant String_List_Access :=
335                                             new String_List
336                                               (1 ..
337                                                Config_File_Names'Length + 1);
338
339                            begin
340                               for Index in Config_File_Names'Range loop
341                                  New_Names (Index) :=
342                                    Config_File_Names (Index);
343                                  Config_File_Names (Index) := null;
344                               end loop;
345
346                               New_Names (New_Names'Last) := Config_File_Name;
347                               Free (Config_File_Names);
348                               Config_File_Names := New_Names;
349                            end;
350                         end if;
351                      end;
352
353                      return;
354
355                   --  -gnateD switch (symbol definition)
356
357                   when 'D' =>
358                      Store_Switch := False;
359                      Ptr := Ptr + 1;
360
361                      if Ptr > Max then
362                         raise Bad_Switch;
363                      end if;
364
365                      Add_Symbol_Definition (Switch_Chars (Ptr .. Max));
366
367                      --  Store the switch
368
369                      Storing (First_Stored .. First_Stored + 1) := "eD";
370                      Storing
371                        (First_Stored + 2 .. First_Stored + Max - Ptr + 2) :=
372                        Switch_Chars (Ptr .. Max);
373                      Store_Compilation_Switch (Storing
374                               (Storing'First .. First_Stored + Max - Ptr + 2));
375                      return;
376
377                   --  -gnatef (full source path for brief error messages)
378
379                   when 'f' =>
380                      Store_Switch := False;
381                      Ptr := Ptr + 1;
382                      Full_Path_Name_For_Brief_Errors := True;
383                      return;
384
385                   --  -gnateI (index of unit in multi-unit source)
386
387                   when 'I' =>
388                      Ptr := Ptr + 1;
389                      Scan_Pos (Switch_Chars, Max, Ptr, Multiple_Unit_Index);
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                   when 'z' =>
450                      Store_Switch := False;
451                      Disable_Switch_Storing;
452                      Ptr := Ptr + 1;
453
454                   --  All other -gnate? switches are unassigned
455
456                   when others =>
457                      raise Bad_Switch;
458                end case;
459
460             --  -gnatE (dynamic elaboration checks)
461
462             when 'E' =>
463                Ptr := Ptr + 1;
464                Dynamic_Elaboration_Checks := True;
465
466             --  -gnatf (full error messages)
467
468             when 'f' =>
469                Ptr := Ptr + 1;
470                All_Errors_Mode := True;
471
472             --  Processing for F switch
473
474             when 'F' =>
475                Ptr := Ptr + 1;
476                External_Name_Exp_Casing := Uppercase;
477                External_Name_Imp_Casing := Uppercase;
478
479             --  Processing for g switch
480
481             when 'g' =>
482                Ptr := Ptr + 1;
483                GNAT_Mode := True;
484                Identifier_Character_Set := 'n';
485                System_Extend_Unit := Empty;
486                Warning_Mode := Treat_As_Error;
487
488                --  Set default warnings for -gnatg (same set as -gnatwa)
489
490                Check_Unreferenced           := True;
491                Check_Unreferenced_Formals   := True;
492                Check_Withs                  := True;
493                Constant_Condition_Warnings  := True;
494                Implementation_Unit_Warnings := True;
495                Ineffective_Inline_Warnings  := True;
496                Warn_On_Bad_Fixed_Value      := True;
497                Warn_On_Constant             := True;
498                Warn_On_Export_Import        := True;
499                Warn_On_Modified_Unread      := True;
500                Warn_On_No_Value_Assigned    := True;
501                Warn_On_Obsolescent_Feature  := True;
502                Warn_On_Redundant_Constructs := True;
503                Warn_On_Unchecked_Conversion := True;
504                Warn_On_Unrecognized_Pragma  := True;
505
506                Set_Style_Check_Options ("3abcdefhiklmnprst");
507
508             --  Processing for G switch
509
510             when 'G' =>
511                Ptr := Ptr + 1;
512                Print_Generated_Code := True;
513
514             --  Processing for h switch
515
516             when 'h' =>
517                Ptr := Ptr + 1;
518                Usage_Requested := True;
519
520             --  Processing for H switch
521
522             when 'H' =>
523                Ptr := Ptr + 1;
524                HLO_Active := True;
525
526             --  Processing for i switch
527
528             when 'i' =>
529                if Ptr = Max then
530                   raise Bad_Switch;
531                end if;
532
533                Ptr := Ptr + 1;
534                C := Switch_Chars (Ptr);
535
536                if C in '1' .. '5'
537                  or else C = '8'
538                  or else C = '9'
539                  or else C = 'p'
540                  or else C = 'f'
541                  or else C = 'n'
542                  or else C = 'w'
543                then
544                   Identifier_Character_Set := C;
545                   Ptr := Ptr + 1;
546
547                else
548                   raise Bad_Switch;
549                end if;
550
551             --  Processing for k switch
552
553             when 'k' =>
554                Ptr := Ptr + 1;
555                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_File_Name_Length);
556
557             --  Processing for l switch
558
559             when 'l' =>
560                Ptr := Ptr + 1;
561                Full_List := True;
562
563             --  Processing for L switch
564
565             when 'L' =>
566                Ptr := Ptr + 1;
567                Zero_Cost_Exceptions_Set := True;
568                Zero_Cost_Exceptions_Val := False;
569
570             --  Processing for m switch
571
572             when 'm' =>
573                Ptr := Ptr + 1;
574                Scan_Pos (Switch_Chars, Max, Ptr, Maximum_Errors);
575
576             --  Processing for n switch
577
578             when 'n' =>
579                Ptr := Ptr + 1;
580                Inline_Active := True;
581
582             --  Processing for N switch
583
584             when 'N' =>
585                Ptr := Ptr + 1;
586                Inline_Active := True;
587                Front_End_Inlining := True;
588
589             --  Processing for o switch
590
591             when 'o' =>
592                Ptr := Ptr + 1;
593                Suppress_Options (Overflow_Check) := False;
594                Opt.Enable_Overflow_Checks := True;
595
596             --  Processing for O switch
597
598             when 'O' =>
599                Store_Switch := False;
600                Ptr := Ptr + 1;
601                Output_File_Name_Present := True;
602
603             --  Processing for p switch
604
605             when 'p' =>
606                Ptr := Ptr + 1;
607                Suppress_Options           := (others => True);
608                Validity_Checks_On         := False;
609                Opt.Suppress_Checks        := True;
610                Opt.Enable_Overflow_Checks := False;
611
612             --  Processing for P switch
613
614             when 'P' =>
615                Ptr := Ptr + 1;
616                Polling_Required := True;
617
618             --  Processing for q switch
619
620             when 'q' =>
621                Ptr := Ptr + 1;
622                Try_Semantics := True;
623
624             --  Processing for q switch
625
626             when 'Q' =>
627                Ptr := Ptr + 1;
628                Force_ALI_Tree_File := True;
629                Try_Semantics := True;
630
631             --  Processing for R switch
632
633             when 'R' =>
634                Ptr := Ptr + 1;
635                Back_Annotate_Rep_Info := True;
636                List_Representation_Info := 1;
637
638                while Ptr <= Max loop
639                   C := Switch_Chars (Ptr);
640
641                   if C in '1' .. '3' then
642                      List_Representation_Info :=
643                        Character'Pos (C) - Character'Pos ('0');
644
645                   elsif Switch_Chars (Ptr) = 's' then
646                      List_Representation_Info_To_File := True;
647
648                   elsif Switch_Chars (Ptr) = 'm' then
649                      List_Representation_Info_Mechanisms := True;
650
651                   else
652                      raise Bad_Switch;
653                   end if;
654
655                   Ptr := Ptr + 1;
656                end loop;
657
658             --  Processing for s switch
659
660             when 's' =>
661                if not First_Switch then
662                   Osint.Fail
663                     ("-gnats must be first if combined with other switches");
664                end if;
665
666                Ptr := Ptr + 1;
667                Operating_Mode := Check_Syntax;
668
669             --  Processing for S switch
670
671             when 'S' =>
672                Print_Standard := True;
673                Ptr := Ptr + 1;
674
675             --  Processing for t switch
676
677             when 't' =>
678                Ptr := Ptr + 1;
679                Tree_Output := True;
680
681                if Operating_Mode = Check_Semantics then
682                   ASIS_Mode := True;
683                end if;
684
685                Back_Annotate_Rep_Info := True;
686
687             --  Processing for T switch
688
689             when 'T' =>
690                Ptr := Ptr + 1;
691                Scan_Pos (Switch_Chars, Max, Ptr, Table_Factor);
692
693             --  Processing for u switch
694
695             when 'u' =>
696                Ptr := Ptr + 1;
697                List_Units := True;
698
699             --  Processing for U switch
700
701             when 'U' =>
702                Ptr := Ptr + 1;
703                Unique_Error_Tag := True;
704
705             --  Processing for v switch
706
707             when 'v' =>
708                Ptr := Ptr + 1;
709                Verbose_Mode := True;
710
711             --  Processing for V switch
712
713             when 'V' =>
714                Store_Switch := False;
715                Storing (First_Stored) := 'V';
716                Ptr := Ptr + 1;
717
718                if Ptr > Max then
719                   raise Bad_Switch;
720
721                else
722                   declare
723                      OK  : Boolean;
724
725                   begin
726                      Set_Validity_Check_Options
727                        (Switch_Chars (Ptr .. Max), OK, Ptr);
728
729                      if not OK then
730                         raise Bad_Switch;
731                      end if;
732
733                      for Index in First_Char + 1 .. Max loop
734                         Storing (First_Stored + 1) :=
735                           Switch_Chars (Index);
736                         Store_Compilation_Switch
737                           (Storing (Storing'First .. First_Stored + 1));
738                      end loop;
739                   end;
740                end if;
741
742                Ptr := Max + 1;
743
744             --  Processing for w switch
745
746             when 'w' =>
747                Store_Switch := False;
748                Storing (First_Stored) := 'w';
749                Ptr := Ptr + 1;
750
751                if Ptr > Max then
752                   raise Bad_Switch;
753                end if;
754
755                while Ptr <= Max loop
756                   C := Switch_Chars (Ptr);
757
758                   case C is
759                      when 'a' =>
760                         Check_Unreferenced              := True;
761                         Check_Unreferenced_Formals      := True;
762                         Check_Withs                     := True;
763                         Constant_Condition_Warnings     := True;
764                         Implementation_Unit_Warnings    := True;
765                         Ineffective_Inline_Warnings     := True;
766                         Warn_On_Bad_Fixed_Value         := True;
767                         Warn_On_Constant                := True;
768                         Warn_On_Export_Import           := True;
769                         Warn_On_Modified_Unread         := True;
770                         Warn_On_No_Value_Assigned       := True;
771                         Warn_On_Obsolescent_Feature     := True;
772                         Warn_On_Redundant_Constructs    := True;
773                         Warn_On_Unchecked_Conversion    := True;
774                         Warn_On_Unrecognized_Pragma     := True;
775
776                      when 'A' =>
777                         Check_Unreferenced              := False;
778                         Check_Unreferenced_Formals      := False;
779                         Check_Withs                     := False;
780                         Constant_Condition_Warnings     := False;
781                         Elab_Warnings                   := False;
782                         Implementation_Unit_Warnings    := False;
783                         Ineffective_Inline_Warnings     := False;
784                         Warn_On_Bad_Fixed_Value         := False;
785                         Warn_On_Constant                := False;
786                         Warn_On_Dereference             := False;
787                         Warn_On_Export_Import           := False;
788                         Warn_On_Hiding                  := False;
789                         Warn_On_Modified_Unread         := False;
790                         Warn_On_No_Value_Assigned       := False;
791                         Warn_On_Obsolescent_Feature     := False;
792                         Warn_On_Redundant_Constructs    := False;
793                         Warn_On_Unchecked_Conversion    := False;
794                         Warn_On_Unrecognized_Pragma     := False;
795
796                      when 'b' =>
797                         Warn_On_Bad_Fixed_Value         := True;
798
799                      when 'B' =>
800                         Warn_On_Bad_Fixed_Value         := False;
801
802                      when 'c' =>
803                         Constant_Condition_Warnings     := True;
804
805                      when 'C' =>
806                         Constant_Condition_Warnings     := False;
807
808                      when 'd' =>
809                         Warn_On_Dereference             := True;
810
811                      when 'D' =>
812                         Warn_On_Dereference             := False;
813
814                      when 'e' =>
815                         Warning_Mode                    := Treat_As_Error;
816
817                      when 'f' =>
818                         Check_Unreferenced_Formals      := True;
819
820                      when 'F' =>
821                         Check_Unreferenced_Formals      := False;
822
823                      when 'g' =>
824                         Warn_On_Unrecognized_Pragma     := True;
825
826                      when 'G' =>
827                         Warn_On_Unrecognized_Pragma     := False;
828
829                      when 'h' =>
830                         Warn_On_Hiding                  := True;
831
832                      when 'H' =>
833                         Warn_On_Hiding                  := False;
834
835                      when 'i' =>
836                         Implementation_Unit_Warnings    := True;
837
838                      when 'I' =>
839                         Implementation_Unit_Warnings    := False;
840
841                      when 'j' =>
842                         Warn_On_Obsolescent_Feature     := True;
843
844                      when 'J' =>
845                         Warn_On_Obsolescent_Feature     := False;
846
847                      when 'k' =>
848                         Warn_On_Constant                := True;
849
850                      when 'K' =>
851                         Warn_On_Constant                := False;
852
853                      when 'l' =>
854                         Elab_Warnings                   := True;
855
856                      when 'L' =>
857                         Elab_Warnings                   := False;
858
859                      when 'm' =>
860                         Warn_On_Modified_Unread         := True;
861
862                      when 'M' =>
863                         Warn_On_Modified_Unread         := False;
864
865                      when 'n' =>
866                         Warning_Mode                    := Normal;
867
868                      when 'o' =>
869                         Address_Clause_Overlay_Warnings := True;
870
871                      when 'O' =>
872                         Address_Clause_Overlay_Warnings := False;
873
874                      when 'p' =>
875                         Ineffective_Inline_Warnings     := True;
876
877                      when 'P' =>
878                         Ineffective_Inline_Warnings     := False;
879
880                      when 'r' =>
881                         Warn_On_Redundant_Constructs    := True;
882
883                      when 'R' =>
884                         Warn_On_Redundant_Constructs    := False;
885
886                      when 's' =>
887                         Warning_Mode                    := Suppress;
888
889                      when 'u' =>
890                         Check_Unreferenced              := True;
891                         Check_Withs                     := True;
892                         Check_Unreferenced_Formals      := True;
893
894                      when 'U' =>
895                         Check_Unreferenced              := False;
896                         Check_Withs                     := False;
897                         Check_Unreferenced_Formals      := False;
898
899                      when 'v' =>
900                         Warn_On_No_Value_Assigned       := True;
901
902                      when 'V' =>
903                         Warn_On_No_Value_Assigned       := False;
904
905                      when 'x' =>
906                         Warn_On_Export_Import           := True;
907
908                      when 'X' =>
909                         Warn_On_Export_Import           := False;
910
911                      when 'z' =>
912                         Warn_On_Unchecked_Conversion    := True;
913
914                      when 'Z' =>
915                         Warn_On_Unchecked_Conversion    := False;
916
917                         --  Allow and ignore 'w' so that the old
918                         --  format (e.g. -gnatwuwl) will work.
919
920                      when 'w' =>
921                         null;
922
923                      when others =>
924                         raise Bad_Switch;
925                   end case;
926
927                   if C /= 'w' then
928                      Storing (First_Stored + 1) := C;
929                      Store_Compilation_Switch
930                        (Storing (Storing'First .. First_Stored + 1));
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                   raise Bad_Switch;
945                end if;
946
947                for J in WC_Encoding_Method loop
948                   if Switch_Chars (Ptr) = WC_Encoding_Letters (J) then
949                      Wide_Character_Encoding_Method := J;
950                      exit;
951
952                   elsif J = WC_Encoding_Method'Last then
953                      raise Bad_Switch;
954                   end if;
955                end loop;
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
976             --  Processing for y switch
977
978             when 'y' =>
979                Ptr := Ptr + 1;
980
981                if Ptr > Max then
982                   Set_Default_Style_Check_Options;
983
984                else
985                   Store_Switch := False;
986                   Storing (First_Stored) := 'y';
987
988                   declare
989                      OK  : Boolean;
990                      Last_Stored : Integer;
991
992                   begin
993                      Set_Style_Check_Options
994                        (Switch_Chars (Ptr .. Max), OK, Ptr);
995
996                      if not OK then
997                         raise Bad_Switch;
998                      end if;
999
1000                      Ptr := First_Char + 1;
1001
1002                      while Ptr <= Max loop
1003                         Last_Stored := First_Stored + 1;
1004                         Storing (Last_Stored) := Switch_Chars (Ptr);
1005
1006                         if Switch_Chars (Ptr) = 'M' then
1007                            loop
1008                               Ptr := Ptr + 1;
1009                               exit when Ptr > Max
1010                                 or else Switch_Chars (Ptr) not in '0' .. '9';
1011                               Last_Stored := Last_Stored + 1;
1012                               Storing (Last_Stored) := Switch_Chars (Ptr);
1013                            end loop;
1014
1015                         else
1016                            Ptr := Ptr + 1;
1017                         end if;
1018
1019                         Store_Compilation_Switch
1020                           (Storing (Storing'First .. Last_Stored));
1021                      end loop;
1022                   end;
1023                end if;
1024
1025             --  Processing for z switch
1026
1027             when 'z' =>
1028                Ptr := Ptr + 1;
1029
1030                --  Allowed for compiler only if this is the only
1031                --  -z switch, we do not allow multiple occurrences
1032
1033                if Distribution_Stub_Mode = No_Stubs then
1034                   case Switch_Chars (Ptr) is
1035                      when 'r' =>
1036                         Distribution_Stub_Mode := Generate_Receiver_Stub_Body;
1037
1038                      when 'c' =>
1039                         Distribution_Stub_Mode := Generate_Caller_Stub_Body;
1040
1041                      when others =>
1042                         raise Bad_Switch;
1043                   end case;
1044
1045                   Ptr := Ptr + 1;
1046
1047                end if;
1048
1049             --  Processing for Z switch
1050
1051             when 'Z' =>
1052                Ptr := Ptr + 1;
1053                Zero_Cost_Exceptions_Set := True;
1054                Zero_Cost_Exceptions_Val := True;
1055
1056             --  Processing for 83 switch
1057
1058             when '8' =>
1059                if Ptr = Max then
1060                   raise Bad_Switch;
1061                end if;
1062
1063                Ptr := Ptr + 1;
1064
1065                if Switch_Chars (Ptr) /= '3' then
1066                   raise Bad_Switch;
1067                else
1068                   Ptr := Ptr + 1;
1069                   Ada_Version := Ada_83;
1070                end if;
1071
1072             --  Processing for 95 switch
1073
1074             when '9' =>
1075                if Ptr = Max then
1076                   raise Bad_Switch;
1077                end if;
1078
1079                Ptr := Ptr + 1;
1080
1081                if Switch_Chars (Ptr) /= '5' then
1082                   raise Bad_Switch;
1083                else
1084                   Ptr := Ptr + 1;
1085                   Ada_Version := Ada_95;
1086                end if;
1087
1088             --  Processing for 05 switch
1089
1090             when '0' =>
1091                if Ptr = Max then
1092                   raise Bad_Switch;
1093                end if;
1094
1095                Ptr := Ptr + 1;
1096
1097                if Switch_Chars (Ptr) /= '5' then
1098                   raise Bad_Switch;
1099                else
1100                   Ptr := Ptr + 1;
1101                   Ada_Version := Ada_05;
1102                end if;
1103
1104             --  Ignore extra switch character
1105
1106             when '/' | '-' =>
1107                Ptr := Ptr + 1;
1108
1109             --  Anything else is an error (illegal switch character)
1110
1111             when others =>
1112                raise Bad_Switch;
1113             end case;
1114          end case;
1115
1116          if Store_Switch then
1117             Storing (First_Stored .. First_Stored + Ptr - First_Char - 1) :=
1118               Switch_Chars (First_Char .. Ptr - 1);
1119             Store_Compilation_Switch
1120               (Storing (Storing'First .. First_Stored + Ptr - First_Char - 1));
1121          end if;
1122
1123          First_Switch := False;
1124       end loop;
1125
1126    exception
1127       when Bad_Switch =>
1128          Osint.Fail ("invalid switch: ", (1 => C));
1129
1130       when Bad_Switch_Value =>
1131          Osint.Fail ("numeric value out of range for switch: ", (1 => C));
1132
1133       when Missing_Switch_Value =>
1134          Osint.Fail ("missing numeric value for switch: ", (1 => C));
1135
1136    end Scan_Front_End_Switches;
1137
1138 end Switch.C;