aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2016-06-20 12:27:05 +0000
committerArnaud Charlet <charlet@adacore.com>2016-06-20 12:27:05 +0000
commit1067dc7691d15acfd5e4d8de5c52437d88aac21c (patch)
tree0188bb4ed9f12c4b185d27885c4814bbb1d172e0
parentbed01cb5097df5589cbe1a10320e5dc921428c23 (diff)
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). git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@237599 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog9
-rw-r--r--gcc/ada/sem_ch13.adb88
2 files changed, 93 insertions, 4 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 5f5bd60253f..0f7c8352082 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 009bf3235f4..9d2a0bdd25a 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -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