]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Thu, 12 Jul 2012 10:19:13 +0000 (12:19 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Thu, 12 Jul 2012 10:19:13 +0000 (12:19 +0200)
2012-07-12  Robert Dewar  <dewar@adacore.com>

* make.adb, sem_ch9.adb, prj.adb, s-rident.ads, snames.ads-tmpl: Minor
reformatting.

2012-07-12  Javier Miranda  <miranda@adacore.com>

* exp_ch3.adb (Is_User_Defined_Equality): New subprogram.
(Make_Neq_Body): New subprogram.
(Make_Predefined_Primitive_Specs): Adding local variable
Has_Predef_Eq_ Renaming to ensure that we enable the machinery
which handles renamings of predefined primitive operators.

From-SVN: r189432

gcc/ada/ChangeLog
gcc/ada/exp_ch3.adb
gcc/ada/make.adb
gcc/ada/prj.adb
gcc/ada/s-rident.ads
gcc/ada/sem_ch9.adb
gcc/ada/snames.ads-tmpl

index 38b62351cf36304a0e150daa442046dba7b9cf1e..0e30e766c269727522645856a32d2f7e406cf805 100644 (file)
@@ -1,3 +1,16 @@
+2012-07-12  Robert Dewar  <dewar@adacore.com>
+
+       * make.adb, sem_ch9.adb, prj.adb, s-rident.ads, snames.ads-tmpl: Minor
+       reformatting.
+
+2012-07-12  Javier Miranda  <miranda@adacore.com>
+
+       * exp_ch3.adb (Is_User_Defined_Equality): New subprogram.
+       (Make_Neq_Body): New subprogram.
+       (Make_Predefined_Primitive_Specs): Adding local variable
+       Has_Predef_Eq_ Renaming to ensure that we enable the machinery
+       which handles renamings of predefined primitive operators.
+
 2012-07-09  Pascal Obry  <obry@adacore.com>
 
        * prj.adb (For_Every_Project_Imported_Context): Make sure we
index 7f7aa6f6bb798e0aca4887f77a73c032c120e0cb..369d895906ba7b70dbc7069fd0b6db8996c82531 100644 (file)
@@ -202,6 +202,9 @@ package body Exp_Ch3 is
    --  Check if E is defined in the RTL (in a child of Ada or System). Used
    --  to avoid to bring in the overhead of _Input, _Output for tagged types.
 
+   function Is_User_Defined_Equality (Prim : Node_Id) return Boolean;
+   --  Returns true if Prim is a user defined equality function
+
    function Is_Variable_Size_Array (E : Entity_Id) return Boolean;
    --  Returns true if E has variable size components
 
@@ -237,6 +240,11 @@ package body Exp_Ch3 is
    --  formals at some upper level). E provides the Sloc to be used for the
    --  generated code.
 
