[Ada] Parameterless calls to protected operations on selected components.
Arnaud Charlet
charlet@adacore.com
Fri Aug 1 13:31:00 GMT 2014
A multi-level selected component can designate a call to a parameterless
protected operation whose target object is itself given by a selected component.
When the node is rewritten as a function call, it is necessary to preserve the
tree structure of the name, so that overload information and subsequent action
insertions work properly.
THe following must compile quietly:
gcc -c ia-ib-ic-d.adb
---
WITH Ada.Unchecked_Deallocation;
PACKAGE BODY ia.ib.ic.d IS
-- ------------------------------------------------------------------------
-- Protected declaration
-- ------------------------------------------------------------------------
PROTECTED TYPE network_state_controller IS
PROCEDURE set_send_success (success : IN Boolean);
PROCEDURE set_receive_success (success : IN Boolean);
PROCEDURE set_connected;
PROCEDURE set_disconnected;
PROCEDURE set_open_connection;
PROCEDURE set_close_connection;
FUNCTION is_connected RETURN Boolean;
FUNCTION is_opened RETURN Boolean;
ENTRY wait_disconnected;
ENTRY wait_connected;
PRIVATE
connected : Boolean := False;
open_connection : Boolean := False;
send_success : Boolean := True;
receive_success : Boolean := True;
END network_state_controller;
TYPE internals IS RECORD
-- object management
-- -----------------
is_initialized : Boolean := False;
-- Network
-- -------
network_state : network_state_controller;
-- values that may be sent to the gun
-- ----------------------------------
-- values reported back by the gun
-- -------------------------------
-- raw telegram buffers
-- --------------------
-- comms house keeping and control
-- -------------------------------
-- fire zone comms
-- ---------------
fire_zone_request_timeout : Natural := 0; -- 10 ms cycle count
fire_zone_request_started_at : Natural := 0;-- 10 ms cycle count
-- Trace
-- -----
use_tracer_position_entry : Boolean := False;
tracer_dusc : Boolean := False;
tracer_dusc_overwrite : Boolean := False;
tracer_zoom_overwrite : Boolean := False;
print_counter : Positive := 1; -- for debugging information
call_counter : Natural := 0;
tick_cycle : Natural := 0;
proceed_counter : Natural := 0; -- for test purpose
self : reference := NULL;
trace_alarm : Boolean := False;
trace_fire : Boolean := False;
END RECORD;
FUNCTION create RETURN reference IS
ref : reference := NEW object;
BEGIN
ref.hidden := NEW internals;
ref.hidden.self := ref;
RETURN ref;
EXCEPTION
WHEN error : OTHERS =>
RETURN NULL;
END create;
PROCEDURE initialize (obj : IN OUT object; success : OUT Boolean) IS
BEGIN
IF NOT obj.hidden.is_initialized THEN
obj.hidden.is_initialized := True;
success := True;
END IF;
EXCEPTION
WHEN error : OTHERS =>
success := False;
END initialize;
-- ------------------------------------------------------------------------
PROCEDURE free IS NEW Ada.Unchecked_Deallocation (object'class, reference);
PROCEDURE free IS NEW Ada.Unchecked_Deallocation
(internals,
access_internals);
-- ------------------------------------------------------------------------
PROCEDURE finalize (obj : IN OUT reference) IS
BEGIN
IF obj /= NULL THEN
IF obj.hidden /= NULL THEN
free (obj.hidden);
END IF;
free (obj);
END IF;
EXCEPTION
WHEN error : OTHERS =>
NULL;
END finalize;
FUNCTION is_connected (obj : IN object) RETURN Boolean IS
BEGIN
IF obj.hidden.network_state.is_opened
AND THEN obj.hidden.network_state.is_connected THEN
RETURN True;
ELSE
RETURN False;
END IF;
EXCEPTION
WHEN error : OTHERS =>
RETURN False;
END is_connected;
max_before_reconnect : CONSTANT Positive := 100;
PROTECTED BODY network_state_controller IS
PROCEDURE set_send_success (success : IN Boolean) IS
BEGIN
send_success := success;
END set_send_success;
PROCEDURE set_receive_success (success : IN Boolean) IS
BEGIN
receive_success := success;
END set_receive_success;
PROCEDURE set_connected IS
BEGIN
connected := True;
END set_connected;
PROCEDURE set_disconnected IS
BEGIN
connected := False;
END set_disconnected;
FUNCTION is_connected RETURN Boolean IS
BEGIN
RETURN open_connection AND THEN connected;
END is_connected;
FUNCTION is_opened RETURN Boolean IS
BEGIN
RETURN open_connection;
END is_opened;
PROCEDURE set_close_connection IS
BEGIN
connected := False;
open_connection := False;
END set_close_connection;
PROCEDURE set_open_connection IS
BEGIN
connected := False;
open_connection := True;
END set_open_connection;
ENTRY wait_disconnected WHEN NOT connected IS
BEGIN
NULL;
END wait_disconnected;
ENTRY wait_connected WHEN open_connection AND THEN connected IS
BEGIN
NULL;
END wait_connected;
END network_state_controller;
END ia.ib.ic.d;
---
PACKAGE ia.ib.ic.d IS
TYPE object IS NEW ia.ib.ic.object WITH PRIVATE;
TYPE reference IS ACCESS ALL object'class;
FUNCTION create RETURN reference;
PROCEDURE initialize (obj : IN OUT object; success : OUT Boolean);
PROCEDURE finalize (obj : IN OUT reference);
FUNCTION is_connected (obj : IN object) RETURN Boolean;
PRIVATE
TYPE internals;
TYPE access_internals IS ACCESS ALL internals;
TYPE object IS NEW ia.ib.ic.object WITH RECORD
hidden : access_internals := NULL;
END RECORD;
END ia.ib.ic.d;
---
PACKAGE ia.ib.ic IS
TYPE object IS NEW ia.ib.object WITH PRIVATE;
TYPE reference IS ACCESS ALL object'class;
PRIVATE
TYPE object IS NEW ia.ib.object WITH NULL RECORD;
END ia.ib.ic;
---
PACKAGE ia.ib IS
TYPE object IS NEW ia.object WITH PRIVATE;
TYPE reference IS ACCESS ALL object'class;
PRIVATE
TYPE object IS NEW ia.object WITH NULL RECORD;
END ia.ib;
---
PACKAGE ia IS
TYPE object IS ABSTRACT TAGGED PRIVATE;
TYPE reference IS ACCESS ALL ia.object'class;
TYPE view IS ACCESS CONSTANT ia.object'class;
nil : CONSTANT view := NULL;
PROCEDURE finalize (obj : ACCESS object'class) IS ABSTRACT;
PRIVATE
TYPE object IS ABSTRACT TAGGED NULL RECORD;
END ia;
Tested on x86_64-pc-linux-gnu, committed on trunk
2014-08-01 Ed Schonberg <schonberg@adacore.com>
* sem_res.adb (Check_Parameterless_Call): Use Relocate_Node
to create the name of the parameterless call, rather than
New_Copy, to preserve the tree structure when the name is a
complex expression, e.g. a selected component that denotes a
protected operation, whose prefix is itself a selected component.
-------------- next part --------------
Index: sem_res.adb
===================================================================
--- sem_res.adb (revision 213451)
+++ sem_res.adb (working copy)
@@ -1102,8 +1102,11 @@
end if;
end if;
- Nam := New_Copy (N);
+ -- The node is the name of the parameterless call. Preserve its
+ -- descendants, which may be complex expressions.
+ Nam := Relocate_Node (N);
+
-- If overloaded, overload set belongs to new copy
Save_Interps (N, Nam);
More information about the Gcc-patches
mailing list