Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

4.1.3 Selected Components

[Selected_components are used to denote components (including discriminants), entries, entry families, and protected subprograms; they are also used as expanded names as described below. ]


selected_component ::= prefix . selector_name
selector_name ::= identifier | character_literal | operator_symbol

Name Resolution Rules

A selected_component is called an expanded name if, according to the visibility rules, at least one possible interpretation of its prefix denotes a package or an enclosing named construct (directly, not through a subprogram_renaming_declaration or generic_renaming_declaration).
Discussion: See AI83-00187. 
A selected_component that is not an expanded name shall resolve to denote one of the following:
Ramification: If the prefix of a selected_component denotes an enclosing named construct, then the selected_component is interpreted only as an expanded name, even if the named construct is a function that could be called without parameters. 
A component [(including a discriminant)]:
The prefix shall resolve to denote an object or value of some non-array composite type (after any implicit dereference). The selector_name shall resolve to denote a discriminant_specification of the type, or, unless the type is a protected type, a component_declaration of the type. The selected_component denotes the corresponding component of the object or value. 
Reason: {AI05-0005-1} The components of a protected object cannot be named except by an expanded name, even from within the corresponding protected body. The protected body cannot reference the private components of some arbitrary object of the protected type; the protected body may reference components of the current instance only (by an expanded name or a direct_name).
Ramification: Only the discriminants and components visible at the place of the selected_component can be selected, since a selector_name can only denote declarations that are visible (see 8.3).
A single entry, an entry family, or a protected subprogram:
The prefix shall resolve to denote an object or value of some task or protected type (after any implicit dereference). The selector_name shall resolve to denote an entry_declaration or subprogram_declaration occurring (implicitly or explicitly) within the visible part of that type. The selected_component denotes the corresponding entry, entry family, or protected subprogram.
Reason: This explicitly says “visible part” because even though the body has visibility on the private part, it cannot call the private operations of some arbitrary object of the task or protected type, only those of the current instance (and expanded name notation has to be used for that). 
{AI95-00252-01} {AI95-00407-01} A view of a subprogram whose first formal parameter is of a tagged type or is an access parameter whose designated type is tagged:
{AI95-00252-01} {AI95-00407-01} {AI05-0090-1} The prefix (after any implicit dereference) shall resolve to denote an object or value of a specific tagged type T or class-wide type T'Class. The selector_name shall resolve to denote a view of a subprogram declared immediately within the declarative region in which an ancestor of the type T is declared. The first formal parameter of the subprogram shall be of type T, or a class-wide type that covers T, or an access parameter designating one of these types. The designator of the subprogram shall not be the same as that of a component of the tagged type visible at the point of the selected_component. The subprogram shall not be an implicitly declared primitive operation of type T that overrides an inherited subprogram implemented by an entry or protected subprogram visible at the point of the selected_component. The selected_component denotes a view of this subprogram that omits the first formal parameter. This view is called a prefixed view of the subprogram, and the prefix of the selected_component (after any implicit dereference) is called the prefix of the prefixed view.
Discussion: {AI05-0090-1} The part of the rule that excludes a primitive overriding subprogram as a selector applies only to the wrapper subprogram that is implicitly declared to override a subprogram inherited from a synchronized interface that is implemented by an operation of a task or protected type (see 9.1 and 9.4). We don't want calls that use a prefixed view to be ambiguous between the wrapper subprogram and the implementing entry or protected operation. Note that it is illegal to declare an explicit primitive that has a prefixed view that is homographic with one of the type's operations, so in normal cases it isn't possible to have an ambiguity in a prefix call. However, a class-wide operation of an ancestor type that is declared in the same declaration list with the ancestor type is also considered, and that can still make a call ambiguous. 
An expanded name shall resolve to denote a declaration that occurs immediately within a named declarative region, as follows: 
The prefix shall resolve to denote either a package [(including the current instance of a generic package, or a rename of a package)], or an enclosing named construct.
The selector_name shall resolve to denote a declaration that occurs immediately within the declarative region of the package or enclosing construct [(the declaration shall be visible at the place of the expanded name — see 8.3)]. The expanded name denotes that declaration. 
Ramification: Hence, a library unit or subunit can use an expanded name to refer to the declarations within the private part of its parent unit, as well as to other children that have been mentioned in with_clauses.
If the prefix does not denote a package, then it shall be a direct_name or an expanded name, and it shall resolve to denote a program unit (other than a package), the current instance of a type, a block_statement, a loop_statement, or an accept_statement (in the case of an accept_statement or entry_body, no family index is allowed); the expanded name shall occur within the declarative region of this construct. Further, if this construct is a callable construct and the prefix denotes more than one such enclosing callable construct, then the expanded name is ambiguous, independently of the selector_name.