+   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id;
+   --  Search for a renaming of the inequality dispatching primitive of
+   --  this tagged type. If found then build and return the corresponding
+   --  rename-as-body inequality subprogram; otherwise return Empty.
+
    procedure Make_Predefined_Primitive_Specs
      (Tag_Typ     : Entity_Id;
       Predef_List : out List_Id;
@@ -7677,6 +7685,18 @@ package body Exp_Ch3 is
       end loop;
    end Init_Secondary_Tags;
 
+   ------------------------
+   -- Is_User_Defined_Eq --
+   ------------------------
+
+   function Is_User_Defined_Equality (Prim : Node_Id) return Boolean is
+   begin
+      return Chars (Prim) = Name_Op_Eq
+        and then Etype (First_Formal (Prim)) =
+                 Etype (Next_Formal (First_Formal (Prim)))
+        and then Base_Type (Etype (Prim)) = Standard_Boolean;
+   end Is_User_Defined_Equality;
+
    ----------------------------
    -- Is_Variable_Size_Array --
    ----------------------------
@@ -8140,6 +8160,175 @@ package body Exp_Ch3 is
       end if;
    end Make_Eq_If;
 
+   --------------------
+   --  Make_Neq_Body --
+   --------------------
+
+   function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id is
+
+      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean;
+      --  Returns true if Prim is a renaming of an unresolved predefined
+      --  inequality operation.
+
+      --------------------------------
+      -- Is_Predefined_Neq_Renaming --
+      --------------------------------
+
+      function Is_Predefined_Neq_Renaming (Prim : Node_Id) return Boolean is
+      begin
+         return Chars (Prim) /= Name_Op_Ne
+           and then Present (Alias (Prim))
+           and then Comes_From_Source (Prim)
+           and then Is_Intrinsic_Subprogram (Alias (Prim))
+           and then Chars (Alias (Prim)) = Name_Op_Ne;
+      end Is_Predefined_Neq_Renaming;
+
+      --  Local variables
+
+      Loc           : constant Source_Ptr := Sloc (Parent (Tag_Typ));
+      Stmts         : constant List_Id    := New_List;
+      Decl          : Node_Id;
+      Eq_Prim       : Entity_Id;
+      Left_Op       : Entity_Id;
+      Renaming_Prim : Entity_Id;
+      Right_Op      : Entity_Id;
+      Target        : Entity_Id;
+
+   --  Start of processing for Make_Neq_Body
+
+   begin
+      --  For a call on a renaming of a dispatching subprogram that is
+      --  overridden, if the overriding occurred before the renaming, then
+      --  the body executed is that of the overriding declaration, even if the
+      --  overriding declaration is not visible at the place of the renaming;
+      --  otherwise, the inherited or predefined subprogram is called, see
+      --  (RM 8.5.4(8))
+
+      --  Stage 1: Search for a renaming of the unequality primitive and also
+      --  search for an overriding of the equality primitive located before the
+      --  renaming declaration.
+
+      declare
+         Elmt : Elmt_Id;
+         Prim : Node_Id;
+
+      begin
+         Eq_Prim       := Empty;
+         Renaming_Prim := Empty;
+
+         Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
+         while Present (Elmt) loop
+            Prim := Node (Elmt);
+
+            if Is_User_Defined_Equality (Prim)
+              and then No (Alias (Prim))
+            then
+               if No (Renaming_Prim) then
+                  pragma Assert (No (Eq_Prim));
+                  Eq_Prim := Prim;
+               end if;
+
+            elsif Is_Predefined_Neq_Renaming (Prim) then
+               Renaming_Prim := Prim;
+            end if;
+
+            Next_Elmt (Elmt);
+         end loop;
+      end;
+
+      --  No further action needed if no renaming was found
+
+      if No (Renaming_Prim) then
+         return Empty;
+      end if;
+
+      --  Stage 2: Replace the renaming declaration by a subprogram declaration
+      --  (required to add its body)
+
+      Decl := Parent (Parent (Renaming_Prim));
+      Rewrite (Decl,
+        Make_Subprogram_Declaration (Loc,
+          Specification => Specification (Decl)));
+      Set_Analyzed (Decl);
+
+      --  Remove the decoration of intrinsic renaming subprogram
+
+      Set_Is_Intrinsic_Subprogram (Renaming_Prim, False);
+      Set_Convention (Renaming_Prim, Convention_Ada);
+      Set_Alias (Renaming_Prim, Empty);
+      Set_Has_Completion (Renaming_Prim, False);
+
+      --  Stage 3: Build the corresponding body
+
+      Left_Op  := First_Formal (Renaming_Prim);
+      Right_Op := Next_Formal (Left_Op);
+
+      Decl :=
+        Predef_Spec_Or_Body (Loc,
+          Tag_Typ => Tag_Typ,
+          Name    => Chars (Renaming_Prim),
+          Profile => New_List (
+            Make_Parameter_Specification (Loc,
+              Defining_Identifier =>
+                Make_Defining_Identifier (Loc, Chars (Left_Op)),
+              Parameter_Type      => New_Reference_To (Tag_Typ, Loc)),
+
+            Make_Parameter_Specification (Loc,
+              Defining_Identifier =>
+                Make_Defining_Identifier (Loc, Chars (Right_Op)),
+              Parameter_Type      => New_Reference_To (Tag_Typ, Loc))),
+
+          Ret_Type => Standard_Boolean,
+          For_Body => True);
+
+      --  If the overriding of the equality primitive occurred before the
+      --  renaming, then generate:
+
+      --    function <Neq_Name> (X : Y : Typ) return Boolean is
+      --    begin
+      --       return not Oeq (X, Y);
+      --    end;
+
+      if Present (Eq_Prim) then
+         Target := Eq_Prim;
+
+      --  Otherwise build a nested subprogram which performs the predefined
+      --  evaluation of the equality operator. That is, generate:
+
+      --    function <Neq_Name> (X : Y : Typ) return Boolean is
+      --       function Oeq (X : Y) return Boolean is
+      --       begin
+      --          <<body of default implementation>>
+      --       end;
+      --    begin
+      --       return not Oeq (X, Y);
+      --    end;
+
+      else
+         declare
+            Local_Subp : Node_Id;
+         begin
+            Local_Subp := Make_Eq_Body (Tag_Typ, Name_Op_Eq);
+            Set_Declarations (Decl, New_List (Local_Subp));
+            Target := Defining_Entity (Local_Subp);
+         end;
+      end if;
+
+      Append_To (Stmts,
+        Make_Simple_Return_Statement (Loc,
+          Expression =>
+            Make_Op_Not (Loc,
+              Make_Function_Call (Loc,
+                Name => New_Reference_To (Target, Loc),
+                Parameter_Associations => New_List (
+                  Make_Identifier (Loc, Chars (Left_Op)),
+                  Make_Identifier (Loc, Chars (Right_Op)))))));
+
+      Set_Handled_Statement_Sequence
+        (Decl, Make_Handled_Sequence_Of_Statements (Loc, Stmts));
+      return Decl;
+   end Make_Neq_Body;
+
    -------------------------------
    -- Make_Null_Procedure_Specs --
    -------------------------------
@@ -8238,13 +8427,6 @@ package body Exp_Ch3 is
       Predef_List : out List_Id;
       Renamed_Eq  : out Entity_Id)
    is
