]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Thu, 11 Apr 2013 13:10:28 +0000 (15:10 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Thu, 11 Apr 2013 13:10:28 +0000 (15:10 +0200)
2013-04-11  Arnaud Charlet  <charlet@adacore.com>

* xgnatugn.adb: Remove obsolete comments.

2013-04-11  Robert Dewar  <dewar@adacore.com>

* back_end.ads, back_end.adb: Minor reformatting.
* set_targ.ads, set_targ.adb: New files.

2013-04-11  Hristian Kirtchev  <kirtchev@adacore.com>

* sem_case.adb (Check_Against_Predicate): New routine.
(Check_Choices): When the type covered by the list of choices
is a static subtype with a static predicate, check all choices
agains the predicate.
(Issue_Msg): All versions removed.
(Missing_Choice): New routines.
* sem_ch4.adb: Code and comment reformatting.
(Analyze_Case_Expression): Do not check the choices when the case
expression is being preanalyzed and the type of the expression
is a subtype with a static predicate.
(Has_Static_Predicate): New routine.
* sem_ch13.adb: Code and comment reformatting. (Build_Range):
Always build a range even if the low and hi bounds denote the
same value. This is needed by the machinery in Check_Choices.
(Build_Static_Predicate): Always build a range even if the low and
hi bounds denote the same value. This is needed by the machinery
in Check_Choices.

From-SVN: r197789

gcc/ada/ChangeLog
gcc/ada/back_end.adb
gcc/ada/back_end.ads
gcc/ada/sem_case.adb
gcc/ada/sem_ch13.adb
gcc/ada/sem_ch4.adb
gcc/ada/set_targ.adb [new file with mode: 0755]
gcc/ada/set_targ.ads [new file with mode: 0755]
gcc/ada/xgnatugn.adb

index cc11908b17b76b68a51be743c53364f1f4df80f2..4852ff9fa11a6f7acdfb9fef7059ed0f14db69ce 100644 (file)
@@ -1,3 +1,32 @@
+2013-04-11  Arnaud Charlet  <charlet@adacore.com>
+
+       * xgnatugn.adb: Remove obsolete comments.
+
+2013-04-11  Robert Dewar  <dewar@adacore.com>
+
+       * back_end.ads, back_end.adb: Minor reformatting.
+       * set_targ.ads, set_targ.adb: New files.
+
+2013-04-11  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * sem_case.adb (Check_Against_Predicate): New routine.
+       (Check_Choices): When the type covered by the list of choices
+       is a static subtype with a static predicate, check all choices
+       agains the predicate.
+       (Issue_Msg): All versions removed.
+       (Missing_Choice): New routines.
+       * sem_ch4.adb: Code and comment reformatting.
+       (Analyze_Case_Expression): Do not check the choices when the case
+       expression is being preanalyzed and the type of the expression
+       is a subtype with a static predicate.
+       (Has_Static_Predicate): New routine.
+       * sem_ch13.adb: Code and comment reformatting.  (Build_Range):
+       Always build a range even if the low and hi bounds denote the
+       same value. This is needed by the machinery in Check_Choices.
+       (Build_Static_Predicate): Always build a range even if the low and
+       hi bounds denote the same value. This is needed by the machinery
+       in Check_Choices.
+
 2013-04-11  Robert Dewar  <dewar@adacore.com>
 
        * einfo.ads, sem_util.adb, exp_ch6.adb, xgnatugn.adb: Minor
index f23230ecf9d34aee65e86422188b3671f5d4bdd6..fafbbc4dc2f3073b9f25e659dc55621f544937f5 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2013, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -347,7 +347,6 @@ package body Back_End is
    procedure Register_Back_End_Types (Call_Back : Register_Type_Proc) is
       procedure Enumerate_Modes (Call_Back : Register_Type_Proc);
       pragma Import (C, Enumerate_Modes, "enumerate_modes");
-
    begin
       Enumerate_Modes (Call_Back);
    end Register_Back_End_Types;
index bfa2eb5b440da98a642cd75de3d3cef91d819b0a..4f30b039f39f6254850736a8b5d150c41b1585e9 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2013, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -24,7 +24,8 @@
 ------------------------------------------------------------------------------
 
 --  Call the back end with all the information needed. Also contains other
---  back-end specific interfaces required by the front end.
+--  back-end specific interfaces required by the front end. See also Get_Targ,
+--  which defines additional interfaces to the back end.
 
 with Einfo; use Einfo;
 
@@ -63,13 +64,13 @@ package Back_End is
    --  the back end.
 
    procedure Register_Back_End_Types (Call_Back : Register_Type_Proc);
-   --  Calls the Call_Back function with information for each supported type.
+   --  Calls the Call_Back function with information for each supported type
 
    procedure Call_Back_End (Mode : Back_End_Mode_Type);
    --  Call back end, i.e. make call to driver traversing the tree and
-   --  outputting code. This call is made with all tables locked.
-   --  The back end is responsible for unlocking any tables it may need
-   --  to change, and locking them again before returning.
+   --  outputting code. This call is made with all tables locked. The back
+   --  end is responsible for unlocking any tables it may need to change,
+   --  and locking them again before returning.
 
    procedure Scan_Compiler_Arguments;
    --  Acquires command-line parameters passed to the compiler and processes
index 432de5dc3674530fcd69278a4a97864eee0c3211..6f066fe917ba1ecd14b04166357907f4470d3099 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1996-2012, Free Software Foundation, Inc.         --
+--          Copyright (C) 1996-2013, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -114,6 +114,18 @@ package body Sem_Case is
       Others_Present : Boolean;
       Case_Node      : Node_Id)
    is
+      procedure Check_Against_Predicate
+        (Pred    : in out Node_Id;
+         Choice  : Choice_Bounds;
+         Prev_Lo : in out Uint;
+         Prev_Hi : in out Uint;
+         Error   : in out Boolean);
+      --  Determine whether a choice covers legal values as defined by a static
+      --  predicate set. Pred is a static predicate range. Choice is the choice
+      --  to be examined. Prev_Lo and Prev_Hi are the bounds of the previous
+      --  choice that covered a predicate set. Error denotes whether the check
+      --  found an illegal intersection.
+
       procedure Explain_Non_Static_Bound;
       --  Called when we find a non-static bound, requiring the base type to
       --  be covered. Provides where possible a helpful explanation of why the
@@ -123,102 +135,292 @@ package body Sem_Case is
       --  Comparison routine for comparing Choice_Table entries. Use the lower
       --  bound of each Choice as the key.
 
+      procedure Missing_Choice (Value1 : Node_Id; Value2 : Node_Id);
+      procedure Missing_Choice (Value1 : Node_Id; Value2 : Uint);
+      procedure Missing_Choice (Value1 : Uint;    Value2 : Node_Id);
+      procedure Missing_Choice (Value1 : Uint;    Value2 : Uint);
+      --  Issue an error message indicating that there are missing choices,
+      --  followed by the image of the missing choices themselves which lie
+      --  between Value1 and Value2 inclusive.
+
+      procedure Missing_Choices (Pred : Node_Id; Prev_Hi : Uint);
+      --  Emit an error message for each non-covered static predicate set.
+      --  Prev_Hi denotes the upper bound of the last choice that covered a
+      --  set.
+
       procedure Move_Choice (From : Natural; To : Natural);
       --  Move routine for sorting the Choice_Table
 
       package Sorting is new GNAT.Heap_Sort_G (Move_Choice, Lt_Choice);
 
-      procedure Issue_Msg (Value1 : Node_Id; Value2 : Node_Id);
-      procedure Issue_Msg (Value1 : Node_Id; Value2 : Uint);
-      procedure Issue_Msg (Value1 : Uint;    Value2 : Node_Id);
-      procedure Issue_Msg (Value1 : Uint;    Value2 : Uint);
-      --  Issue an error message indicating that there are missing choices,
-      --  followed by the image of the missing choices themselves which lie
-      --  between Value1 and Value2 inclusive.
+      -----------------------------
+      -- Check_Against_Predicate --
+      -----------------------------
 
-      ---------------
-      -- Issue_Msg --
-      ---------------
+      procedure Check_Against_Predicate
+        (Pred    : in out Node_Id;
+         Choice  : Choice_Bounds;
+         Prev_Lo : in out Uint;
+         Prev_Hi : in out Uint;
+         Error   : in out Boolean)
+      is
+         procedure Illegal_Range
+           (Loc : Source_Ptr;
+            Lo  : Uint;
+            Hi  : Uint);
+         --  Emit an error message regarding a choice that clashes with the
+         --  legal static predicate sets. Loc is the location of the choice
+         --  that introduced the illegal range. Lo .. Hi is the range.
+
+         function Inside_Range
+           (Lo  : Uint;
+            Hi  : Uint;
+            Val : Uint) return Boolean;
+         --  Determine whether position Val within a discrete type is within
+         --  the range Lo .. Hi inclusive.
+
+         -------------------
+         -- Illegal_Range --
+         -------------------
+
+         procedure Illegal_Range
+           (Loc : Source_Ptr;
+            Lo  : Uint;
+            Hi  : Uint)
+         is
+         begin
+            Error_Msg_Name_1 := Chars (Bounds_Type);
 
-      procedure Issue_Msg (Value1 : Node_Id; Value2 : Node_Id) is
-      begin
-         Issue_Msg (Expr_Value (Value1), Expr_Value (Value2));
-      end Issue_Msg;
+            --  Single value
 
-      procedure Issue_Msg (Value1 : Node_Id; Value2 : Uint) is
-      begin
-         Issue_Msg (Expr_Value (Value1), Value2);
-      end Issue_Msg;
+            if Lo = Hi then
+               if Is_Integer_Type (Bounds_Type) then
+                  Error_Msg_Uint_1 := Lo;
+                  Error_Msg ("static predicate on % excludes value ^!", Loc);
+               else
+                  Error_Msg_Name_2 := Choice_Image (Lo, Bounds_Type);
+                  Error_Msg ("static predicate on % excludes value %!", Loc);
+               end if;
 
-      procedure Issue_Msg (Value1 : Uint; Value2 : Node_Id) is
-      begin
-         Issue_Msg (Value1, Expr_Value (Value2));
-      end Issue_Msg;
+            --  Range
 
-      procedure Issue_Msg (Value1 : Uint; Value2 : Uint) is
-         Msg_Sloc : constant Source_Ptr := Sloc (Case_Node);
+            else
+               if Is_Integer_Type (Bounds_Type) then
+                  Error_Msg_Uint_1 := Lo;
+                  Error_Msg_Uint_2 := Hi;
+                  Error_Msg
+                    ("static predicate on % excludes range ^ .. ^!", Loc);
+               else
+                  Error_Msg_Name_2 := Choice_Image (Lo, Bounds_Type);
+                  Error_Msg_Name_3 := Choice_Image (Hi, Bounds_Type);
+                  Error_Msg
+                    ("static predicate on % excludes range % .. %!", Loc);
+               end if;
+            end if;
+         end Illegal_Range;
+
+         ------------------
+         -- Inside_Range --
+         ------------------
+
+         function Inside_Range
+           (Lo  : Uint;
+            Hi  : Uint;
+            Val : Uint) return Boolean
+         is
+         begin
+            return
+              Val = Lo or else Val = Hi or else (Lo < Val and then Val < Hi);
+         end Inside_Range;
+
+         --  Local variables
+
+         Choice_Hi : constant Uint := Expr_Value (Choice.Hi);
+         Choice_Lo : constant Uint := Expr_Value (Choice.Lo);
+         Loc       : Source_Ptr;
+         Next_Hi   : Uint;
+         Next_Lo   : Uint;
+         Pred_Hi   : Uint;
+         Pred_Lo   : Uint;
+
+      --  Start of processing for Check_Against_Predicate
 
       begin
-         --  AI05-0188 : within an instance the non-others choices do not
-         --  have to belong to the actual subtype.
+         --  Find the proper error message location
 
-         if Ada_Version >= Ada_2012 and then In_Instance then
-            return;
+         if Present (Choice.Node) then
+            Loc := Sloc (Choice.Node);
+         else
+            Loc := Sloc (Case_Node);
          end if;
 
-         --  In some situations, we call this with a null range, and
-         --  obviously we don't want to complain in this case!
+         if Present (Pred) then
+            Pred_Lo := Expr_Value (Low_Bound  (Pred));
+            Pred_Hi := Expr_Value (High_Bound (Pred));
+
+         --  Previous choices managed to satisfy all static predicate sets
+
+         else
+            Illegal_Range (Loc, Choice_Lo, Choice_Hi);
+            Error := True;
 
-         if Value1 > Value2 then
             return;
          end if;
 
-         --  Case of only one value that is missing
+         --  Step 1: Detect duplicate choices
 
-         if Value1 = Value2 then
-            if Is_Integer_Type (Bounds_Type) then
-               Error_Msg_Uint_1 := Value1;
-               Error_Msg ("missing case value: ^!", Msg_Sloc);
+         if Inside_Range (Choice_Lo, Choice_Hi, Prev_Lo)
+           or else Inside_Range (Choice_Lo, Choice_Hi, Prev_Hi)
+         then
+            Error_Msg ("duplication of choice value", Loc);
+            Error := True;
+
+         --  Step 2: Detect full coverage
+
+         --  Choice_Lo    Choice_Hi
+         --  +============+
+         --  Pred_Lo      Pred_Hi
+
+         elsif Choice_Lo = Pred_Lo and then Choice_Hi = Pred_Hi then
+            Prev_Lo := Choice_Lo;
+            Prev_Hi := Choice_Hi;
+            Next (Pred);
+
+         --  Step 3: Detect all cases where a choice mentions values that are
+         --  not part of the static predicate sets.
+
+         --  Choice_Lo   Choice_Hi   Pred_Lo   Pred_Hi
+         --  +-----------+ . . . . . +=========+
+         --   ^ illegal ^
+
+         elsif Choice_Lo < Pred_Lo and then Choice_Hi < Pred_Lo then
+            Illegal_Range (Loc, Choice_Lo, Choice_Hi);
+            Error := True;
+
+         --  Choice_Lo   Pred_Lo   Choice_Hi   Pred_Hi
+         --  +-----------+=========+===========+
+         --   ^ illegal ^
+
+         elsif Choice_Lo < Pred_Lo
+           and then Inside_Range (Pred_Lo, Pred_Hi, Choice_Hi)
+         then
+            Illegal_Range (Loc, Choice_Lo, Pred_Lo - 1);
+            Error := True;
+
+         --  Pred_Lo   Pred_Hi   Choice_Lo   Choice_Hi
+         --  +=========+ . . . . +-----------+
+         --                       ^ illegal ^
+
+         elsif Pred_Lo < Choice_Lo and then Pred_Hi < Choice_Lo then
+            Missing_Choice (Pred_Lo, Pred_Hi);
+            Error := True;
+
+            --  There may be several static predicate sets between the current
+            --  one and the choice. Inspect the next static predicate set.
+
+            Next (Pred);
+            Check_Against_Predicate
+              (Pred    => Pred,
+               Choice  => Choice,
+               Prev_Lo => Prev_Lo,
+               Prev_Hi => Prev_Hi,
+               Error   => Error);
+
+         --  Pred_Lo   Choice_Lo   Pred_Hi     Choice_Hi
+         --  +=========+===========+-----------+
+         --                         ^ illegal ^
+
+         elsif Pred_Hi < Choice_Hi
+           and then Inside_Range (Pred_Lo, Pred_Hi, Choice_Lo)
+         then
+            Next (Pred);
+
+            --  The choice may fall in a static predicate set. If this is the
+            --  case, avoid mentioning legal values in the error message.
+
+            if Present (Pred) then
+               Next_Lo := Expr_Value (Low_Bound  (Pred));
+               Next_Hi := Expr_Value (High_Bound (Pred));
+
+               --  The next static predicate set is to the right of the choice
+
+               if Choice_Hi < Next_Lo and then Choice_Hi < Next_Hi then
+                  Illegal_Range (Loc, Pred_Hi + 1, Choice_Hi);
+               else
+                  Illegal_Range (Loc, Pred_Hi + 1, Next_Lo - 1);
+               end if;
             else
-               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
-               Error_Msg ("missing case value: %!", Msg_Sloc);
+               Illegal_Range (Loc, Pred_Hi + 1, Choice_Hi);
             end if;
 
-         --  More than one choice value, so print range of values
+            Error := True;
+
+         --  Choice_Lo   Pred_Lo   Pred_Hi     Choice_Hi
+         --  +-----------+=========+-----------+
+         --   ^ illegal ^           ^ illegal ^
+
+         --  Emit an error on the low gap, disregard the upper gap
+
+         elsif Choice_Lo < Pred_Lo and then Pred_Hi < Choice_Hi then
+            Illegal_Range (Loc, Choice_Lo, Pred_Lo - 1);
+            Error := True;
+
+         --  Step 4: Detect all cases of partial or missing coverage
+
+         --  Pred_Lo   Choice_Lo  Choice_Hi   Pred_Hi
+         --  +=========+==========+===========+
+         --   ^  gap  ^            ^   gap   ^
 
          else
-            if Is_Integer_Type (Bounds_Type) then
-               Error_Msg_Uint_1 := Value1;
-               Error_Msg_Uint_2 := Value2;
-               Error_Msg ("missing case values: ^ .. ^!", Msg_Sloc);
-            else
-               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
-               Error_Msg_Name_2 := Choice_Image (Value2, Bounds_Type);
-               Error_Msg ("missing case values: % .. %!", Msg_Sloc);
-            end if;
-         end if;
-      end Issue_Msg;
+            --  An "others" choice covers all gaps
 
-      ---------------
-      -- Lt_Choice --
-      ---------------
+            if Others_Present then
+               Prev_Lo := Choice_Lo;
+               Prev_Hi := Choice_Hi;
+               Next (Pred);
 
-      function Lt_Choice (C1, C2 : Natural) return Boolean is
-      begin
-         return
-           Expr_Value (Choice_Table (Nat (C1)).Lo)
-             <
-           Expr_Value (Choice_Table (Nat (C2)).Lo);
-      end Lt_Choice;
+            --  Choice_Lo   Choice_Hi   Pred_Hi
+            --  +===========+===========+
+            --  Pred_Lo      ^   gap   ^
 
-      -----------------
-      -- Move_Choice --
-      -----------------
+            --  The upper gap may be covered by a subsequent choice
 
-      procedure Move_Choice (From : Natural; To : Natural) is
-      begin
-         Choice_Table (Nat (To)) := Choice_Table (Nat (From));
-      end Move_Choice;
+            elsif Pred_Lo = Choice_Lo then
+               Prev_Lo := Choice_Lo;
+               Prev_Hi := Choice_Hi;
+
+            --  Pred_Lo     Prev_Hi   Choice_Lo   Choice_Hi   Pred_Hi
+            --  +===========+=========+===========+===========+
+            --   ^ covered ^ ^  gap  ^
+
+            else pragma Assert (Pred_Lo < Choice_Lo);
+
+               --  A previous choice covered the gap up to the current choice
+
+               if Prev_Hi = Choice_Lo - 1 then
+                  Prev_Lo := Choice_Lo;
+                  Prev_Hi := Choice_Hi;
+
+                  if Choice_Hi = Pred_Hi then
+                     Next (Pred);
+                  end if;
+
+               --  The previous choice did not intersect with the current
+               --  static predicate set.
+
+               elsif Prev_Hi < Pred_Lo then
+                  Missing_Choice (Pred_Lo, Choice_Lo - 1);
+                  Error := True;
+
+               --  The previous choice covered part of the static predicate set
+
+               else
+                  Missing_Choice (Prev_Hi, Choice_Lo - 1);
+                  Error := True;
+               end if;
+            end if;
+         end if;
+      end Check_Against_Predicate;
 
       ------------------------------
       -- Explain_Non_Static_Bound --
