* [Ada] Overloaded indexing operations of a derived type
@ 2015-10-26 11:52 Arnaud Charlet
0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2015-10-26 11:52 UTC (permalink / raw)
To: gcc-patches; +Cc: Ed Schonberg
[-- Attachment #1: Type: text/plain, Size: 4528 bytes --]
This patch fixes the handling of overloaded indexing operations that are
inherited by a type derived from one that carries an indexing aspect.
Source:
---
with Ada.Text_Io; use Ada.Text_Io;
with References;
procedure Main is
A : aliased References.Iterated;
begin
A (1) := 42;
Put_Line ("A (1)" & References.Object_T'Image (A (1)));
Put_Line ("A (1, 1)" & References.Object_T'Image (A (1, 1)));
end Main;
---
package body References is
function Find (I : aliased in out Indexed; Key : Index) return Reference_T
is
begin
return (Object => I.Rep (Key)'Access);
end Find;
function Find (I : aliased in out Indexed; Key1, Key2 : Index)
return Reference_T
is
begin
return (Object => I.Rep (Key1)'Access);
end Find;
function Find (I : aliased in out Iterated; C : Cursor) return Reference_T
is
begin
return (Object => I.Rep (C.I)'Access);
end Find;
function Has_Element (Position : Cursor) return Boolean is
begin
return Position.Has_Element;
end Has_Element;
function First (Object : Iterator) return Cursor is
Has_Elements : constant Boolean := Object.First <= Object.Last;
begin
if Has_Elements then
return (Has_Element => True, I => Object.First);
else
return (Has_Element => False);
end if;
end First;
function Next (Object : Iterator; Position : Cursor) return Cursor is
begin
if Position.Has_Element and then Position.I /= Index'Last then
return (Has_Element => True, I => Position.I + 1);
else
return (Has_Element => False);
end if;
end Next;
function Last (Object : Iterator) return Cursor is
Has_Elements : constant Boolean := Object.First <= Object.Last;
begin
if Has_Elements then
return (Has_Element => True, I => Object.Last);
else
return (Has_Element => False);
end if;
end Last;
function Previous (Object : Iterator; Position : Cursor) return Cursor is
begin
if Position.Has_Element and then Position.I /= Index'First then
return (Has_Element => True, I => Position.I - 1);
else
return (Has_Element => False);
end if;
end Previous;
function Iterate (Container : Iterated)
return Iterators.Reversible_Iterator'Class
is
begin
return Iterator'(First => Container.Rep'First, Last => Container.Rep'Last);
end Iterate;
end References;
---
with Ada.Iterator_Interfaces;
package References is
type Object_T is new Integer;
type Reference_T (Object : not null access Object_T) is private
with Implicit_Dereference => Object;
type Index is range 1 .. 2;
type Array_T is array (Index) of aliased Object_T;
type Cursor is private;
type Indexed is tagged
record
Rep : Array_T;
end record
with Variable_Indexing => Find;
function Find (I : aliased in out Indexed; Key : Index) return Reference_T;
function Find (I : aliased in out Indexed; Key1, Key2 : Index)
return Reference_T;
function Has_Element (Position : Cursor) return Boolean;
package Iterators is new Ada.Iterator_Interfaces (Cursor, Has_Element);
type Iterator is new Iterators.Reversible_Iterator with
record
First : Index;
Last : Index;
end record;
function First (Object : Iterator) return Cursor;
function Next (Object : Iterator; Position : Cursor) return Cursor;
function Last (Object : Iterator) return Cursor;
function Previous (Object : Iterator; Position : Cursor) return Cursor;
type Iterated is new Indexed with null record with
Default_Iterator => Iterate,
Iterator_Element => Object_T;
function Find (I : aliased in out Iterated; C : Cursor) return Reference_T;
function Iterate
(Container : Iterated)
return Iterators.Reversible_Iterator'Class;
private
type Reference_T (Object : not null access Object_T) is null record;
type Cursor (Has_Element : Boolean := False) is
record
case Has_Element is
when True =>
I : Index;
when False =>
null;
end case;
end record;
end References;
---
Command:
gnatmake -q main
main
---
Output:
A (1) 42
A (1, 1) 42
Tested on x86_64-pc-linux-gnu, committed on trunk
2015-10-26 Ed Schonberg <schonberg@adacore.com>
* exp_util.ads, exp_util.adb (Find_Primitive_Operations): New
subprogram to retrieve by name the possibly overloaded set of
primitive operations of a type.
* sem_ch4.adb (Try_Container_Indexing): Use
Find_Primitive_Operations to handle overloaded indexing operations
of a derived type.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 3657 bytes --]
Index: exp_util.adb
===================================================================
--- exp_util.adb (revision 229313)
+++ exp_util.adb (working copy)
@@ -2707,6 +2707,50 @@
end if;
end Find_Optional_Prim_Op;
+ -------------------------------
+ -- Find_Primitive_Operations --
+ -------------------------------
+
+ function Find_Primitive_Operations
+ (T : Entity_Id;
+ Name : Name_Id) return Node_Id
+ is
+ Prim_Elmt : Elmt_Id;
+ Prim_Id : Entity_Id;
+ Ref : Node_Id;
+ Typ : Entity_Id := T;
+
+ begin
+ if Is_Class_Wide_Type (Typ) then
+ Typ := Root_Type (Typ);
+ end if;
+
+ Typ := Underlying_Type (Typ);
+
+ Ref := Empty;
+ Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
+ while Present (Prim_Elmt) loop
+ Prim_Id := Node (Prim_Elmt);
+ if Chars (Prim_Id) = Name then
+
+ -- If this is the first primitive operation found,
+ -- create a reference to it.
+
+ if No (Ref) then
+ Ref := New_Occurrence_Of (Prim_Id, Sloc (T));
+
+ -- Otherwise, add interpretation to existing reference
+
+ else
+ Add_One_Interp (Ref, Prim_Id, Etype (Prim_Id));
+ end if;
+ end if;
+ Next_Elmt (Prim_Elmt);
+ end loop;
+
+ return Ref;
+ end Find_Primitive_Operations;
+
------------------
-- Find_Prim_Op --
------------------
Index: exp_util.ads
===================================================================
--- exp_util.ads (revision 229313)
+++ exp_util.ads (working copy)
@@ -467,6 +467,13 @@
-- Ada 2005 (AI-251): Given a type T implementing the interface Iface,
-- return the record component containing the tag of Iface.
+ function Find_Primitive_Operations
+ (T : Entity_Id;
+ Name : Name_Id) return Node_Id;
+ -- Return a reference to a primitive operation with given name. If
+ -- operation is overloaded, the node carries the corresponding set
+ -- of overloaded interpretations.
+
function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id;
-- Find the first primitive operation of a tagged type T with name Name.
-- This function allows the use of a primitive operation which is not
Index: sem_ch4.adb
===================================================================
--- sem_ch4.adb (revision 229331)
+++ sem_ch4.adb (working copy)
@@ -7215,20 +7215,17 @@
-- However, Reference is also a primitive operation of the type, and
-- the inherited operation has a different signature. We retrieve the
- -- right one from the list of primitive operations of the derived type.
+ -- right ones (the function may be overloaded) from the list of
+ -- primitive operations of the derived type.
-- Note that predefined containers are typically all derived from one
-- of the Controlled types. The code below is motivated by containers
-- that are derived from other types with a Reference aspect.
- -- Additional machinery may be needed for types that have several user-
- -- defined Reference operations with different signatures ???
-
elsif Is_Derived_Type (C_Type)
and then Etype (First_Formal (Entity (Func_Name))) /= Etype (Prefix)
then
- Func := Find_Prim_Op (C_Type, Chars (Func_Name));
- Func_Name := New_Occurrence_Of (Func, Loc);
+ Func_Name := Find_Primitive_Operations (C_Type, Chars (Func_Name));
end if;
Assoc := New_List (Relocate_Node (Prefix));
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-10-26 11:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-26 11:52 [Ada] Overloaded indexing operations of a derived type Arnaud Charlet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).