-      Loc       : constant Source_Ptr := Sloc (Tag_Typ);
-      Res       : constant List_Id    := New_List;
-      Eq_Name   : Name_Id := Name_Op_Eq;
-      Eq_Needed : Boolean;
-      Eq_Spec   : Node_Id;
-      Prim      : Elmt_Id;
-
       function Is_Predefined_Eq_Renaming (Prim : Node_Id) return Boolean;
       --  Returns true if Prim is a renaming of an unresolved predefined
       --  equality operation.
@@ -8262,6 +8444,19 @@ package body Exp_Ch3 is
            and then Chars (Alias (Prim)) = Name_Op_Eq;
       end Is_Predefined_Eq_Renaming;
 
+      --  Local variables
+
+      Loc       : constant Source_Ptr := Sloc (Tag_Typ);
+      Res       : constant List_Id    := New_List;
+      Eq_Name   : Name_Id := Name_Op_Eq;
+      Eq_Needed : Boolean;
+      Eq_Spec   : Node_Id;
+      Prim      : Elmt_Id;
+
+      Has_Predef_Eq_Renaming : Boolean := False;
+      --  Set to True if Tag_Typ has a primitive that renames the predefined
+      --  equality operator. Used to implement (RM 8-5-4(8)).
+
    --  Start of processing for Make_Predefined_Primitive_Specs
 
    begin
@@ -8299,9 +8494,9 @@ package body Exp_Ch3 is
          end loop;
       end;
 
-      --  Spec of "=" is expanded if the type is not limited and if a
-      --  user defined "=" was not already declared for the non-full
-      --  view of a private extension
+      --  Spec of "=" is expanded if the type is not limited and if a user
+      --  defined "=" was not already declared for the non-full view of a
+      --  private extension
 
       if not Is_Limited_Type (Tag_Typ) then
          Eq_Needed := True;