@@ -236,16 +438,16 @@ package body Sem_Case is
 
          if Bounds_Type /= Subtyp then
 
-            --  If the case is a variant part, the expression is given by
-            --  the discriminant itself, and the bounds are the culprits.
+            --  If the case is a variant part, the expression is given by the
+            --  discriminant itself, and the bounds are the culprits.
 
             if Nkind (Case_Node) = N_Variant_Part then
                Error_Msg_NE
                  ("bounds of & are not static," &
                      " alternatives must cover base type", Expr, Expr);
 
-            --  If this is a case statement, the expression may be
-            --  non-static or else the subtype may be at fault.
+            --  If this is a case statement, the expression may be non-static
+            --  or else the subtype may be at fault.
 
             elsif Is_Entity_Name (Expr) then
                Error_Msg_NE
@@ -269,30 +471,150 @@ package body Sem_Case is
          end if;
       end Explain_Non_Static_Bound;
 
-      --  Variables local to Check_Choices
+      ---------------
+      -- Lt_Choice --
+      ---------------
+
+      function Lt_Choice (C1, C2 : Natural) return Boolean is
+      begin
+         return
+           Expr_Value (Choice_Table (Nat (C1)).Lo)
+             <
+           Expr_Value (Choice_Table (Nat (C2)).Lo);
+      end Lt_Choice;
+
+      --------------------
+      -- Missing_Choice --
+      --------------------
 
-      Choice    : Node_Id;
-      Bounds_Lo : constant Node_Id := Type_Low_Bound  (Bounds_Type);
-      Bounds_Hi : constant Node_Id := Type_High_Bound (Bounds_Type);
+      procedure Missing_Choice (Value1 : Node_Id; Value2 : Node_Id) is
+      begin
+         Missing_Choice (Expr_Value (Value1), Expr_Value (Value2));
+      end Missing_Choice;
 
-      Prev_Choice : Node_Id;
+      procedure Missing_Choice (Value1 : Node_Id; Value2 : Uint) is
+      begin
+         Missing_Choice (Expr_Value (Value1), Value2);
+      end Missing_Choice;
+
+      procedure Missing_Choice (Value1 : Uint; Value2 : Node_Id) is
+      begin
+         Missing_Choice (Value1, Expr_Value (Value2));
+      end Missing_Choice;
+
+      procedure Missing_Choice (Value1 : Uint; Value2 : Uint) is
+         Msg_Sloc : constant Source_Ptr := Sloc (Case_Node);
+
+      begin
+         --  AI05-0188 : within an instance the non-others choices do not have
+         --  to belong to the actual subtype.
+
+         if Ada_Version >= Ada_2012 and then In_Instance then
+            return;
+
+         --  In some situations, we call this with a null range, and obviously
+         --  we don't want to complain in this case.
+
+         elsif Value1 > Value2 then
+            return;
+         end if;
+
+         --  Case of only one value that is missing
+
+         if Value1 = Value2 then
+            if Is_Integer_Type (Bounds_Type) then
+               Error_Msg_Uint_1 := Value1;
+               Error_Msg ("missing case value: ^!", Msg_Sloc);
+            else
+               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
+               Error_Msg ("missing case value: %!", Msg_Sloc);
+            end if;
+
+         --  More than one choice value, so print range of values
+
+         else
+            if Is_Integer_Type (Bounds_Type) then
+               Error_Msg_Uint_1 := Value1;
+               Error_Msg_Uint_2 := Value2;
+               Error_Msg ("missing case values: ^ .. ^!", Msg_Sloc);
+            else
+               Error_Msg_Name_1 := Choice_Image (Value1, Bounds_Type);
+               Error_Msg_Name_2 := Choice_Image (Value2, Bounds_Type);
+               Error_Msg ("missing case values: % .. %!", Msg_Sloc);
+            end if;
+         end if;
+      end Missing_Choice;
+
+      ---------------------
+      -- Missing_Choices --
+      ---------------------
 
-      Hi      : Uint;
-      Lo      : Uint;
-      Prev_Hi : Uint;
+      procedure Missing_Choices (Pred : Node_Id; Prev_Hi : Uint) is
+         Hi  : Uint;
+         Lo  : Uint;
+         Set : Node_Id;
+
+      begin
+         Set := Pred;
+         while Present (Set) loop
+            Lo := Expr_Value (Low_Bound (Set));
+            Hi := Expr_Value (High_Bound (Set));
+
+            --  A choice covered part of a static predicate set
+
+            if Lo <= Prev_Hi and then Prev_Hi < Hi then
+               Missing_Choice (Prev_Hi + 1, Hi);
+
+            else
+               Missing_Choice (Lo, Hi);
+            end if;
+
+            Next (Set);
+         end loop;
+      end Missing_Choices;
+
+      -----------------
+      -- Move_Choice --
+      -----------------
+
+      procedure Move_Choice (From : Natural; To : Natural) is
+      begin
+         Choice_Table (Nat (To)) := Choice_Table (Nat (From));
+      end Move_Choice;
+
+      --  Local variables
+
+      Bounds_Hi     : constant Node_Id := Type_High_Bound (Bounds_Type);
+      Bounds_Lo     : constant Node_Id := Type_Low_Bound  (Bounds_Type);
+      Has_Predicate : constant Boolean :=
+                        Is_Static_Subtype (Bounds_Type)
+                          and then Present (Static_Predicate (Bounds_Type));
+      Num_Choices   : constant Nat     := Choice_Table'Last;
+
+      Choice      : Node_Id;
+      Choice_Hi   : Uint;
+      Choice_Lo   : Uint;
+      Error       : Boolean;
+      Pred        : Node_Id;
+      Prev_Choice : Node_Id;
+      Prev_Lo     : Uint;
+      Prev_Hi     : Uint;
 
    --  Start of processing for Check_Choices
 
    begin
