3.10.1 Incomplete Type Declarations

From OC Systems Wiki!
Jump to: navigation, search

There are no particular limitations on the designated type of an access type. In particular, the type of a component of the designated type can be another access type, or even the same access type. This permits mutually dependent and recursive access types. An incomplete_type_declaration can be used to introduce a type to be used as a designated type, while deferring its full definition to a subsequent full_type_declaration.

Syntax

incomplete_type_declaration ::= type defining_identifier [discriminant_part];

Legality Rules

An incomplete_type_declaration requires a completion, which shall be a full_type_declaration. If the incomplete_type_declaration occurs immediately within either the visible part of a package_specification or a declarative_part, then the full_type_declaration shall occur later and immediately within this visible part or declarative_part. If the incomplete_type_declaration occurs immediately within the private part of a given package_specification, then the full_type_declaration shall occur later and immediately within either the private part itself, or the declarative_part of the corresponding package_body.

If an incomplete_type_declaration has a known_discriminant_part, then a full_type_declaration that completes it shall have a fully conforming (explicit) known_discriminant_part (see 6.3.1). If an incomplete_type_declaration has no discriminant_part (or an unknown_discriminant_part), then a corresponding full_type_declaration is nevertheless allowed to have discriminants, either explicitly, or inherited via derivation.

The only allowed uses of a name that denotes an incomplete_type_declaration are as follows:

  • as the subtype_mark in the subtype_indication of an access_to_object_definition; the only form of constraint allowed in this subtype_indication is a discriminant_constraint;
  • as the subtype_mark defining the subtype of a parameter or result of an access_to_subprogram_definition;
  • as the subtype_mark in an access_definition;
  • as the prefix of an attribute_reference whose attribute_designator is Class; such an attribute_reference is similarly restricted to the uses allowed here; when used in this way, the corresponding full_type_declaration shall declare a tagged type, and the attribute_reference shall occur in the same library unit as the incomplete_type_declaration.

A dereference (whether implicit or explicit -- see 4.1) shall not be of an incomplete type.

Static Semantics

An incomplete_type_declaration declares an incomplete type and its first subtype; the first subtype is unconstrained if a known_discriminant_part appears.

Dynamic Semantics

The elaboration of an incomplete_type_declaration has no effect.

Notes

80  Within a declarative_part, an incomplete_type_declaration and a corresponding full_type_declaration cannot be separated by an intervening body. This is because a type has to be completely defined before it is frozen, and a body freezes all types declared prior to it in the same declarative_part (see 13.14).

Examples

Example of a recursive type:

type Cell;  --  incomplete type declaration
type Link is access Cell;

type Cell is 
    record
        Value  : Integer;
        Succ   : Link;
        Pred   : Link;
    end record;

Head   : Link  := new Cell'(0, null, null); 
Next   : Link  := Head.Succ;

Examples of mutually dependent access types:

type Person(<>);    -- incomplete type declaration
type Car;           -- incomplete type declaration

type Person_Name is access Person;
type Car_Name    is access all Car;

type Car is 
    record
        Number  : Integer;
        Owner   : Person_Name;
    end record;

type Person(Sex Gender) is 
    record
        Name     : String(1 .. 20);
        Birth    : Date;
        Age      : Integer range 0 .. 130;
        Vehicle  : Car_Name;
        case Sex is
            when M => Wife           : Person_Name(Sex => F); 
            when F => Husband        : Person_Name(Sex => M);
        end case;
    end record;

My_Car, Your_Car, Next_Car : Car_Name := new Car;  -- see 4.8 
George : Person_Name := new Person(M);
 ...
George.Vehicle := Your_Car;

Copyright © 1992,1993,1994,1995 Intermetrics, Inc.
Copyright © 2000 The MITRE Corporation, Inc. Ada Reference Manual