@@ -8311,21 +8506,18 @@ package body Exp_Ch3 is
             --  If a primitive is encountered that renames the predefined
             --  equality operator before reaching any explicit equality
             --  primitive, then we still need to create a predefined equality
-            --  function, because calls to it can occur via the renaming. A new
-            --  name is created for the equality to avoid conflicting with any
-            --  user-defined equality. (Note that this doesn't account for
+            --  function, because calls to it can occur via the renaming. A
+            --  new name is created for the equality to avoid conflicting with
+            --  any user-defined equality. (Note that this doesn't account for
             --  renamings of equality nested within subpackages???)
 
             if Is_Predefined_Eq_Renaming (Node (Prim)) then
+               Has_Predef_Eq_Renaming := True;
                Eq_Name := New_External_Name (Chars (Node (Prim)), 'E');
 
             --  User-defined equality
 
-            elsif Chars (Node (Prim)) = Name_Op_Eq
-              and then Etype (First_Formal (Node (Prim))) =
-                         Etype (Next_Formal (First_Formal (Node (Prim))))
-              and then Base_Type (Etype (Node (Prim))) = Standard_Boolean
-            then
+            elsif Is_User_Defined_Equality (Node (Prim)) then
                if No (Alias (Node (Prim)))
                  or else Nkind (Unit_Declaration_Node (Node (Prim))) =
                            N_Subprogram_Renaming_Declaration
@@ -8394,7 +8586,7 @@ package body Exp_Ch3 is
                 Ret_Type => Standard_Boolean);
             Append_To (Res, Eq_Spec);
 
-            if Eq_Name /= Name_Op_Eq then
+            if Has_Predef_Eq_Renaming then
                Renamed_Eq := Defining_Unit_Name (Specification (Eq_Spec));
 
                Prim := First_Elmt (Primitive_Operations (Tag_Typ));
@@ -8966,6 +9158,14 @@ package body Exp_Ch3 is
             Append_To (Res, Decl);
          end if;
 
+         --  Body for inequality (if required!)
+
+         Decl := Make_Neq_Body (Tag_Typ);
+
+         if Present (Decl) then
+            Append_To (Res, Decl);
+         end if;
+
          --  Body for dispatching assignment
 
          Decl :=
index 91d64b514372d88c5a445d67ac677a75fefd9a4c..dca504d7919644a14e8f671009145f881136904c 100644 (file)
@@ -4807,8 +4807,10 @@ package body Make is
          return;
       end if;
 
-      --  Regenerate libraries, if there are any and if object files
-      --  have been regenerated.
+      --  Regenerate libraries, if there are any and if object files have been
+      --  regenerated. Note that we skip this in CodePeer mode because we don't
+      --  need libraries in this case, and more importantly, the object files
+      --  may not be present.
 
       if Main_Project /= No_Project
         and then not CodePeer_Mode
index d70315bbbbc684ca73b720061540b2e4d5e2cb6c..150d524d30f3a40231c0df4f589794ea1a902879 100644 (file)
@@ -599,12 +599,14 @@ package body Prj is
 
             function Has_Sources (P : Project_Id) return Boolean is
                Lang : Language_Ptr;
+
             begin
                Lang := P.Languages;
                while Lang /= No_Language_Index loop
                   if Lang.First_Source /= No_Source then
                      return True;
                   end if;
+
                   Lang := Lang.Next;
                end loop;
 
@@ -617,6 +619,7 @@ package body Prj is
 
             function Get_From_Tree (P : Project_Id) return Project_Id is
                List : Project_List := Tree.Projects;
+
             begin
                if not Has_Sources (P) then
                   while List /= null loop
@@ -625,6 +628,7 @@ package body Prj is
                      then
                         return List.Project;
                      end if;
+
                      List := List.Next;
                   end loop;
                end if;
@@ -632,8 +636,12 @@ package body Prj is
                return P;
             end Get_From_Tree;
 
+            --  Local variables
+
             List : Project_List;
 