-      --  Choice_Table must start at 0 which is an unused location used
-      --  by the sorting algorithm. However the first valid position for
-      --  a discrete choice is 1.
+      --  Choice_Table must start at 0 which is an unused location used by the
+      --  sorting algorithm. However the first valid position for a discrete
+      --  choice is 1.
 
       pragma Assert (Choice_Table'First = 0);
 
-      if Choice_Table'Last = 0 then
+      --  The choices do not cover the base range. Emit an error if "others" is
+      --  not available and return as there is no need for further processing.
+
+      if Num_Choices = 0 then
          if not Others_Present then
-            Issue_Msg (Bounds_Lo, Bounds_Hi);
+            Missing_Choice (Bounds_Lo, Bounds_Hi);
          end if;
 
          return;
@@ -300,59 +622,98 @@ package body Sem_Case is
 
       Sorting.Sort (Positive (Choice_Table'Last));
 
-      Lo      := Expr_Value (Choice_Table (1).Lo);
-      Hi      := Expr_Value (Choice_Table (1).Hi);
-      Prev_Hi := Hi;
+      --  The type covered by the list of choices is actually a static subtype
+      --  subject to a static predicate. The predicate defines subsets of legal
+      --  values and requires finer grained analysis.
+
+      if Has_Predicate then
+         Pred    := First (Static_Predicate (Bounds_Type));
+         Prev_Lo := Uint_Minus_1;
+         Prev_Hi := Uint_Minus_1;
+         Error   := False;
+
+         for Index in 1 .. Num_Choices loop
+            Check_Against_Predicate
+              (Pred    => Pred,
+               Choice  => Choice_Table (Index),
+               Prev_Lo => Prev_Lo,
+               Prev_Hi => Prev_Hi,
+               Error   => Error);
+
+            --  The analysis detected an illegal intersection between a choice
+            --  and a static predicate set.
 
-      if not Others_Present and then Expr_Value (Bounds_Lo) < Lo then
-         Issue_Msg (Bounds_Lo, Lo - 1);
+            if Error then
+               return;
+            end if;
+         end loop;
 
-         --  If values are missing outside of the subtype, add explanation.
-         --  No additional message if only one value is missing.
+         --  The choices may legally cover some of the static predicate sets,
+         --  but not all. Emit an error for each non-covered set.
 
-         if Expr_Value (Bounds_Lo) < Lo - 1 then
-            Explain_Non_Static_Bound;
+         if not Others_Present then
+            Missing_Choices (Pred, Prev_Hi);
          end if;
-      end if;
 
-      for J in 2 .. Choice_Table'Last loop
-         Lo := Expr_Value (Choice_Table (J).Lo);
-         Hi := Expr_Value (Choice_Table (J).Hi);
+      --  Default analysis
 
-         if Lo <= Prev_Hi then
-            Choice := Choice_Table (J).Node;
+      else
+         Choice_Lo := Expr_Value (Choice_Table (1).Lo);
+         Choice_Hi := Expr_Value (Choice_Table (1).Hi);
+         Prev_Hi   := Choice_Hi;
 
-            --  Find first previous choice that overlaps
+         if not Others_Present and then Expr_Value (Bounds_Lo) < Choice_Lo then
+            Missing_Choice (Bounds_Lo, Choice_Lo - 1);
 
-            for K in 1 .. J - 1 loop
-               if Lo <= Expr_Value (Choice_Table (K).Hi) then
-                  Prev_Choice := Choice_Table (K).Node;
-                  exit;
-               end if;
-            end loop;
+            --  If values are missing outside of the subtype, add explanation.
+            --  No additional message if only one value is missing.
 
-            if Sloc (Prev_Choice) <= Sloc (Choice) then
-               Error_Msg_Sloc := Sloc (Prev_Choice);
-               Error_Msg_N ("duplication of choice value#", Choice);
-            else
-               Error_Msg_Sloc := Sloc (Choice);
-               Error_Msg_N ("duplication of choice value#", Prev_Choice);
+            if Expr_Value (Bounds_Lo) < Choice_Lo - 1 then
+               Explain_Non_Static_Bound;
             end if;
-
-         elsif not Others_Present and then Lo /= Prev_Hi + 1 then
-            Issue_Msg (Prev_Hi + 1, Lo - 1);
          end if;
 
-         if Hi > Prev_Hi then
-            Prev_Hi := Hi;
-         end if;
-      end loop;
+         for Outer_Index in 2 .. Num_Choices loop
+            Choice_Lo := Expr_Value (Choice_Table (Outer_Index).Lo);
+            Choice_Hi := Expr_Value (Choice_Table (Outer_Index).Hi);
+
+            if Choice_Lo <= Prev_Hi then
+               Choice := Choice_Table (Outer_Index).Node;
 
-      if not Others_Present and then Expr_Value (Bounds_Hi) > Hi then
-         Issue_Msg (Hi + 1, Bounds_Hi);
+               --  Find first previous choice that overlaps
 
-         if Expr_Value (Bounds_Hi) > Hi + 1 then
-            Explain_Non_Static_Bound;
+               for Inner_Index in 1 .. Outer_Index - 1 loop
+                  if Choice_Lo <=
+                       Expr_Value (Choice_Table (Inner_Index).Hi)
+                  then
+                     Prev_Choice := Choice_Table (Inner_Index).Node;
+                     exit;
+                  end if;
+               end loop;
+
+               if Sloc (Prev_Choice) <= Sloc (Choice) then
+                  Error_Msg_Sloc := Sloc (Prev_Choice);
+                  Error_Msg_N ("duplication of choice value#", Choice);
+               else
+                  Error_Msg_Sloc := Sloc (Choice);
+                  Error_Msg_N ("duplication of choice value#", Prev_Choice);
+               end if;
+
+            elsif not Others_Present and then Choice_Lo /= Prev_Hi + 1 then
+               Missing_Choice (Prev_Hi + 1, Choice_Lo - 1);
+            end if;
+
+            if Choice_Hi > Prev_Hi then
+               Prev_Hi := Choice_Hi;
+            end if;
+         end loop;
+
+         if not Others_Present and then Expr_Value (Bounds_Hi) > Choice_Hi then
+            Missing_Choice (Choice_Hi + 1, Bounds_Hi);
+
+            if Expr_Value (Bounds_Hi) > Choice_Hi + 1 then
+               Explain_Non_Static_Bound;
+            end if;
          end if;
       end if;
    end Check_Choices;
index 832e7c24aa42518e58fae508929ddea6d9e8540c..654df4320c012a41d370eeedb45e37baa19dcbd1 100644 (file)
@@ -93,7 +93,7 @@ package body Sem_Ch13 is
    --  the function is inserted before the freeze node, and the body of the
    --  function is inserted after the freeze node. If the predicate expression
    --  has at least one Raise_Expression, then this procedure also builds the
-   --  M version of the predicate function for ue in membership tests.
+   --  M version of the predicate function for use in membership tests.
 
    procedure Build_Static_Predicate
      (Typ  : Entity_Id;
@@ -6188,15 +6188,15 @@ package body Sem_Ch13 is
       type REnt is record
          Lo, Hi : Uint;
       end record;
-      --  One entry in a Rlist value, a single REnt (range entry) value
-      --  denotes one range from Lo to Hi. To represent a single value
-      --  range Lo = Hi = value.
+      --  One entry in a Rlist value, a single REnt (range entry) value denotes
+      --  one range from Lo to Hi. To represent a single value range Lo = Hi =
+      --  value.
 
       type RList is array (Nat range <>) of REnt;
-      --  A list of ranges. The ranges are sorted in increasing order,
-      --  and are disjoint (there is a gap of at least one value between
-      --  each range in the table). A value is in the set of ranges in
-      --  Rlist if it lies within one of these ranges
+      --  A list of ranges. The ranges are sorted in increasing order, and are
+      --  disjoint (there is a gap of at least one value between each range in
+      --  the table). A value is in the set of ranges in Rlist if it lies
+      --  within one of these ranges.
 
       False_Range : constant RList :=
                       RList'(1 .. 0 => REnt'(No_Uint, No_Uint));
@@ -6210,41 +6210,41 @@ package body Sem_Ch13 is
       True_Range : constant RList := RList'(1 => REnt'(BLo, BHi));
       --  Range representing True, value must be in the base range
 
-      function "and" (Left, Right : RList) return RList;
-      --  And's together two range lists, returning a range list. This is
-      --  a set intersection operation.
+      function "and" (Left : RList; Right : RList) return RList;
+      --  And's together two range lists, returning a range list. This is a set
+      --  intersection operation.
 
-      function "or" (Left, Right : RList) return RList;
-      --  Or's together two range lists, returning a range list. This is a
-      --  set union operation.
+      function "or" (Left : RList; Right : RList) return RList;
+      --  Or's together two range lists, returning a range list. This is a set
+      --  union operation.
 
       function "not" (Right : RList) return RList;
       --  Returns complement of a given range list, i.e. a range list
-      --  representing all the values in TLo .. THi that are not in the
-      --  input operand Right.
+      --  representing all the values in TLo .. THi that are not in the input
+      --  operand Right.
 
       function Build_Val (V : Uint) return Node_Id;
       --  Return an analyzed N_Identifier node referencing this value, suitable
       --  for use as an entry in the Static_Predicate list. This node is typed
       --  with the base type.
 
-      function Build_Range (Lo, Hi : Uint) return Node_Id;
-      --  Return an analyzed N_Range node referencing this range, suitable
-      --  for use as an entry in the Static_Predicate list. This node is typed
-      --  with the base type.
+      function Build_Range (Lo : Uint; Hi : Uint) return Node_Id;
+      --  Return an analyzed N_Range node referencing this range, suitable for
+      --  use as an entry in the Static_Predicate list. This node is typed with
+      --  the base type.
 
       function Get_RList (Exp : Node_Id) return RList;
-      --  This is a recursive routine that converts the given expression into
-      --  list of ranges, suitable for use in building the static predicate.
+      --  This is a recursive routine that converts the given expression into a
+      --  list of ranges, suitable for use in building the static predicate.
 
       function Is_False (R : RList) return Boolean;
       pragma Inline (Is_False);
-      --  Returns True if the given range list is empty, and thus represents
-      --  False list of ranges that can never be satisfied.
+      --  Returns True if the given range list is empty, and thus represents a
+      --  False list of ranges that can never be satisfied.
 
       function Is_True (R : RList) return Boolean;
-      --  Returns True if R trivially represents the True predicate by having
-      --  single range from BLo to BHi.
+      --  Returns True if R trivially represents the True predicate by having a
+      --  single range from BLo to BHi.
 
       function Is_Type_Ref (N : Node_Id) return Boolean;
       pragma Inline (Is_Type_Ref);
@@ -6277,7 +6277,7 @@ package body Sem_Ch13 is
       -- "and" --
       -----------
 
-      function "and" (Left, Right : RList) return RList is
+      function "and" (Left : RList; Right : RList) return RList is
          FEnt : REnt;
          --  First range of result
 
@@ -6302,8 +6302,8 @@ package body Sem_Ch13 is
             return False_Range;
          end if;
 
-         --  Loop to remove entries at start that are disjoint, and thus
-         --  just get discarded from the result entirely.
+         --  Loop to remove entries at start that are disjoint, and thus just
+         --  get discarded from the result entirely.
 
          loop
             --  If no operands left in either operand, result is false
@@ -6328,15 +6328,15 @@ package body Sem_Ch13 is
             end if;
          end loop;
 
-         --  Now we have two non-null operands, and first entries overlap.
-         --  The first entry in the result will be the overlapping part of
-         --  these two entries.
+         --  Now we have two non-null operands, and first entries overlap. The
+         --  first entry in the result will be the overlapping part of these
+         --  two entries.
 
          FEnt := REnt'(Lo => UI_Max (Left (SLeft).Lo, Right (SRight).Lo),
                        Hi => UI_Min (Left (SLeft).Hi, Right (SRight).Hi));
 
-         --  Now we can remove the entry that ended at a lower value, since
-         --  its contribution is entirely contained in Fent.
+         --  Now we can remove the entry that ended at a lower value, since its
+         --  contribution is entirely contained in Fent.
 
          if Left (SLeft).Hi <= Right (SRight).Hi then
             SLeft := SLeft + 1;
@@ -6344,10 +6344,10 @@ package body Sem_Ch13 is
             SRight := SRight + 1;
          end if;
 
-         --  Compute result by concatenating this first entry with the "and"
-         --  of the remaining parts of the left and right operands. Note that
-         --  if either of these is empty, "and" will yield empty, so that we
-         --  will end up with just Fent, which is what we want in that case.
+         --  Compute result by concatenating this first entry with the "and" of
+         --  the remaining parts of the left and right operands. Note that if
+         --  either of these is empty, "and" will yield empty, so that we will
+         --  end up with just Fent, which is what we want in that case.
 
          return
            FEnt & (Left (SLeft .. Left'Last) and Right (SRight .. Right'Last));
@@ -6411,7 +6411,7 @@ package body Sem_Ch13 is
       -- "or" --
       ----------
 
-      function "or" (Left, Right : RList) return RList is
+      function "or" (Left : RList; Right : RList) return RList is
          FEnt : REnt;
          --  First range of result
 
@@ -6436,8 +6436,8 @@ package body Sem_Ch13 is
             return Left;
          end if;
 
-         --  Initialize result first entry from left or right operand
-         --  depending on which starts with the lower range.
+         --  Initialize result first entry from left or right operand depending
+         --  on which starts with the lower range.
 
          if Left (SLeft).Lo < Right (SRight).Lo then
             FEnt := Left (SLeft);
@@ -6447,12 +6447,12 @@ package body Sem_Ch13 is
             SRight := SRight + 1;
          end if;
 
-         --  This loop eats ranges from left and right operands that
-         --  are contiguous with the first range we are gathering.
+         --  This loop eats ranges from left and right operands that are
+         --  contiguous with the first range we are gathering.
 
          loop
-            --  Eat first entry in left operand if contiguous or
-            --  overlapped by gathered first operand of result.
+            --  Eat first entry in left operand if contiguous or overlapped by
+            --  gathered first operand of result.
 
             if SLeft <= Left'Last
               and then Left (SLeft).Lo <= FEnt.Hi + 1
@@ -6460,8 +6460,8 @@ package body Sem_Ch13 is
                FEnt.Hi := UI_Max (FEnt.Hi, Left (SLeft).Hi);
                SLeft := SLeft + 1;
 
-               --  Eat first entry in right operand if contiguous or
-               --  overlapped by gathered right operand of result.
+            --  Eat first entry in right operand if contiguous or overlapped by
+            --  gathered right operand of result.
 
             elsif SRight <= Right'Last
               and then Right (SRight).Lo <= FEnt.Hi + 1
@@ -6469,7 +6469,7 @@ package body Sem_Ch13 is
                FEnt.Hi := UI_Max (FEnt.Hi, Right (SRight).Hi);
                SRight := SRight + 1;
 
-               --  All done if no more entries to eat!
+            --  All done if no more entries to eat
 
             else
                exit;
@@ -6488,20 +6488,18 @@ package body Sem_Ch13 is
       -- Build_Range --
       -----------------
 
-      function Build_Range (Lo, Hi : Uint) return Node_Id is
+      function Build_Range (Lo : Uint; Hi : Uint) return Node_Id is
          Result : Node_Id;
+
       begin
-         if Lo = Hi then
-            return Build_Val (Hi);
-         else
-            Result :=
-              Make_Range (Loc,
-                Low_Bound  => Build_Val (Lo),
-                High_Bound => Build_Val (Hi));
-            Set_Etype (Result, Btyp);
-            Set_Analyzed (Result);
-            return Result;
-         end if;
+         Result :=
+           Make_Range (Loc,
+             Low_Bound  => Build_Val (Lo),
+             High_Bound => Build_Val (Hi));
+         Set_Etype (Result, Btyp);
+         Set_Analyzed (Result);
+
+         return Result;
       end Build_Range;
 
       ---------------
@@ -6911,11 +6909,7 @@ package body Sem_Ch13 is
 
                   --  Convert range into required form
 
-                  if Lo = Hi then
-                     Append_To (Plist, Build_Val (Lo));
-                  else
-                     Append_To (Plist, Build_Range (Lo, Hi));
-                  end if;
+                  Append_To (Plist, Build_Range (Lo, Hi));
                end if;
             end;
          end loop;
@@ -9452,12 +9446,12 @@ package body Sem_Ch13 is
       --  storage orders differ.
 
       if (Is_Record_Type (T1) or else Is_Array_Type (T1))
-        and then
+            and then
          (Is_Record_Type (T2) or else Is_Array_Type (T2))
         and then
          (Component_Alignment (T1) /= Component_Alignment (T2)
             or else
-          Reverse_Storage_Order (T1) /= Reverse_Storage_Order (T2))
+              Reverse_Storage_Order (T1) /= Reverse_Storage_Order (T2))
       then
          return False;
       end if;
index 421cd81b5c38f3da01bed453c52de1445add1c3a..cd262601cdb2d723e0bd86fe430a00c459280992 100644 (file)
@@ -1248,14 +1248,8 @@ package body Sem_Ch4 is
    -----------------------------
 
    procedure Analyze_Case_Expression (N : Node_Id) is
-      Expr      : constant Node_Id := Expression (N);
-      FirstX    : constant Node_Id := Expression (First (Alternatives (N)));
-      Alt       : Node_Id;
-      Exp_Type  : Entity_Id;
-      Exp_Btype : Entity_Id;
-
-      Dont_Care      : Boolean;
-      Others_Present : Boolean;
+      function Has_Static_Predicate (Subtyp : Entity_Id) return Boolean;
+      --  Determine whether subtype Subtyp has aspect Static_Predicate
 
       procedure Non_Static_Choice_Error (Choice : Node_Id);
       --  Error routine invoked by the generic instantiation below when
@@ -1270,6 +1264,28 @@ package body Sem_Ch4 is
            Process_Associated_Node   => No_OP);
       use Case_Choices_Processing;
 
+      --------------------------
+      -- Has_Static_Predicate --
+      --------------------------
+
+      function Has_Static_Predicate (Subtyp : Entity_Id) return Boolean is
+         Item : Node_Id;
+
+      begin
+         Item := First_Rep_Item (Subtyp);
+         while Present (Item) loop
+            if Nkind (Item) = N_Aspect_Specification
+              and then Chars (Identifier (Item)) = Name_Static_Predicate
+            then
+               return True;
+            end if;
+
+            Next_Rep_Item (Item);
+         end loop;
+
+         return False;
+      end Has_Static_Predicate;
+
       -----------------------------
       -- Non_Static_Choice_Error --
       -----------------------------
@@ -1280,6 +1296,17 @@ package body Sem_Ch4 is
            ("choice given in case expression is not static!", Choice);
       end Non_Static_Choice_Error;
 
+      --  Local variables
+
+      Expr      : constant Node_Id := Expression (N);
+      FirstX    : constant Node_Id := Expression (First (Alternatives (N)));
+      Alt       : Node_Id;
+      Exp_Type  : Entity_Id;
+      Exp_Btype : Entity_Id;
+
+      Dont_Care      : Boolean;
+      Others_Present : Boolean;
+
    --  Start of processing for Analyze_Case_Expression
 
    begin
@@ -1364,9 +1391,22 @@ package body Sem_Ch4 is
          Exp_Type := Exp_Btype;
       end if;
 
+      --  The case expression alternatives cover the range of a static subtype
+      --  subject to aspect Static_Predicate. Do not check the choices when the
+      --  case expression has not been fully analyzed yet because this may lead
+      --  to bogus errors.
+
+      if Is_Static_Subtype (Exp_Type)
+        and then Has_Static_Predicate (Exp_Type)
+        and then In_Spec_Expression
+      then
+         null;
+
       --  Call instantiated Analyze_Choices which does the rest of the work
 
-      Analyze_Choices (N, Exp_Type, Dont_Care, Others_Present);
+      else
+         Analyze_Choices (N, Exp_Type, Dont_Care, Others_Present);
+      end if;
 
       if Exp_Type = Universal_Integer and then not Others_Present then
          Error_Msg_N
@@ -1896,10 +1936,9 @@ package body Sem_Ch4 is
 
    begin
       A := First (Actions (N));
-      loop
+      while Present (A) loop
          Analyze (A);
          Next (A);
-         exit when No (A);
       end loop;
 
       --  This test needs a comment ???
