OSDN Git Service

PR ada/23646
[pf3gnuchains/gcc-fork.git] / gcc / ada / targparm.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                        GNAT RUN-TIME COMPONENTS                          --
4 --                                                                          --
5 --                             T A R G P A R M                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1999-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,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, 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 Csets;  use Csets;
28 with Namet;  use Namet;
29 with Opt;    use Opt;
30 with Osint;  use Osint;
31 with Output; use Output;
32
33 package body Targparm is
34    use ASCII;
35
36    Parameters_Obtained : Boolean := False;
37    --  Set True after first call to Get_Target_Parameters. Used to avoid
38    --  reading system.ads more than once, since it cannot change.
39
40    --  The following array defines a tag name for each entry
41
42    type Targparm_Tags is
43      (AAM,  --   AAMP
44       BDC,  --   Backend_Divide_Checks
45       BOC,  --   Backend_Overflow_Checks
46       CLA,  --   Command_Line_Args
47       CRT,  --   Configurable_Run_Times
48       CSV,  --   Compiler_System_Version
49       D32,  --   Duration_32_Bits
50       DEN,  --   Denorm
51       DSP,  --   Functions_Return_By_DSP
52       EXS,  --   Exit_Status_Supported
53       FEL,  --   Frontend_Layout
54       FFO,  --   Fractional_Fixed_Ops
55       MOV,  --   Machine_Overflows
56       MRN,  --   Machine_Rounds
57       PAS,  --   Preallocated_Stacks
58       S64,  --   Support_64_Bit_Divides
59       SAG,  --   Support_Aggregates
60       SCA,  --   Support_Composite_Assign
61       SCC,  --   Support_Composite_Compare
62       SCD,  --   Stack_Check_Default
63       SCP,  --   Stack_Check_Probes
64       SLS,  --   Support_Long_Shifts
65       SNZ,  --   Signed_Zeros
66       SSL,  --   Suppress_Standard_Library
67       UAM,  --   Use_Ada_Main_Program_Name
68       VMS,  --   OpenVMS
69       ZCD,  --   ZCX_By_Default
70       ZCG); --   GCC_ZCX_Support
71
72    subtype Targparm_Tags_OK is Targparm_Tags range AAM .. ZCG;
73    --  Range excluding obsolete entries
74
75    Targparm_Flags : array (Targparm_Tags) of Boolean := (others => False);
76    --  Flag is set True if corresponding parameter is scanned
77
78    --  The following list of string constants gives the parameter names
79
80    AAM_Str : aliased constant Source_Buffer := "AAMP";
81    BDC_Str : aliased constant Source_Buffer := "Backend_Divide_Checks";
82    BOC_Str : aliased constant Source_Buffer := "Backend_Overflow_Checks";
83    CLA_Str : aliased constant Source_Buffer := "Command_Line_Args";
84    CRT_Str : aliased constant Source_Buffer := "Configurable_Run_Time";
85    CSV_Str : aliased constant Source_Buffer := "Compiler_System_Version";
86    D32_Str : aliased constant Source_Buffer := "Duration_32_Bits";
87    DEN_Str : aliased constant Source_Buffer := "Denorm";
88    DSP_Str : aliased constant Source_Buffer := "Functions_Return_By_DSP";
89    EXS_Str : aliased constant Source_Buffer := "Exit_Status_Supported";
90    FEL_Str : aliased constant Source_Buffer := "Frontend_Layout";
91    FFO_Str : aliased constant Source_Buffer := "Fractional_Fixed_Ops";
92    MOV_Str : aliased constant Source_Buffer := "Machine_Overflows";
93    MRN_Str : aliased constant Source_Buffer := "Machine_Rounds";
94    PAS_Str : aliased constant Source_Buffer := "Preallocated_Stacks";
95    S64_Str : aliased constant Source_Buffer := "Support_64_Bit_Divides";
96    SAG_Str : aliased constant Source_Buffer := "Support_Aggregates";
97    SCA_Str : aliased constant Source_Buffer := "Support_Composite_Assign";
98    SCC_Str : aliased constant Source_Buffer := "Support_Composite_Compare";
99    SCD_Str : aliased constant Source_Buffer := "Stack_Check_Default";
100    SCP_Str : aliased constant Source_Buffer := "Stack_Check_Probes";
101    SLS_Str : aliased constant Source_Buffer := "Support_Long_Shifts";
102    SNZ_Str : aliased constant Source_Buffer := "Signed_Zeros";
103    SSL_Str : aliased constant Source_Buffer := "Suppress_Standard_Library";
104    UAM_Str : aliased constant Source_Buffer := "Use_Ada_Main_Program_Name";
105    VMS_Str : aliased constant Source_Buffer := "OpenVMS";
106    ZCD_Str : aliased constant Source_Buffer := "ZCX_By_Default";
107    ZCG_Str : aliased constant Source_Buffer := "GCC_ZCX_Support";
108
109    --  The following defines a set of pointers to the above strings,
110    --  indexed by the tag values.
111
112    type Buffer_Ptr is access constant Source_Buffer;
113    Targparm_Str : constant array (Targparm_Tags) of Buffer_Ptr :=
114      (AAM_Str'Access,
115       BDC_Str'Access,
116       BOC_Str'Access,
117       CLA_Str'Access,
118       CRT_Str'Access,
119       CSV_Str'Access,
120       D32_Str'Access,
121       DEN_Str'Access,
122       DSP_Str'Access,
123       EXS_Str'Access,
124       FEL_Str'Access,
125       FFO_Str'Access,
126       MOV_Str'Access,
127       MRN_Str'Access,
128       PAS_Str'Access,
129       S64_Str'Access,
130       SAG_Str'Access,
131       SCA_Str'Access,
132       SCC_Str'Access,
133       SCD_Str'Access,
134       SCP_Str'Access,
135       SLS_Str'Access,
136       SNZ_Str'Access,
137       SSL_Str'Access,
138       UAM_Str'Access,
139       VMS_Str'Access,
140       ZCD_Str'Access,
141       ZCG_Str'Access);
142
143    -----------------------
144    -- Local Subprograms --
145    -----------------------
146
147    procedure Set_Profile_Restrictions (P : Profile_Name);
148    --  Set Restrictions_On_Target for the given profile
149
150    ------------------------------
151    -- Set_Profile_Restrictions --
152    ------------------------------
153
154    procedure Set_Profile_Restrictions (P : Profile_Name) is
155       R : Restriction_Flags  renames Profile_Info (P).Set;
156       V : Restriction_Values renames Profile_Info (P).Value;
157
158    begin
159       for J in R'Range loop
160          if R (J) then
161             Restrictions_On_Target.Set (J) := True;
162
163             if J in All_Parameter_Restrictions then
164                Restrictions_On_Target.Value (J) := V (J);
165             end if;
166          end if;
167       end loop;
168    end Set_Profile_Restrictions;
169
170    ---------------------------
171    -- Get_Target_Parameters --
172    ---------------------------
173
174    --  Version which reads in system.ads
175
176    procedure Get_Target_Parameters is
177       Text : Source_Buffer_Ptr;
178       Hi   : Source_Ptr;
179
180    begin
181       if Parameters_Obtained then
182          return;
183       end if;
184
185       Name_Buffer (1 .. 10) := "system.ads";
186       Name_Len := 10;
187
188       Read_Source_File (Name_Find, Lo => 0, Hi => Hi, Src => Text);
189
190       if Text = null then
191          Write_Line ("fatal error, run-time library not installed correctly");
192          Write_Line ("cannot locate file system.ads");
193          raise Unrecoverable_Error;
194       end if;
195
196       Targparm.Get_Target_Parameters
197         (System_Text  => Text,
198          Source_First => 0,
199          Source_Last  => Hi);
200    end Get_Target_Parameters;
201
202    --  Version where caller supplies system.ads text
203
204    procedure Get_Target_Parameters
205      (System_Text  : Source_Buffer_Ptr;
206       Source_First : Source_Ptr;
207       Source_Last  : Source_Ptr)
208    is
209       P : Source_Ptr;
210       --  Scans source buffer containing source of system.ads
211
212       Fatal : Boolean := False;
213       --  Set True if a fatal error is detected
214
215       Result : Boolean;
216       --  Records boolean from system line
217
218    begin
219       if Parameters_Obtained then
220          return;
221       else
222          Parameters_Obtained := True;
223       end if;
224
225       Opt.Address_Is_Private := False;
226
227       P := Source_First;
228       Line_Loop : while System_Text (P .. P + 10) /= "end System;" loop
229
230          --  Skip comments quickly
231
232          if System_Text (P) = '-' then
233             goto Line_Loop_Continue;
234
235          --  Test for type Address is private
236
237          elsif System_Text (P .. P + 26) = "   type Address is private;" then
238             Opt.Address_Is_Private := True;
239             P := P + 26;
240             goto Line_Loop_Continue;
241
242          --  Test for pragma Profile (Ravenscar);
243
244          elsif System_Text (P .. P + 26) =
245                  "pragma Profile (Ravenscar);"
246          then
247             Set_Profile_Restrictions (Ravenscar);
248             Opt.Task_Dispatching_Policy := 'F';
249             Opt.Locking_Policy          := 'C';
250             P := P + 27;
251             goto Line_Loop_Continue;
252
253          --  Test for pragma Profile (Restricted);
254
255          elsif System_Text (P .. P + 27) =
256                  "pragma Profile (Restricted);"
257          then
258             Set_Profile_Restrictions (Restricted);
259             P := P + 28;
260             goto Line_Loop_Continue;
261
262          --  Test for pragma Restrictions
263
264          elsif System_Text (P .. P + 20) = "pragma Restrictions (" then
265             P := P + 21;
266
267             Rloop : for K in All_Boolean_Restrictions loop
268                declare
269                   Rname : constant String := Restriction_Id'Image (K);
270
271                begin
272                   for J in Rname'Range loop
273                      if Fold_Upper (System_Text (P + Source_Ptr (J - 1)))
274                                                         /= Rname (J)
275                      then
276                         goto Rloop_Continue;
277                      end if;
278                   end loop;
279
280                   if System_Text (P + Rname'Length) = ')' then
281                      Restrictions_On_Target.Set (K) := True;
282                      goto Line_Loop_Continue;
283                   end if;
284                end;
285
286             <<Rloop_Continue>>
287                null;
288             end loop Rloop;
289
290             Ploop : for K in All_Parameter_Restrictions loop
291                declare
292                   Rname : constant String :=
293                             All_Parameter_Restrictions'Image (K);
294
295                   V : Natural;
296                   --  Accumulates value
297
298                begin
299                   for J in Rname'Range loop
300                      if Fold_Upper (System_Text (P + Source_Ptr (J - 1)))
301                                                         /= Rname (J)
302                      then
303                         goto Ploop_Continue;
304                      end if;
305                   end loop;
306
307                   if System_Text (P + Rname'Length .. P + Rname'Length + 3) =
308                                                       " => "
309                   then
310                      P := P + Rname'Length + 4;
311
312                      V := 0;
313                      loop
314                         if System_Text (P) in '0' .. '9' then
315                            declare
316                               pragma Unsuppress (Overflow_Check);
317
318                            begin
319                               --  Accumulate next digit
320
321                               V := 10 * V +
322                                    Character'Pos (System_Text (P)) -
323                                    Character'Pos ('0');
324
325                            exception
326                               --  On overflow, we just ignore the pragma since
327                               --  that is the standard handling in this case.
328
329                               when Constraint_Error =>
330                                  goto Line_Loop_Continue;
331                            end;
332
333                         elsif System_Text (P) = '_' then
334                            null;
335
336                         elsif System_Text (P) = ')' then
337                            Restrictions_On_Target.Value (K) := V;
338                            Restrictions_On_Target.Set (K) := True;
339                            goto Line_Loop_Continue;
340
341                         else
342                            exit Ploop;
343                         end if;
344
345                         P := P + 1;
346                      end loop;
347
348                   else
349                      exit Ploop;
350                   end if;
351                end;
352
353             <<Ploop_Continue>>
354                null;
355             end loop Ploop;
356
357             Set_Standard_Error;
358             Write_Line
359                ("fatal error: system.ads is incorrectly formatted");
360             Write_Str ("unrecognized or incorrect restrictions pragma: ");
361
362             while System_Text (P) /= ')'
363                     and then
364                   System_Text (P) /= ASCII.LF
365             loop
366                Write_Char (System_Text (P));
367                P := P + 1;
368             end loop;
369
370             Write_Eol;
371             Fatal := True;
372             Set_Standard_Output;
373
374          --  Test for pragma Detect_Blocking;
375
376          elsif System_Text (P .. P + 22) = "pragma Detect_Blocking;" then
377             P := P + 23;
378             Opt.Detect_Blocking := True;
379             goto Line_Loop_Continue;
380
381          --  Discard_Names
382
383          elsif System_Text (P .. P + 20) = "pragma Discard_Names;" then
384             P := P + 21;
385             Opt.Global_Discard_Names := True;
386             goto Line_Loop_Continue;
387
388          --  Locking Policy
389
390          elsif System_Text (P .. P + 22) = "pragma Locking_Policy (" then
391             P := P + 23;
392             Opt.Locking_Policy := System_Text (P);
393             Opt.Locking_Policy_Sloc := System_Location;
394             goto Line_Loop_Continue;
395
396          --  Normalize_Scalars
397
398          elsif System_Text (P .. P + 24) = "pragma Normalize_Scalars;" then
399             P := P + 25;
400             Opt.Normalize_Scalars := True;
401             Opt.Init_Or_Norm_Scalars := True;
402             goto Line_Loop_Continue;
403
404          --  Polling (On)
405
406          elsif System_Text (P .. P + 19) = "pragma Polling (On);" then
407             P := P + 20;
408             Opt.Polling_Required := True;
409             goto Line_Loop_Continue;
410
411          --  Ignore pragma Pure (System)
412
413          elsif System_Text (P .. P + 20) = "pragma Pure (System);" then
414             P := P + 21;
415             goto Line_Loop_Continue;
416
417          --  Queuing Policy
418
419          elsif System_Text (P .. P + 22) = "pragma Queuing_Policy (" then
420             P := P + 23;
421             Opt.Queuing_Policy := System_Text (P);
422             Opt.Queuing_Policy_Sloc := System_Location;
423             goto Line_Loop_Continue;
424
425          --  Suppress_Exception_Locations
426
427          elsif System_Text (P .. P + 34) =
428                                 "pragma Suppress_Exception_Locations;"
429          then
430             P := P + 35;
431             Opt.Exception_Locations_Suppressed := True;
432             goto Line_Loop_Continue;
433
434          --  Task_Dispatching Policy
435
436          elsif System_Text (P .. P + 31) =
437                                    "pragma Task_Dispatching_Policy ("
438          then
439             P := P + 32;
440             Opt.Task_Dispatching_Policy := System_Text (P);
441             Opt.Task_Dispatching_Policy_Sloc := System_Location;
442             goto Line_Loop_Continue;
443
444          --  No other pragmas are permitted
445
446          elsif System_Text (P .. P + 6) = "pragma " then
447             Set_Standard_Error;
448             Write_Line ("unrecognized line in system.ads: ");
449
450             while System_Text (P) /= ')'
451               and then System_Text (P) /= ASCII.LF
452             loop
453                Write_Char (System_Text (P));
454                P := P + 1;
455             end loop;
456
457             Write_Eol;
458             Set_Standard_Output;
459             Fatal := True;
460
461          --  See if we have a Run_Time_Name
462
463          elsif System_Text (P .. P + 38) =
464                   "   Run_Time_Name : constant String := """
465          then
466             P := P + 39;
467
468             Name_Len := 0;
469             while System_Text (P) in 'A' .. 'Z'
470                     or else
471                   System_Text (P) in 'a' .. 'z'
472                     or else
473                   System_Text (P) in '0' .. '9'
474                     or else
475                   System_Text (P) = ' '
476                     or else
477                   System_Text (P) = '_'
478             loop
479                Add_Char_To_Name_Buffer (System_Text (P));
480                P := P + 1;
481             end loop;
482
483             if System_Text (P) /= '"'
484               or else System_Text (P + 1) /= ';'
485               or else (System_Text (P + 2) /= ASCII.LF
486                          and then
487                        System_Text (P + 2) /= ASCII.CR)
488             then
489                Set_Standard_Error;
490                Write_Line
491                  ("incorrectly formatted Run_Time_Name in system.ads");
492                Set_Standard_Output;
493                Fatal := True;
494
495             else
496                Run_Time_Name_On_Target := Name_Enter;
497             end if;
498
499             goto Line_Loop_Continue;
500
501          --  Next See if we have a configuration parameter
502
503          else
504             Config_Param_Loop : for K in Targparm_Tags loop
505                if System_Text (P + 3 .. P + 2 + Targparm_Str (K)'Length) =
506                                                       Targparm_Str (K).all
507                then
508                   P := P + 3 + Targparm_Str (K)'Length;
509
510                   if Targparm_Flags (K) then
511                      Set_Standard_Error;
512                      Write_Line
513                        ("fatal error: system.ads is incorrectly formatted");
514                      Write_Str ("duplicate line for parameter: ");
515
516                      for J in Targparm_Str (K)'Range loop
517                         Write_Char (Targparm_Str (K).all (J));
518                      end loop;
519
520                      Write_Eol;
521                      Set_Standard_Output;
522                      Fatal := True;
523
524                   else
525                      Targparm_Flags (K) := True;
526                   end if;
527
528                   while System_Text (P) /= ':'
529                      or else System_Text (P + 1) /= '='
530                   loop
531                      P := P + 1;
532                   end loop;
533
534                   P := P + 2;
535
536                   while System_Text (P) = ' ' loop
537                      P := P + 1;
538                   end loop;
539
540                   Result := (System_Text (P) = 'T');
541
542                   case K is
543                      when AAM => AAMP_On_Target                      := Result;
544                      when BDC => Backend_Divide_Checks_On_Target     := Result;
545                      when BOC => Backend_Overflow_Checks_On_Target   := Result;
546                      when CLA => Command_Line_Args_On_Target         := Result;
547                      when CRT => Configurable_Run_Time_On_Target     := Result;
548                      when CSV => Compiler_System_Version             := Result;
549                      when D32 => Duration_32_Bits_On_Target          := Result;
550                      when DEN => Denorm_On_Target                    := Result;
551                      when DSP => Functions_Return_By_DSP_On_Target   := Result;
552                      when EXS => Exit_Status_Supported_On_Target     := Result;
553                      when FEL => Frontend_Layout_On_Target           := Result;
554                      when FFO => Fractional_Fixed_Ops_On_Target      := Result;
555                      when MOV => Machine_Overflows_On_Target         := Result;
556                      when MRN => Machine_Rounds_On_Target            := Result;
557                      when PAS => Preallocated_Stacks_On_Target       := Result;
558                      when S64 => Support_64_Bit_Divides_On_Target    := Result;
559                      when SAG => Support_Aggregates_On_Target        := Result;
560                      when SCA => Support_Composite_Assign_On_Target  := Result;
561                      when SCC => Support_Composite_Compare_On_Target := Result;
562                      when SCD => Stack_Check_Default_On_Target       := Result;
563                      when SCP => Stack_Check_Probes_On_Target        := Result;
564                      when SLS => Support_Long_Shifts_On_Target       := Result;
565                      when SSL => Suppress_Standard_Library_On_Target := Result;
566                      when SNZ => Signed_Zeros_On_Target              := Result;
567                      when UAM => Use_Ada_Main_Program_Name_On_Target := Result;
568                      when VMS => OpenVMS_On_Target                   := Result;
569                      when ZCD => ZCX_By_Default_On_Target            := Result;
570                      when ZCG => GCC_ZCX_Support_On_Target           := Result;
571
572                      goto Line_Loop_Continue;
573                   end case;
574
575                   --  Here we are seeing a parameter we do not understand. We
576                   --  simply ignore this (will happen when an old compiler is
577                   --  used to compile a newer version of GNAT which does not
578                   --  support the
579                end if;
580             end loop Config_Param_Loop;
581          end if;
582
583          --  Here after processing one line of System spec
584
585          <<Line_Loop_Continue>>
586
587          while System_Text (P) /= CR and then System_Text (P) /= LF loop
588             P := P + 1;
589             exit when P >= Source_Last;
590          end loop;
591
592          while System_Text (P) = CR or else System_Text (P) = LF loop
593             P := P + 1;
594             exit when P >= Source_Last;
595          end loop;
596
597          if P >= Source_Last then
598             Set_Standard_Error;
599             Write_Line ("fatal error, system.ads not formatted correctly");
600             Write_Line ("unexpected end of file");
601             Set_Standard_Output;
602             raise Unrecoverable_Error;
603          end if;
604       end loop Line_Loop;
605
606       --  Check no missing target parameter settings (skip for compiler vsn)
607
608       if not Compiler_System_Version then
609          for K in Targparm_Tags_OK loop
610             if not Targparm_Flags (K) then
611                Set_Standard_Error;
612                Write_Line
613                  ("fatal error: system.ads is incorrectly formatted");
614                Write_Str ("missing line for parameter: ");
615
616                for J in Targparm_Str (K)'Range loop
617                   Write_Char (Targparm_Str (K).all (J));
618                end loop;
619
620                Write_Eol;
621                Set_Standard_Output;
622                Fatal := True;
623             end if;
624          end loop;
625       end if;
626
627       if Fatal then
628          raise Unrecoverable_Error;
629       end if;
630    end Get_Target_Parameters;
631
632 end Targparm;