Legality Rules

   {AI95-00252-01} {AI95-00407-01} For a subprogram whose first parameter is an access parameter, the prefix of any prefixed view shall denote an aliased view of an object.
   {AI95-00407-01} For a subprogram whose first parameter is of mode in out or out, or of an anonymous access-to-variable type, the prefix of any prefixed view shall denote a variable.
Reason: We want calls through a prefixed view and through a normal view to have the same legality. Thus, the implicit 'Access in this new notation needs the same legality check that an explicit 'Access would have. Similarly, we need to prohibit the object from being constant if the first parameter of the subprogram is in out, because that is (obviously) prohibited for passing a normal parameter. 

Dynamic Semantics

The evaluation of a selected_component includes the evaluation of the prefix.
For a selected_component that denotes a component of a variant, a check is made that the values of the discriminants are such that the value or object denoted by the prefix has this component. The exception Constraint_Error is raised if this check fails.


Examples of selected components: 
{AI95-00252-01} {AI95-00407-01}   Tomorrow.Month     --  a record component  (see 3.8)
  Next_Car.Owner     --  a record component                      (see 3.10.1)
  Next_Car.Owner.Age --  a record component                      (see 3.10.1)
                     --  the previous two lines involve implicit dereferences
  Writer.Unit        --  a record component (a discriminant)     (see 3.8.1)
  Min_Cell(H).Value  --  a record component of the result        (see 6.1)
                     --  of the function call Min_Cell(H)
  Cashier.Append     --  a prefixed view of a procedure          (see 3.9.4)
  Control.Seize      --  an entry of a protected object          (see 9.4)
  Pool(K).Write      --  an entry of the task Pool(K)            (see 9.4)
Examples of expanded names: 
  Key_Manager."<"      --  an operator of the visible part of a package  (see 7.3.1)
  Dot_Product.Sum      --  a variable declared in a function body       (see 6.1)
  Buffer.Pool          --  a variable declared in a protected unit      (see 9.11)
  Buffer.Read          --  an entry of a protected unit                 (see 9.11)
  Swap.Temp            --  a variable declared in a block statement     (see 5.6)
  Standard.Boolean     --  the name of a predefined type                (see A.1)

Extensions to Ada 83

We now allow an expanded name to use a prefix that denotes a rename of a package, even if the selector is for an entity local to the body or private part of the package, so long as the entity is visible at the place of the reference. This eliminates a preexisting anomaly where references in a package body may refer to declarations of its visible part but not those of its private part or body when the prefix is a rename of the package. 

Wording Changes from Ada 83

The syntax rule for selector_name is new. It is used in places where visibility, but not necessarily direct visibility, is required. See 4.1, “Names” for more information.
The description of dereferencing an access type has been moved to 4.1, “Names”; name.all is no longer considered a selected_component.
The rules have been restated to be consistent with our new terminology, to accommodate class-wide types, etc. 

Extensions to Ada 95

{AI95-00252-01} The prefixed view notation for tagged objects is new. This provides a similar notation to that used in other popular languages, and also reduces the need for use_clauses. This is sometimes known as “distinguished receiver notation”.
Given the following definitions for a tagged type T: 
procedure Do_Something (Obj : in out T; Count : in Natural);
procedure Do_Something_Else (Obj : access T; Flag : in Boolean);
My_Object : aliased T;
the following calls are equivalent: 
Do_Something (My_Object, Count => 10);
My_Object.Do_Something (Count => 10);
as are the following calls: 
Do_Something_Else (My_Object'Access, Flag => True);
My_Object.Do_Something_Else (Flag => True);

Wording Changes from Ada 2005

{AI05-0090-1} Correction: Corrected the definition of a prefixed view to ignore the implicit subprograms declared for “implemented by” entries and protected subprograms. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe