sem_ch13.adb (Visible_Component): New procedure...
authorEd Schonberg <schonberg@adacore.com>
Mon, 20 Jun 2016 12:27:05 +0000 (12:27 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 20 Jun 2016 12:27:05 +0000 (14:27 +0200)
2016-06-20  Ed Schonberg  <schonberg@adacore.com>

* sem_ch13.adb (Visible_Component): New procedure, subsidiary
of Replace_Type_References_ Generic, to determine whether an
identifier in a predicate or invariant expression is a visible
component of the type to which the predicate or invariant
applies. Implements the visibility rule stated in RM 13.1.1
(12/3).

From-SVN: r237599

gcc/ada/ChangeLog
gcc/ada/sem_ch13.adb

index 5f5bd60253f0b9fc9b5815640e3d996378b75252..0f7c8352082ba188fb5c2f6f193b7629deb84ace 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-20  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch13.adb (Visible_Component): New procedure, subsidiary
+       of Replace_Type_References_ Generic, to determine whether an
+       identifier in a predicate or invariant expression is a visible
+       component of the type to which the predicate or invariant
+       applies. Implements the visibility rule stated in RM 13.1.1
+       (12/3).
+
 2016-06-20  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * s-regpat.adb, sem_prag.adb, pprint.adb, sem_ch13.adb: Minor
index 009bf3235f40bee6b33e87a214049379620d23a1..9d2a0bdd25a50a1652d68d6d4ef1b5057c087b73 100644 (file)
@@ -12298,17 +12298,44 @@ package body Sem_Ch13 is
       --  Processes a single node in the traversal procedure below, checking
       --  if node N should be replaced, and if so, doing the replacement.
 
+      function Visible_Component (Comp : Name_Id) return Entity_Id;
+      --  Given an identifier in the expression, check whether there is a
+      --  discriminant or component of the type that is directy visible, and
+      --  rewrite it as the corresponding selected component of the formal of
+      --  the subprogram. The entity is located by a sequential search, which
+      --  seems acceptable given the typical size of component lists and check
+      --  expressions. Possible optimization ???
+
       ----------------------
       -- Replace_Type_Ref --
       ----------------------
 
       function Replace_Type_Ref (N : Node_Id) return Traverse_Result is
-         S : Entity_Id;
-         P : Node_Id;
+         Loc : constant Source_Ptr := Sloc (N);
+         C   : Entity_Id;
+         S   : Entity_Id;
+         P   : Node_Id;
 
-      begin
-         --  Case of identifier
+         procedure Add_Prefix (Ref : Node_Id; Comp : Entity_Id);
+         --  Add the proper prefix to a reference to a component of the
+         --  type when it is not already a selected component.
+
+         ----------------
+         -- Add_Prefix --
+         ----------------
 
+         procedure Add_Prefix (Ref : Node_Id; Comp : Entity_Id) is
+         begin
+            Rewrite (Ref,
+              Make_Selected_Component (Loc,
+                Prefix => New_Occurrence_Of (T, Loc),
+                Selector_Name => New_Occurrence_Of (Comp, Loc)));
+            Replace_Type_Reference (Prefix (Ref));
+         end Add_Prefix;
+
+      --  Start of processing for Replace_Type_Ref
+
+      begin
          if Nkind (N) = N_Identifier then
 
             --  If not the type name, check whether it is a reference to some
@@ -12323,6 +12350,33 @@ package body Sem_Ch13 is
                   Freeze_Before (Freeze_Node (T), Current_Entity (N));
                end if;
 
+               --  The components of the type are directly visible and can
+               --  be referenced without a prefix.
+
+               if Nkind (Parent (N)) = N_Selected_Component then
+                  null;
+
+               --  In expression C (I), C may be a directly visible function
+               --  or a visible component that has an array type. Disambiguate
+               --  by examining the component type.
+
+               elsif Nkind (Parent (N)) = N_Indexed_Component
+                 and then N = Prefix (Parent (N))
+               then
+                  C := Visible_Component (Chars (N));
+
+                  if Present (C) and then Is_Array_Type (Etype (C)) then
+                     Add_Prefix (N, C);
+                  end if;
+
+               else
+                  C := Visible_Component (Chars (N));
+
+                  if Present (C) then
+                     Add_Prefix (N, C);
+                  end if;
+               end if;
+
                return Skip;
 
             --  Otherwise do the replacement and we are done with this node
@@ -12397,6 +12451,32 @@ package body Sem_Ch13 is
          end if;
       end Replace_Type_Ref;
 
+      -----------------------
+      -- Visible_Component --
+      -----------------------
+
+      function Visible_Component (Comp : Name_Id) return Entity_Id is
+         E : Entity_Id;
+      begin
+         if Ekind (T) /= E_Record_Type then
+            return Empty;
+
+         else
+            E := First_Entity (T);
+            while Present (E) loop
+               if Comes_From_Source (E)
+                 and then Chars (E) = Comp
+               then
+                  return E;
+               end if;
+
+               Next_Entity (E);
+            end loop;
+
+            return Empty;
+         end if;
+      end Visible_Component;
+
       procedure Replace_Type_Refs is new Traverse_Proc (Replace_Type_Ref);
 
    begin