8.5.4 Subprogram Renaming Declarations
1
A
subprogram_renaming_declaration
can serve as the completion of a
subprogram_declaration;
{renaming-as-body} such
a
renaming_declaration is called a
renaming-as-body.
{renaming-as-declaration}
A
subprogram_renaming_declaration
that is not a completion is called a
renaming-as-declaration[,
and is used to rename a subprogram (possibly an enumeration literal)
or an entry].
1.a
Ramification: A renaming-as-body is a
declaration, as defined in Section 3.
Syntax
2/2
{
AI95-00218-03}
subprogram_renaming_declaration ::=
[overriding_indicator]
subprogram_specification renames callable_entity_name;
Name Resolution Rules
3
{expected profile
(subprogram_renaming_declaration) [partial]} The
expected profile for the
callable_entity_name
is the profile given in the
subprogram_specification.
Legality Rules
4
The profile of a renaming-as-declaration shall be
mode-conformant with that of the renamed callable entity.
{mode
conformance (required)}
4.1/2
{
AI95-00423-01}
For a parameter or result subtype of the subprogram_specification
that has an explicit null_exclusion:
4.2/2
- if the callable_entity_name
denotes a generic formal subprogram of a generic unit G, and the
subprogram_renaming_declaration occurs within
the body of a generic unit G or within the body of a generic unit
declared within the declarative region of the generic unit G,
then the corresponding parameter or result subtype of the formal subprogram
of G shall have a null_exclusion;
4.3/2
- otherwise, the
subtype of the corresponding parameter or result type of the renamed
callable entity shall exclude null. {generic
contract issue [partial]} In addition
to the places where Legality Rules normally apply (see 12.3),
this rule applies also in the private part of an instance of a generic
unit.
4.a/2
Reason:
This rule prevents “lying”. Null must never be
the value of a parameter or result with an explicit null_exclusion.
The first bullet is an assume-the-worst rule which prevents trouble in
generic bodies (including bodies of child units) when the formal subtype
excludes null implicitly.
5/1
{
8652/0027}
{
8652/0028} {
AI95-00135-01}
{
AI95-00145-01}
The profile of a renaming-as-body
shall be subtype-conformant
with that of the renamed callable entity, and shall conform fully
to that of the declaration it completes.
{full
conformance (required)} If the renaming-as-body
completes that declaration before the subprogram it declares is frozen,
the profile shall be mode-conformant {mode
conformance (required)} with that of the
renamed callable entity and the subprogram it declares takes its
convention from the renamed subprogram; otherwise
,
the profile shall be subtype-conformant with that of the renamed callable
entity and the convention of the renamed subprogram shall not
be Intrinsic.
{subtype conformance (required)}
A renaming-as-body is illegal
if the declaration occurs before the subprogram whose declaration it
completes is frozen, and the renaming renames the subprogram itself,
through one or more subprogram renaming declarations, none of whose subprograms
has been frozen.
5.a/1
Reason: The otherwise
part of the second sentence first part of
the first sentence is to allow an implementation of a renaming-as-body
as a single jump instruction to the target subprogram. Among other things,
this prevents a subprogram from being completed with a renaming of an
entry. (In most cases, the target of the jump can be filled in at link
time. In some cases, such as a renaming of a name like "A(I).all",
an indirect jump is needed. Note that the name is evaluated at renaming
time, not at call time.)
5.a.1/1
{
8652/0028}
{
AI95-00145-01}
The first part of the second sentence is intended
to allow renaming-as-body of predefined operators before the subprogram_declaration
is frozen. For some types (such as integer types), the parameter type
for operators is the base type, and it would be very strange for
function Equal (A, B : in T) return
Boolean;
function Equal (A, B : in T) return
Boolean renames "=";
to be illegal. (Note that predefined operators cannot be renamed this
way after the subprogram_declaration is frozen,
as they have convention Intrinsic.)
5.b/1
The second part of the
first sentence is the normal rule for completions of subprogram_declarations.
5.c
Ramification: An entry_declaration,
unlike a subprogram_declaration, cannot be
completed with a renaming_declaration. Nor
can a generic_subprogram_declaration.
5.d
The syntax rules prevent a protected subprogram
declaration from being completed by a renaming. This is fortunate, because
it allows us to avoid worrying about whether the implicit protected object
parameter of a protected operation is involved in the conformance rules.
5.d.1/1
Reason: {
8652/0027}
{
AI95-00135-01}
Circular renames before freezing is illegal, as
the compiler would not be able to determine the convention of the subprogram.
Other circular renames are handled below; see Bounded (Run-Time) Errors.
5.1/2
{
AI95-00228-01}
The callable_entity_name
of a renaming shall not denote a subprogram that requires overriding
(see 3.9.3).
5.d.2/2
Reason: {
AI95-00228-01}
Such a rename cannot be of the inherited subprogram
(which requires overriding because it cannot be called), and thus cannot
squirrel away a subprogram (see below). That would be confusing, so we
make it illegal. The renaming is allowed after the overriding, as then
the name will denote the overriding subprogram,
not the inherited one.
5.2/2
{
AI95-00228-01}
The callable_entity_name
of a renaming-as-body shall not denote an abstract subprogram.
5.d.3/2
Reason: {
AI95-00228-01}
Such a subprogram has no body, so it hardly can
replace one in the program.
6
A name that denotes a
formal parameter of the subprogram_specification
is not allowed within the callable_entity_name.
6.a
Reason: This
is to prevent things like this:
6.b
function F(X : Integer) return Integer renames Table(X).all;
6.c
A similar
rule in
6.1 forbids things like this:
6.d
function F(X : Integer; Y : Integer := X) return Integer;
Static Semantics
7
A renaming-as-declaration declares a new view of
the renamed entity. The profile of this new view takes its subtypes,
parameter modes, and calling convention from the original profile of
the callable entity, while taking the formal parameter names
and default_expressions from the profile given
in the subprogram_renaming_declaration. The
new view is a function or procedure, never an entry.
7.a
To be honest: When renaming an entry
as a procedure, the compile-time rules apply as if the new view is a
procedure, but the run-time semantics of a call are that of an entry
call.
7.b
Ramification: For example, it is illegal
for the entry_call_statement of a timed_entry_call
to call the new view. But what looks like a procedure call will do things
like barrier waiting.
7.b.1/2
{
8652/0105}
{
AI95-00211-01}
{
AI95-00228-01}
All properties of the renamed entity are inherited
by the new view unless otherwise stated by this International Standard.
In particular, if the renamed entity is abstract or requires overriding (see 3.9.3),
the new view also is abstract. or requires overriding. (The renaming will often be illegal in these
cases, as a renaming cannot be overridden.)
Dynamic Semantics
7.1/1
{
8652/0014}
{
AI95-00064-01}
For a call to a subprogram whose body is given
as a renaming-as-body, the execution of the renaming-as-body is equivalent
to the execution of a subprogram_body that
simply calls the renamed subprogram with its formal parameters as the
actual parameters and, if it is a function, returns the value of the
call.
7.b.2/1
Ramification: This
implies that the subprogram completed by the renaming-as-body has its
own elaboration check.
8
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.
8.a
Discussion: Note that whether or not
the renaming is itself primitive has nothing to do with the renamed subprogram.
8.b
Note that the above rule is only for tagged
types.
8.c
Consider the following
example:
8.d
package P is
type T is tagged null record;
function Predefined_Equal(X, Y : T) return Boolean renames "=";
private
function "="(X, Y : T) return Boolean; -- Override predefined "=".
end P;
8.e
with P; use P;
package Q is
function User_Defined_Equal(X, Y : T) return Boolean renames P."=";
end Q;
8.f
A call on Predefined_Equal will execute the
predefined equality operator of T, whereas a call on User_Defined_Equal
will execute the body of the overriding declaration in the private part
of P.
8.g
Thus a renaming allows one to squirrel away
a copy of an inherited or predefined subprogram before later overriding
it.
Bounded (Run-Time) Errors
8.1/1
{
8652/0027}
{
AI95-00135-01}
{Program_Error
(raised by failure of run-time check)} {Storage_Error
(raised by failure of run-time check)} If
a subprogram directly or indirectly renames itself, then it is a bounded
error to call that subprogram. Possible consequences are that Program_Error
or Storage_Error is raised, or that the call results in infinite recursion.
8.g.1/1
Reason: {
8652/0027}
{
AI95-00135-01}
This has to be a bounded error, as it is possible
for a renaming-as-body appearing in a package body to cause this problem.
Thus it is not possible in general to detect this problem at compile
time.
9
12 A procedure can only be renamed as a
procedure. A function whose
defining_designator
is either an
identifier or an
operator_symbol
can be renamed with either an
identifier or
an
operator_symbol; for renaming as an operator,
the subprogram specification given in the
renaming_declaration
is subject to the rules given in
6.6 for operator
declarations. Enumeration literals can be renamed as functions; similarly,
attribute_references that denote functions
(such as references to Succ and Pred) can be renamed as functions. An
entry can only be renamed as a procedure; the new
name
is only allowed to appear in contexts that allow a procedure
name.
An entry of a family can be renamed, but an entry family cannot be renamed
as a whole.
10
13 The operators of the root numeric types
cannot be renamed because the types in the profile are anonymous, so
the corresponding specifications cannot be written; the same holds for
certain attributes, such as Pos.
11
14 Calls with the new name
of a renamed entry are procedure_call_statements
and are not allowed at places where the syntax requires an entry_call_statement
in conditional_ and timed_entry_calls,
nor in an asynchronous_select; similarly,
the Count attribute is not available for the new name.
12
15 The primitiveness of a renaming-as-declaration
is determined by its profile, and by where it occurs, as for any declaration
of (a view of) a subprogram; primitiveness is not determined by the renamed
view. In order to perform a dispatching call, the subprogram name has
to denote a primitive subprogram, not a non-primitive renaming of a primitive
subprogram.
12.a
Reason: A subprogram_renaming_declaration
could more properly be called renaming_as_subprogram_declaration,
since you're renaming something as a subprogram, but you're not necessarily
renaming a subprogram. But that's too much of a mouthful. Or, alternatively,
we could call it a callable_entity_renaming_declaration,
but that's even worse. Not only is it a mouthful, it emphasizes the entity
being renamed, rather than the new view, which we think is a bad idea.
We'll live with the oddity.
Examples
13
Examples of subprogram
renaming declarations:
14
procedure My_Write(C :
in Character)
renames Pool(K).Write; --
see 4.1.3
15
function Real_Plus(Left, Right : Real ) return Real renames "+";
function Int_Plus (Left, Right : Integer) return Integer renames "+";
16
function Rouge
return Color
renames Red; --
see 3.5.1
function Rot
return Color
renames Red;
function Rosso
return Color
renames Rouge;
17
function Next(X : Color)
return Color
renames Color'Succ; --
see 3.5.1
18
Example of a subprogram
renaming declaration with new parameter names:
19
function "*" (X,Y : Vector)
return Real
renames Dot_Product; --
see 6.1
20
Example of a subprogram
renaming declaration with a new default expression:
21
function Minimum(L : Link := Head)
return Cell
renames Min_Cell; --
see 6.1
Extensions to Ada 95
21.a/2
{
8652/0028}
{
AI95-00145-01}
{extensions to Ada 95} Corrigendum:
Allowed a renaming-as-body to be just mode conformant with the specification
if the subprogram is not yet frozen.
21.b/2
{
AI95-00218-03}
Overriding_indicator
(see 8.3.1) is optionally added to subprogram
renamings.
Wording Changes from Ada 95
21.c/2
{
8652/0014}
{
AI95-00064-01}
Corrigendum: Described the semantics of
renaming-as-body, so that the location of elaboration checks is clear.
21.d/2
{
8652/0027}
{
AI95-00135-01}
Corrigendum: Clarified that circular renaming-as-body
is illegal (if it can be detected in time) or a bounded error.
21.e/2
{
AI95-00228-01}
Clarified that renaming a shall-be-overridden subprogram
is illegal, as well as renaming-as-body an abstract subprogram.
21.f/2