+         --  Start of processing for Recursive_Check
+
          begin
             if not Seen_Name.Contains (Project.Name) then
 
index d067f3d7f4feebe661195abec7806f180524d015..11943f074c3b8f564d84534e21d8eb5f004c304e 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, 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- --
 ------------------------------------------------------------------------------
 
 --  This package defines the set of restriction identifiers. It is a generic
---  package that is instantiated by the compiler/binder in package Rident, and
---  is instantiated in package System.Restrictions for use at run-time.
+--  package that is instantiated by the binder for output of the restrictions
+--  structure, and is instantiated in package System.Restrictions for use at
+--  run-time.
 
 --  The reason that we make this a generic package is so that in the case of
---  the instantiation in Rident for use at compile time and bind time, we can
---  generate normal image tables for the enumeration types, which are needed
---  for diagnostic and informational messages. At run-time we really do not
---  want to waste the space for these image tables, and they are not needed,
---  so we can do the instantiation under control of Discard_Names to remove
---  the tables.
+--  the instantiation in the binder, we can generate normal image tables for
+--  the enumeration types, which are needed for diagnostic and informational
+--  messages as well as for identification of restrictions. At run-time we
+--  really do not want to waste the space for these image tables, and they are
+--  not needed, so we can do the instantiation under control of Discard_Names
+--  to remove the tables.
 
 pragma Compiler_Unit;
 
index 6a9fedf253af2179cf4da8815a2793620a9d238e..d6141bc1e05c37638c45ae68e88342a19849614e 100644 (file)
@@ -244,6 +244,9 @@ package body Sem_Ch9 is
                ----------------
 
                function Check_Node (N : Node_Id) return Traverse_Result is
+
+                  --  The following function belongs in sem_eval ???
+
                   function Is_Static_Function (Attr : Node_Id) return Boolean;
                   --  Given an attribute reference node Attr, return True if
                   --  Attr denotes a static function according to the rules in
index f4facab956bd64fb1f69840d5a6cdb2a60106911..27ee72e2c89017db9e961e90310ffa4af9d7d713 100644 (file)
@@ -953,18 +953,24 @@ package Snames is
    Last_Attribute_Name                 : constant Name_Id := N + $;
 
    --  Names of internal attributes. They are not real attributes but special
-   --  names used internally by GNAT in order to deal with certain delayed
-   --  aspects (Aspect_CPU, Aspect_Dispatching_Domain,
-   --  Aspect_Interrupt_Priority) that don't have corresponding pragmas or
-   --  user-referencable attributes. It is convenient to have these internal
-   --  attributes available in processing the aspects, since the normal
-   --  approach is to convert an aspect into its corresponding pragma or
-   --  attribute specification.
+   --  names used internally by GNAT in order to deal with delayed aspects
+   --  (Aspect_CPU, Aspect_Dispatching_Domain, Aspect_Interrupt_Priority) that
+   --  don't have corresponding pragmas or user-referencable attributes.
+
+   --  It is convenient to have these internal attributes available for
+   --  processing the aspects, since the normal approach is to convert an
+   --  aspect into its corresponding pragma or attribute specification.
+
+   --  These attributes do have Attribute_Id values so that case statements
+   --  on Attribute_Id include these cases, but they are NOT included in the
+   --  Attribute_Name subtype defined above, which is typically used in the
+   --  front end for checking syntax of submitted programs (where the use of
+   --  internal attributes is not permitted).
 
    First_Internal_Attribute_Name       : constant Name_Id := N + $;
-   Name_CPU                            : constant Name_Id := N + $; -- INT
-   Name_Dispatching_Domain             : constant Name_Id := N + $; -- INT
-   Name_Interrupt_Priority             : constant Name_Id := N + $; -- INT
+   Name_CPU                            : constant Name_Id := N + $;
+   Name_Dispatching_Domain             : constant Name_Id := N + $;
+   Name_Interrupt_Priority             : constant Name_Id := N + $;
    Last_Internal_Attribute_Name        : constant Name_Id := N + $;
 
    --  Names of recognized locking policy identifiers