diff --git a/gcc/ada/set_targ.adb b/gcc/ada/set_targ.adb
new file mode 100755 (executable)
index 0000000..ee72d57
--- /dev/null
@@ -0,0 +1,854 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                             S E T _ T A R G                              --
+--                                                                          --
+--                                 B o d y                                  --
+--                                                                          --
+--            Copyright (C) 2013, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
+-- for  more details.  You should have  received  a copy of the GNU General --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+with Debug;    use Debug;
+with Get_Targ; use Get_Targ;
+with Opt;      use Opt;
+with Output;   use Output;
+
+with System;        use System;
+with System.OS_Lib; use System.OS_Lib;
+
+with Unchecked_Conversion;
+
+package body Set_Targ is
+
+   ---------------------------------------------
+   -- Data Used to Read/Write target.atp File --
+   ---------------------------------------------
+
+   File_Name : aliased constant String := "target.atp";
+   --  Name of file to read/write
+
+   --  Table of string names written to file
+
+   subtype Str is String;
+
+   S_Bits_BE                    : constant Str := "Bits_BE";
+   S_Bits_Per_Unit              : constant Str := "Bits_Per_Unit";
+   S_Bits_Per_Word              : constant Str := "Bits_Per_Word";
+   S_Bytes_BE                   : constant Str := "Bytes_BE";
+   S_Char_Size                  : constant Str := "Char_Size";
+   S_Double_Float_Alignment     : constant Str := "Double_Float_Alignment";
+   S_Double_Scalar_Alignment    : constant Str := "Double_Scalar_Alignment";
+   S_Double_Size                : constant Str := "Double_Size";
+   S_Float_Size                 : constant Str := "Float_Size";
+   S_Float_Words_BE             : constant Str := "Float_Words_BE";
+   S_Int_Size                   : constant Str := "Int_Size";
+   S_Long_Double_Size           : constant Str := "Long_Double_Size";
+   S_Long_Long_Size             : constant Str := "Long_Long_Size";
+   S_Long_Size                  : constant Str := "Long_Size";
+   S_Maximum_Alignment          : constant Str := "Maximum_Alignment";
+   S_Max_Unaligned_Field        : constant Str := "Max_Unaligned_Field";
+   S_Pointer_Size               : constant Str := "Pointer_Size";
+   S_Short_Size                 : constant Str := "Short_Size";
+   S_Strict_Alignment           : constant Str := "Strict_Alignment";
+   S_System_Allocator_Alignment : constant Str := "System_Allocator_Alignment";
+   S_Wchar_T_Size               : constant Str := "Wchar_T_Size";
+   S_Words_BE                   : constant Str := "Words_BE";
+
+   --  Table of names
+
+   type AStr is access all String;
+
+   DTN : constant array (Nat range <>) of AStr := (
+          S_Bits_BE                    'Unrestricted_Access,
+          S_Bits_Per_Unit              'Unrestricted_Access,
+          S_Bits_Per_Word              'Unrestricted_Access,
+          S_Bytes_BE                   'Unrestricted_Access,
+          S_Char_Size                  'Unrestricted_Access,
+          S_Double_Float_Alignment     'Unrestricted_Access,
+          S_Double_Scalar_Alignment    'Unrestricted_Access,
+          S_Double_Size                'Unrestricted_Access,
+          S_Float_Size                 'Unrestricted_Access,
+          S_Float_Words_BE             'Unrestricted_Access,
+          S_Int_Size                   'Unrestricted_Access,
+          S_Long_Double_Size           'Unrestricted_Access,
+          S_Long_Long_Size             'Unrestricted_Access,
+          S_Long_Size                  'Unrestricted_Access,
+          S_Maximum_Alignment          'Unrestricted_Access,
+          S_Max_Unaligned_Field        'Unrestricted_Access,
+          S_Pointer_Size               'Unrestricted_Access,
+          S_Short_Size                 'Unrestricted_Access,
+          S_Strict_Alignment           'Unrestricted_Access,
+          S_System_Allocator_Alignment 'Unrestricted_Access,
+          S_Wchar_T_Size               'Unrestricted_Access,
+          S_Words_BE                   'Unrestricted_Access);
+
+   --  Table of corresponding value pointers
+
+   DTV : constant array (Nat range <>) of System.Address := (
+          Bits_BE                    'Address,
+          Bits_Per_Unit              'Address,
+          Bits_Per_Word              'Address,
+          Bytes_BE                   'Address,
+          Char_Size                  'Address,
+          Double_Float_Alignment     'Address,
+          Double_Scalar_Alignment    'Address,
+          Double_Size                'Address,
+          Float_Size                 'Address,
+          Float_Words_BE             'Address,
+          Int_Size                   'Address,
+          Long_Double_Size           'Address,
+          Long_Long_Size             'Address,
+          Long_Size                  'Address,
+          Maximum_Alignment          'Address,
+          Max_Unaligned_Field        'Address,
+          Pointer_Size               'Address,
+          Short_Size                 'Address,
+          Strict_Alignment           'Address,
+          System_Allocator_Alignment 'Address,
+          Wchar_T_Size               'Address,
+          Words_BE                   'Address);
+
+   DTR : array (Nat range DTV'Range) of Boolean := (others => False);
+   --  Table of flags used to validate that all values are present in file
+
+   -----------------------
+   -- Local Subprograms --
+   -----------------------
+
+   procedure Fail (E : String);
+   pragma No_Return (Fail);
+   --  Terminate program with fatal error message passed as parameter
+
+   type C_String is array (0 .. 255) of aliased Character;
+   pragma Convention (C, C_String);
+   --  String long enough to hold any mode name for the following call
+
+   procedure Register_Float_Type
+     (Name      : C_String;
+      Digs      : Natural;
+      Complex   : Boolean;
+      Count     : Natural;
+      Float_Rep : Float_Rep_Kind;
+      Size      : Positive;
+      Alignment : Natural);
+   pragma Convention (C, Register_Float_Type);
+   --  Call back to allow the back end to register available types. This call
+   --  back makes entries in the FPT_Mode_Table for any floating point types
+   --  reported by the back end. Name is the name of the type as a normal
+   --  format Null-terminated string. Digs is the number of digits, where 0
+   --  means it is not a fpt type (ignored during registration). Complex is
+   --  non-zero if the type has real and imaginary parts (also ignored during
+   --  registration). Count is the number of elements in a vector type (zero =
+   --  not a vector, registration ignores vectors). Float_Rep shows the kind of
+   --  floating-point type, and Size/Alignment are the size/alignment in bits.
+   --
+   --  So to summarize, the only types that are actually registered have Digs
+   --  non-zero, Complex zero (false), and Count zero (not a vector).
+
+   ----------
+   -- Fail --
+   ----------
+
+   procedure Fail (E : String) is
+      E_Fatal : constant := 4;
+      --  Code for fatal error
+   begin
+      Write_Str (E);
+      Write_Eol;
+      OS_Exit (E_Fatal);
+   end Fail;
+
+   -------------------------
+   -- Register_Float_Type --
+   -------------------------
+
+   procedure Register_Float_Type
+     (Name      : C_String;
+      Digs      : Natural;
+      Complex   : Boolean;
+      Count     : Natural;
+      Float_Rep : Float_Rep_Kind;
+      Size      : Positive;
+      Alignment : Natural)
+   is
+      T    : String (1 .. Name'Length);
+      Last : Natural := 0;
+
+      procedure Dump;
+      --  Dump information given by the back end for the type to register
+
+      ----------
+      -- Dump --
+      ----------
+
+      procedure Dump is
+      begin
+         Write_Str ("type " & T (1 .. Last) & " is ");
+
+         if Count > 0 then
+            Write_Str ("array (1 .. ");
+            Write_Int (Int (Count));
+
+            if Complex then
+               Write_Str (", 1 .. 2");
+            end if;
+
+            Write_Str (") of ");
+
+         elsif Complex then
+            Write_Str ("array (1 .. 2) of ");
+         end if;
+
+         if Digs > 0 then
+            Write_Str ("digits ");
+            Write_Int (Int (Digs));
+            Write_Line (";");
+
+            Write_Str ("pragma Float_Representation (");
+
+            case Float_Rep is
+               when IEEE_Binary =>
+                  Write_Str ("IEEE");
+
+               when VAX_Native =>
+                  case Digs is
+                     when  6 =>
+                        Write_Str ("VAXF");
+
+                     when  9 =>
+                        Write_Str ("VAXD");
+
+                     when 15 =>
+                        Write_Str ("VAXG");
+
+                     when others =>
+                        Write_Str ("VAX_");
+                        Write_Int (Int (Digs));
+                  end case;
+
+               when AAMP =>         Write_Str ("AAMP");
+            end case;
+
+            Write_Line (", " & T (1 .. Last) & ");");
+
+         else
+            Write_Str ("mod 2**");
+            Write_Int (Int (Size / Positive'Max (1, Count)));
+            Write_Line (";");
+         end if;
+
+         Write_Str ("for " & T (1 .. Last) & "'Size use ");
+         Write_Int (Int (Size));
+         Write_Line (";");
+
+         Write_Str ("for " & T (1 .. Last) & "'Alignment use ");
+         Write_Int (Int (Alignment / 8));
+         Write_Line (";");
+         Write_Eol;
+      end Dump;
+
+   --  Start of processing for Register_Float_Type
+
+   begin
+      --  Acquire name
+
+      for J in T'Range loop
+         T (J) := Name (Name'First + J - 1);
+
+         if T (J) = ASCII.NUL then
+            Last := J - 1;
+            exit;
+         end if;
+      end loop;
+
+      --  Dump info if debug flag set
+
+      if Debug_Flag_Dot_B then
+         Dump;
+      end if;
+
+      --  Acquire entry if non-vector non-complex fpt type (digits non-zero)
+
+      if Digs > 0 and then not Complex and then Count = 0 then
+         Num_FPT_Modes := Num_FPT_Modes + 1;
+         FPT_Mode_Table (Num_FPT_Modes) :=
+           (NAME      => new String'(T (1 .. Last)),
+            DIGS      => Digs,
+            FLOAT_REP => Float_Rep,
+            SIZE      => Size,
+            ALIGNMENT => Alignment);
+      end if;
+   end Register_Float_Type;
+
+   -----------------------------------
+   -- Write_Target_Dependent_Values --
+   -----------------------------------
+
+   --  We do this at the System.Os_Lib level, since we have to do the read at
+   --  that level anyway, so it is easier and more consistent to follow the
+   --  same path for the write.
+
+   procedure Write_Target_Dependent_Values is
+      Fdesc  : File_Descriptor;
+      OK     : Boolean;
+
+      Buffer : String (1 .. 80);
+      Buflen : Natural;
+      --  Buffer used to build line one of file
+
+      type ANat is access all Natural;
+      --  Pointer to Nat or Pos value (it is harmless to treat Pos values and
+      --  Nat values as Natural via Unchecked_Conversion).
+
+      function To_ANat is new Unchecked_Conversion (Address, ANat);
+
+      procedure AddC (C : Character);
+      --  Add one character to buffer
+
+      procedure AddN (N : Natural);
+      --  Add representation of integer N to Buffer, updating Buflen. N
+      --  must be less than 1000, and output is 3 characters with leading
+      --  spaces as needed.
+
+      procedure Write_Line;
+      --  Output contents of Buffer (1 .. Buflen) followed by a New_Line,
+      --  and set Buflen back to zero.
+
+      ----------
+      -- AddC --
+      ----------
+
+      procedure AddC (C : Character) is
+      begin
+         Buflen := Buflen + 1;
+         Buffer (Buflen) := C;
+      end AddC;
+
+      ----------
+      -- AddN --
+      ----------
+
+      procedure AddN (N : Natural) is
+      begin
+         if N > 999 then
+            raise Program_Error;
+         end if;
+
+         if N > 99 then
+            AddC (Character'Val (48 + N / 100));
+         else
+            AddC (' ');
+         end if;
+
+         if N > 9 then
+            AddC (Character'Val (48 + N / 10 mod 10));
+         else
+            AddC (' ');
+         end if;
+
+         AddC (Character'Val (48 + N mod 10));
+      end AddN;
+
+      ----------------
+      -- Write_Line --
+      ----------------
+
+      procedure Write_Line is
+      begin
+         AddC (ASCII.LF);
+
+         if Buflen /= Write (Fdesc, Buffer'Address, Buflen) then
+            Delete_File (File_Name'Address, OK);
+            Fail ("disk full writing target.atp");
+         end if;
+
+         Buflen := 0;
+      end Write_Line;
+
+   --  Start of processing for Write_Target_Dependent_Values
+
+   begin
+      Fdesc := Create_File (File_Name'Address, Text);
+
+      if Fdesc = Invalid_FD then
+         Fail ("cannot create target.atp");
+      end if;
+
+      --  Loop through values
+
+      for J in DTN'Range loop
+
+         --  Output name
+
+         Buflen := DTN (J)'Length;
+         Buffer (1 .. Buflen) := DTN (J).all;
+
+         --  Line up values
+
+         while Buflen < 26 loop
+            AddC (' ');
+         end loop;
+
+         AddC (' ');
+         AddC (' ');
+
+         --  Output value and write line
+
+         AddN (To_ANat (DTV (J)).all);
+         Write_Line;
+      end loop;
+
+      --  Blank line to separate sections
+
+      Write_Line;
+
+      --  Write lines for registered FPT types
+
+      for J in 1 .. Num_FPT_Modes loop
+         declare
+            E : FPT_Mode_Entry renames FPT_Mode_Table (J);
+         begin
+            Buflen := E.NAME'Last;
+            Buffer (1 .. Buflen) := E.NAME.all;
+
+            --  Pad out to line up values
+
+            while Buflen < 11 loop
+               AddC (' ');
+            end loop;
+
+            AddC (' ');
+            AddC (' ');
+
+            AddN (E.DIGS);
+            AddC (' ');
+            AddC (' ');
+
+            case E.FLOAT_REP is
+               when IEEE_Binary =>
+                  AddC ('I');
+               when VAX_Native  =>
+                  AddC ('V');
+               when AAMP        =>
+                  AddC ('A');
+            end case;
+
+            AddC (' ');
+
+            AddN (E.SIZE);
+            AddC (' ');
+
+            AddN (E.ALIGNMENT);
+            Write_Line;
+         end;
+      end loop;
+
+      --  Close file
+
+      Close (Fdesc, OK);
+
+      if not OK then
+         Fail ("disk full writing target.atp");
+      end if;
+   end Write_Target_Dependent_Values;
+
+--  Package Initialization, set target dependent values. This must be done
+--  early on, before we start accessing various compiler packages, since
+--  these values are used all over the place.
+
+begin
+   --  First step: see if the -gnateT switch is present. As we have noted,
+   --  this has to be done very early, so can not depend on the normal circuit
+   --  for reading switches and setting switches in opt. The following code
+   --  will set Opt.Target_Dependent_Info_Read if an option starting -gnatet
+   --  is present in the options string.
+
+   declare
+      type Arg_Array is array (Nat) of Big_String_Ptr;
+      type Arg_Array_Ptr is access Arg_Array;
+      --  Types to access compiler arguments
+
+      save_argc : Nat;
+      pragma Import (C, save_argc);
+      --  Saved value of argc (number of arguments), imported from misc.c
+
+      save_argv : Arg_Array_Ptr;
+      pragma Import (C, save_argv);
+      --  Saved value of argv (argument pointers), imported from misc.c
+
+   begin
+      --  Loop through arguments looking for -gnateT, also look for -gnatd.b
+
+      for Arg in 1 .. save_argc - 1 loop
+         declare
+            Argv_Ptr : constant Big_String_Ptr := save_argv (Arg);
+         begin
+            if Argv_Ptr (1 .. 7) = "-gnateT" then
+               Opt.Target_Dependent_Info_Read := True;
+            elsif Argv_Ptr (1 .. 8) = "-gnatd.b" then
+               Debug_Flag_Dot_B := True;
+            end if;
+         end;
+      end loop;
+   end;
+
+   --  If the switch is not set, we get all values from the back end
+
+   if not Opt.Target_Dependent_Info_Read then
+
+      --  Set values set by direct calls to the back end
+
+      Bits_BE                    := Get_Bits_BE;
+      Bits_Per_Unit              := Get_Bits_Per_Unit;
+      Bits_Per_Word              := Get_Bits_Per_Word;
+      Bytes_BE                   := Get_Bytes_BE;
+      Char_Size                  := Get_Char_Size;
+      Double_Float_Alignment     := Get_Double_Float_Alignment;
+      Double_Scalar_Alignment    := Get_Double_Scalar_Alignment;
+      Double_Size                := Get_Double_Size;
+      Float_Size                 := Get_Float_Size;
+      Float_Words_BE             := Get_Float_Words_BE;
+      Int_Size                   := Get_Int_Size;
+      Long_Double_Size           := Get_Long_Double_Size;
+      Long_Long_Size             := Get_Long_Long_Size;
+      Long_Size                  := Get_Long_Size;
+      Maximum_Alignment          := Get_Maximum_Alignment;
+      Max_Unaligned_Field        := Get_Max_Unaligned_Field;
+      Pointer_Size               := Get_Pointer_Size;
+      Short_Size                 := Get_Short_Size;
+      Strict_Alignment           := Get_Strict_Alignment;
+      System_Allocator_Alignment := Get_System_Allocator_Alignment;
+      Wchar_T_Size               := Get_Wchar_T_Size;
+      Words_BE                   := Get_Words_BE;
+
+      --  Register floating-point types from the back end (depending on the
+      --  back end in use, we have to do different things to get this info).
+
+      case Get_Back_End is
+
+         --  GCC back end, get information using Enumerate_Modes
+
+         when GCC =>
+            declare
+               type Register_Type_Proc is access procedure
+                 (C_Name    : C_String;
+                  Digs      : Natural;
+                  Complex   : Boolean;
+                  Count     : Natural;
+                  Float_Rep : Float_Rep_Kind;
+                  Size      : Positive;
+                  Alignment : Natural);
+               pragma Convention (C, Register_Type_Proc);
+               --  Call back procedure for Register_Back_End_Types
+
+               procedure Enumerate_Modes (Call_Back : Register_Type_Proc);
+               pragma Import (C, Enumerate_Modes, "enumerate_modes");
+               --  Back end procedure that does the call backs (see misc.c)
+
+            begin
+               Num_FPT_Modes := 0;
+               Enumerate_Modes (Register_Float_Type'Access);
+            end;
+
+         --  AAMP back end, supply the two needed types directly
+
+         when AAMP =>
+            declare
+               Str : C_String;
+
+            begin
+               Str (1 .. 6) := "float" & ASCII.NUL;
+               Register_Float_Type
+                 (Name      => Str,
+                  Digs      => 6,
+                  Complex   => False,
+                  Count     => 0,
+                  Float_Rep => AAMP,
+                  Size      => 32,
+                  Alignment => 16);
+
+               Str (1 .. 7) := "double" & ASCII.NUL;
+               Register_Float_Type
+                 (Name      => Str,
+                  Digs      => 9,
+                  Complex   => False,
+                  Count     => 0,
+                  Float_Rep => AAMP,
+                  Size      => 48,
+                  Alignment => 16);
+            end;
+
+            --  DotNet TBD
+
+         when DOTNET =>
+            null;
+      end case;
+
+      --  Case of reading the target dependent values from target.atp
+
+      --  This is bit more complex than might be expected, because it has to
+      --  be done very early. All kinds of packages depend on these values,
+      --  and we can't wait till the normal processing of reading command line
+      --  switches etc to read the file. We do this at the System.OS_Lib level
+      --  since it is too early to be using Osint directly.
+
+   else
+      Read_File : declare
+         File_Desc : File_Descriptor;
+         N         : Natural;
+
+         type ANat is access all Natural;
+         --  Pointer to Nat or Pos value (it is harmless to treat Pos values
+         --  as Nat via Unchecked_Conversion).
+
+         function To_ANat is new Unchecked_Conversion (Address, ANat);
+
+         VP : ANat;
+
+         Buffer : String (1 .. 2000);
+         Buflen : Natural;
+         --  File information and length (2000 easily enough!)
+
+         Nam_Buf : String (1 .. 40);
+         Nam_Len : Natural;
+
+         procedure Check_Spaces;
+         --  Checks that we have one or more spaces and skips them
+
+         procedure FailN (S : String);
+         --  Calls Fail prefixing "target.atp: " to the start of the given
+         --  string, and " name" to the end where name is the currently
+         --  gathered name in Nam_Buf, surrounded by quotes.
+
+         procedure Get_Name;
+         --  Scan out name, leaving it in Nam_Buf with Nam_Len set. Calls
+         --  Skip_Spaces to skip any following spaces. Note that the name is
+         --  terminated by a sequence of at least two spaces.
+
+         function Get_Nat return Natural;
+         --  N on entry points to decimal integer, scan out decimal integer
+         --  and return it, leaving N pointing to following space or LF.
+
+         procedure Skip_Spaces;
+         --  Skip past spaces
+
+         ------------------
+         -- Check_Spaces --
+         ------------------
+
+         procedure Check_Spaces is
+         begin
+            if N > Buflen or else Buffer (N) /= ' ' then
+               FailN ("missing space for");
+            end if;
+
+            Skip_Spaces;
+            return;
+         end Check_Spaces;
+
+         -----------
+         -- FailN --
+         -----------
+
+         procedure FailN (S : String) is
+         begin
+            Fail ("target.atp: " & S & " """ & Nam_Buf (1 .. Nam_Len) & '"');
+         end FailN;
+
+         --------------
+         -- Get_Name --
+         --------------
+
+         procedure Get_Name is
+         begin
+            Nam_Len := 0;
+
+            --  Scan out name and put it in Nam_Buf
+
+            loop
+               if N > Buflen or else Buffer (N) = ASCII.LF then
+                  FailN ("incorrectly formatted line for");
+               end if;
+
+               --  Name is terminated by two blanks
+
+               exit when N < Buflen and then Buffer (N .. N + 1) = "  ";
+
+               Nam_Len := Nam_Len + 1;
+
+               if Nam_Len > Nam_Buf'Last then
+                  Fail ("name too long");
+               end if;
+
+               Nam_Buf (Nam_Len) := Buffer (N);
+               N := N + 1;
+            end loop;
+
+            Check_Spaces;
+         end Get_Name;
+
+         -------------
+         -- Get_Nat --
+         -------------
+
+         function Get_Nat return Natural is
+            Result : Natural := 0;
+
+         begin
+            loop
+               if N > Buflen
+                 or else Buffer (N) not in '0' .. '9'
+                 or else Result > 999
+               then
+                  FailN ("bad value for");
+               end if;
+
+               Result := Result * 10 + (Character'Pos (Buffer (N)) - 48);
+               N := N + 1;
+
+               exit when N <= Buflen
+                 and then (Buffer (N) = ASCII.LF or else Buffer (N) = ' ');
+            end loop;
+
+            return Result;
+         end Get_Nat;
+
+         -----------------
+         -- Skip_Spaces --
+         -----------------
+
+         procedure Skip_Spaces is
+         begin
+            while N <= Buflen and Buffer (N) = ' ' loop
+               N := N + 1;
+            end loop;
+         end Skip_Spaces;
+
+      --  Start of processing for Read_File
+
+      begin
+         File_Desc := Open_Read ("target.atp", Text);
+
+         if File_Desc = Invalid_FD then
+            Fail ("cannot read target.atp file");
+         end if;
+
+         Buflen := Read (File_Desc, Buffer'Address, Buffer'Length);
+
+         if Buflen = Buffer'Length then
+            Fail ("target.atp file is too long");
+         end if;
+
+         --  Scan through file for properly formatted entries in first section
+
+         N := 1;
+         while N <= Buflen and then Buffer (N) /= ASCII.LF loop
+            Get_Name;
+
+            --  Validate name and get corresponding value pointer
+
+            VP := null;
+
+            for J in DTN'Range loop
+               if DTN (J).all = Nam_Buf (1 .. Nam_Len) then
+                  VP := To_ANat (DTV (J));
+                  DTR (J) := True;
+                  exit;
+               end if;
+            end loop;
+
+            if VP = null then
+               FailN ("unrecognized name");
+            end if;
+
+            --  Scan out value
+
+            VP.all := Get_Nat;
+
+            if N > Buflen or else Buffer (N) /= ASCII.LF then
+               FailN ("misformatted line for");
+            end if;
+
+            N := N + 1; -- skip LF
+         end loop;
+
+         --  Fall through this loop when all lines in first section read.
+         --  Check that values have been supplied for all entries.
+
+         for J in DTR'Range loop
+            if not DTR (J) then
+               Fail ("missing entry in target.atp for " & DTN (J).all);
+            end if;
+         end loop;
+
+         --  Now acquire FPT entries
+
+         if N >= Buflen then
+            Fail ("target.atp is missing entries for FPT modes");
+         end if;
+
+         if Buffer (N) = ASCII.LF then
+            N := N + 1;
+         else
+            Fail ("target.atp is missing blank line");
+         end if;
+
+         Num_FPT_Modes := 0;
+         while N <= Buflen loop
+            Get_Name;
+
+            Num_FPT_Modes := Num_FPT_Modes + 1;
+
+            declare
+               E : FPT_Mode_Entry renames FPT_Mode_Table (Num_FPT_Modes);
+
+            begin
+               E.NAME := new String'(Nam_Buf (1 .. Nam_Len));
+
+               E.DIGS := Get_Nat;
+               Check_Spaces;
+
+               case Buffer (N) is
+                  when 'I'    =>
+                     E.FLOAT_REP := IEEE_Binary;
+                  when 'V'    =>
+                     E.FLOAT_REP := VAX_Native;
+                  when 'A'    =>
+                     E.FLOAT_REP := AAMP;
+                  when others =>
+                     FailN ("bad float rep field for");
+               end case;
+
+               N := N + 1;
+               Check_Spaces;
+
+               E.SIZE := Get_Nat;
+               Check_Spaces;
+
+               E.ALIGNMENT := Get_Nat;
+
+               if Buffer (N) /= ASCII.LF then
+                  FailN ("junk at end of line for");
+               end if;
+
+               N := N + 1;
+            end;
+         end loop;
+      end Read_File;
+   end if;
+end Set_Targ;
diff --git a/gcc/ada/set_targ.ads b/gcc/ada/set_targ.ads
new file mode 100755 (executable)
index 0000000..5b5820c
--- /dev/null
@@ -0,0 +1,144 @@
+------------------------------------------------------------------------------
+--                                                                          --
+--                         GNAT COMPILER COMPONENTS                         --
+--                                                                          --
+--                             S E T _ T A R G                              --
+--                                                                          --
+--                                 S p e c                                  --
+--                                                                          --
+--            Copyright (C) 2013, Free Software Foundation, Inc.            --
+--                                                                          --
+-- GNAT is free software;  you can  redistribute it  and/or modify it under --
+-- terms of the  GNU General Public License as published  by the Free Soft- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
+-- for  more details.  You should have  received  a copy of the GNU General --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
+--                                                                          --
+-- GNAT was originally developed  by the GNAT team at  New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
+--                                                                          --
+------------------------------------------------------------------------------
+
+--  This package handles setting target dependent parameters. If the -gnatet
+--  switch is not set, then these values are taken from the back end (via the
+--  routines in Get_Targ, and the enumerate_modes routine in misc.c). If the
+--  switch is set, then the values are read from the target.atp file in the
+--  current directory (usually written with the Write_Target_Dependent_Values
+--  procedure defined in this package).
+
+--  Note that all these values return sizes of C types with corresponding
+--  names. This allows GNAT to define the corresponding Ada types to have
+--  the same representation. There is one exception: the representation
+--  of Wide_Character_Type uses twice the size of a C char, instead of the
+--  size of wchar_t, since this corresponds to expected Ada usage.
+
+with Einfo; use Einfo;
+with Types; use Types;
+
+package Set_Targ is
+
+   -----------------------------
+   -- Target-Dependent Values --
+   -----------------------------
+
+   --  The following is a table of target dependent values. In normal operation
+   --  these values are set by calling the appropriate C backend routines that
+   --  interface to back end routines that determine target characteristics.
+
+   --  If the -gnateT switch is used, then any values that are read from the
+   --  file target.atp in the current directory overwrite values set from the
+   --  back end. This is used by tools other than the compiler, e.g. to do
+   --  semantic analysis of programs that will run on some other target than
+   --  the machine on which the tool is run.
+
+   --  Note: fields marked with a question mark are boolean fields, where a
+   --  value of 0 is False, and a value of 1 is True.
+
+   Bits_BE                    : Nat; -- Bits stored big-endian?
+   Bits_Per_Unit              : Pos; -- Bits in a storage unit
+   Bits_Per_Word              : Pos; -- Bits in a word
+   Bytes_BE                   : Nat; -- Bytes stored big-endian?
+   Char_Size                  : Pos; -- Standard.Character'Size
+   Double_Float_Alignment     : Nat; -- Alignment of double float
+   Double_Scalar_Alignment    : Nat; -- Alignment of double length scalar
+   Double_Size                : Pos; -- Standard.Long_Float'Size
+   Float_Size                 : Pos; -- Standard.Float'Size
+   Float_Words_BE             : Nat; -- Float words stored big-endian?
+   Int_Size                   : Pos; -- Standard.Integer'Size
+   Long_Double_Size           : Pos; -- Standard.Long_Long_Float'Size
+   Long_Long_Size             : Pos; -- Standard.Long_Long_Integer'Size
+   Long_Size                  : Pos; -- Standard.Long_Integer'Size
+   Maximum_Alignment          : Pos; -- Maximum permitted alignment
+   Max_Unaligned_Field        : Pos; -- Maximum size for unaligned bit field
+   Pointer_Size               : Pos; -- System.Address'Size
+   Short_Size                 : Pos; -- Standard.Short_Integer'Size
+   Strict_Alignment           : Nat; -- Strict alignment?
+   System_Allocator_Alignment : Nat; -- Alignment for malloc calls
+   Wchar_T_Size               : Pos; -- Interfaces.C.wchar_t'Size
+   Words_BE                   : Nat; -- Words stored big-endian?
+
+   -------------------------------------
+   -- Registered Floating-Point Types --
+   -------------------------------------
+
+   --  This table contains the list of modes supported by the back-end as
+   --  provided by the back end routine enumerate_modes in misc.c. Note that
+   --  we only store floating-point modes (see Register_Float_Type).
+
+   type FPT_Mode_Entry is record
+      NAME      : String_Ptr;     -- Name of mode (no null character at end)
+      DIGS      : Natural;        -- Digits for floating-point type
+      FLOAT_REP : Float_Rep_Kind; -- Float representation
+      SIZE      : Natural;        -- Size in bits
+      ALIGNMENT : Natural;        -- Alignment in bits
+   end record;
+
+   FPT_Mode_Table : array (1 .. 1000) of FPT_Mode_Entry;
+   Num_FPT_Modes  : Natural;
+   --  Table containing the supported modes and number of entries
+
+   -----------------
+   -- Subprograms --
+   -----------------
+
+   procedure Write_Target_Dependent_Values;
+   --  This routine writes the file target.atp in the current directory with
+   --  the values of the global target parameters as listed above, and as set
+   --  by prior calls to Initialize/Read_Target_Dependent_Values. The format
+   --  of the target.atp file is as follows
+   --
+   --    First come the values of the variables defined in this spec:
+   --
+   --      One line per value
+   --
+   --        name  value
+   --
+   --      where name is the name of the parameter, spelled out in full,
+   --      and cased as in the above list, and value is an unsigned decimal
+   --      integer. Two or more blanks separates the name from the value.
+   --
+   --      All the variables must be present, in alphabetical order (i.e. the
+   --      same order as the declarations in this spec).
+   --
+   --   Then there is a blank line to separate the two parts of the file. Then
+   --   come the lines showing the floating-point types to be registered.
+   --
+   --     One line per registered mode
+   --
+   --       name  digs float_rep size alignment
+   --
+   --     where name is the string name of the type (which can have single
+   --     spaces embedded in the name (e.g. long double). The name is followed
+   --     by at least two blanks. The following fields are as described above
+   --     for a Mode_Entry (where float_rep is I/V/A for IEEE-754-Binary,
+   --     Vax_Native, AAMP), fields are separated by at least one blank, and
+   --     a LF character immediately follows the alignment field.
+   --
+   --    It is a fatal error to call this procedure if the target.atp file is
+   --    not found in the current directory.
+
+end Set_Targ;
index 6ade0742d70d637f195a937149a90df4948bb52a..4706701e9b1081357842750aa50cd241b2d566a8 100644 (file)
 --       output. A line containing this escape sequence may not also contain
 --       a ^alpha^beta^ sequence.
 
---       Process @ifset and @ifclear for the target flags (unw, vms);
---       this is because we have menu problems if we let makeinfo handle
---       these ifset/ifclear pairs.
---       Note: @ifset/@ifclear commands for the edition flags (FSFEDITION,
---       PROEDITION, GPLEDITION) are passed through unchanged
-
 with Ada.Command_Line;           use Ada.Command_Line;
 with Ada.Strings;                use Ada.Strings;
 with Ada.Strings.Fixed;          use Ada.Strings.Fixed;