Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference Manual (Ada 2022)Legal Information
Contents   Index   References   Search   Previous   Next 

13.1.1 Aspect Specifications

{AI05-0183-1} [Certain representation or operational aspects of an entity may be specified as part of its declaration using an aspect_specification, rather than using a separate representation or operational item.] The declaration with the aspect_specification is termed the associated declaration. 


{AI05-0183-1} aspect_specification ::= 
   with aspect_mark [=> aspect_definition] {,
           aspect_mark [=> aspect_definition] }
{AI05-0183-1} aspect_mark ::= aspect_identifier['Class]
{AI05-0183-1} {AI12-0187-1} {AI12-0285-1} {AI12-0373-1} aspect_definition ::= 
name | expression | identifier
  | aggregate | global_aspect_definition

Language Design Principles

{AI05-0183-1} {AI05-0267-1} The aspect_specification is an optional element in most kinds of declarations. Here is a list of all kinds of declarations and an indication of whether or not they allow aspect clauses, and in some cases a short discussion of why (* = allowed, NO = not allowed). Kinds of declarations with no indication are followed by their subdivisions (which have indications).
{AI12-0005-1} {AI12-0061-1} {AI12-0079-3} {AI12-0395-1} {AI12-0398-1} basic_declaration
      type declaration syntax*
    incomplete_type_declaration  --  NO
      -- Incomplete types do not have aspects by definition, type aspects cannot be read by an attribute or specified by attribute_definition_clause
      -- (the attribute name is illegal), so it would not make sense to allow specifying them this in another way.
    object declaration syntax*
number_declaration  --  NO
iterated_component_association  -- NO


package_declaration*  -- via package_specification
    -- There are no language-defined aspects that may be specified
    -- on renames, but implementations might support some.
generic_package_declaration* -- via package_specification
enumeration_literal_specification  --  NO
    -- The syntax would be ambiguous if this was supported directly.

    -- There are no language-defined aspects that may be specified
    -- on discriminants, but implementations might support some.
  --  NO
loop_parameter_specification  --  NO
chunk_specification  -- NO - the enclosing construct has an aspect_specification

iterator_specification  --  NO
iterator_parameter_specification  -- NO

    -- There are no language-defined aspects that may be specified
    -- on parameters, but implementations might support some.
  --  NO
subprogram_body*  --   - but language-defined aspects only if there is no explicit specification
    -- There are no language-defined aspects that may be specified
    -- on an entry index, but implementations might support some.
  --  NO
subprogram_body_stub*  --   - but language-defined aspects only if there is no explicit specification
choice_parameter_specification  --  NO
    -- There are no language-defined aspects that may be specified
    -- on generic formals, but implementations might support some.

formal_incomplete_type_declaration  --  NO  - see incomplete_type_declaration above
    -- There are no language-defined aspects that may be specified
    -- on return objects, but implementations might support some.
 extended_return_statement  --  NO
{AI12-0005-1} {AI12-0169-1} -- We also allow aspect_specifications on all kinds of bodies, but there are no language-defined aspects
-- that may be specified on a body. These are allowed for implementation-defined aspects.
-- See above for subprogram bodies and stubs (as these can be declarations).

{AI05-0267-1} Syntactically, aspect_specifications generally are located at the end of declarations. When a declaration is all in one piece such as a null_procedure_declaration, object_declaration, or generic_instantiation the aspect_specification goes at the end of the declaration; it is then more visible and less likely to interfere with the layout of the rest of the structure. However, we make an exception for program units (other than subprogram specifications) and bodies, in which the aspect_specification goes before the is. In these cases, the entity could be large and could contain other declarations that also have aspect_specifications, so it is better to put the aspect_specification toward the top of the declaration. (Some aspects – such as Pure – also affect the legality of the contents of a unit, so it would be annoying to only see those after reading the entire unit.)

Name Resolution Rules

{AI05-0183-1} {AI12-0212-1} An aspect_mark identifies an aspect of the entity defined by the associated declaration (the associated entity); the aspect denotes an object, a value, an expression, an aggregate, a subprogram, or some other kind of entity. If the aspect_mark identifies: 
an aspect that denotes an object, the aspect_definition shall be a name. The expected type for the name is the type of the identified aspect of the associated entity;
an aspect that is a value or an expression, the aspect_definition shall be an expression. The expected type for the expression is the type of the identified aspect of the associated entity;
{AI12-0212-1} an aspect that is an aggregate, the aspect definition shall be an expression that is an aggregate, with the form of the aggregate determined by the identified aspect;
Ramification: {AI12-0212-1} The only requirement here is that the expression is syntactically an aggregate; there is no requirement that it resolve to some particular type or even that it should resolve like an aggregate. Each aspect that uses an aggregate is responsible for specifying how the choice(s), component(s), and other contents of the aggregate are resolved and interpreted. 
an aspect that denotes a subprogram, the aspect_definition shall be a name; the expected profile for the name is the profile required for the aspect of the associated entity;
an aspect that denotes some other kind of entity, the aspect_definition shall be a name, and the name shall resolve to denote an entity of the appropriate kind;
an aspect that is given by an identifier specific to the aspect, the aspect_definition shall be an identifier, and the identifier shall be one of the identifiers specific to the identified aspect. 
{AI05-0183-1} {AI12-0373-1} {AI12-0427-1} The usage names in an aspect_definition associated with a declaration [ are not resolved at the point of the associated declaration, but rather] are resolved at the end of the immediately enclosing declaration list, or in the case of the declaration of a library unit, at the end of the visible part of the entity.
Ramification: If an aspect_specification is not associated with a declaration (instead being part of a statement or expression), then it is resolved when the associated construct is resolved.
{AI05-0183-1} {AI12-0180-1} {AI12-0220-1} If the associated declaration is for a subprogram, or entry,  or access-to-subprogram type, the names of the formal parameters are directly visible within the aspect_definition, as are certain attributes, as specified elsewhere in this document for the identified aspect. If the associated declaration is a type_declaration, within the aspect_definition the names of any visible components, protected subprograms, and entries are directly visible, and the name of the first subtype denotes the current instance of the type (see 8.6). If the associated declaration is a subtype_declaration, within the aspect_definition the name of the new subtype denotes the current instance of the subtype.

Legality Rules

{AI05-0183-1} If the first freezing point of the associated entity comes before the end of the immediately enclosing declaration list, then each usage name in the aspect_definition shall resolve to the same entity at the first freezing point as it does at the end of the immediately enclosing declaration list.
  {AI12-0181-1} {AI12-0396-1} An expression or name that causes freezing of an entity shall not occur within an aspect_specification that specifies a representation or operational aspect of that entity.
Reason: {AI12-0181-1} {AI12-0396-1} The rule prevents an aspect of an entity from depending (directly or indirectly) on properties of the entity itself. 
Implementation Note: {AI12-0396-1} This check needs to be deferred at least to the freezing of the entity (as the aspect_definition is not resolved until then), and might be accomplished during the freezing of the aspect_definition (since it is closely related). Keep in mind that multiple other entities could be involved. 
{AI05-0183-1} At most one occurrence of each aspect_mark is allowed within a single aspect_specification. The aspect identified by the aspect_mark shall be an aspect that can be specified for the associated entity (or view of the entity defined by the associated declaration).
Ramification: {AI12-0116-1} {AI12-0005-1} {AI12-0396-1} This rule prevents multiple specifications in the same aspect_specification. Rules in 13.1 prevent multiple specifications in different aspect_specifications (on different views of the same type, for instance), or between operational or representation items and an aspect_specification, even for aspects that are neither operational nor representation aspects.
{AI05-0183-1} The aspect_definition associated with a given aspect_mark may be omitted only when the aspect_mark identifies an aspect of a boolean type, in which case it is equivalent to the aspect_definition being specified as True.
{AI05-0183-1} If the aspect_mark includes 'Class, then the associated entity shall be a tagged type or a primitive subprogram of a tagged type.
{AI05-0183-1} {AI05-0267-1} {AI12-0064-2} {AI12-0194-1} {AI12-0380-1} {AI12-0407-1} Unless otherwise specified for a specific aspect, a There are no language-defined aspect cannot aspects that may be specified on a renaming_declaration or, a generic_formal_parameter_declaration, a subunit, a package_body, a task_body, a protected_body, or a body_stub other than a subprogram_body_stub.
Discussion: {AI12-0064-2} Implementation-defined aspects can be allowed on these, of course; the implementation will need to define the semantics. In addition particular, the language does not define default aspect matching rules for generic formals; only the handful of aspects allowed on formals have such rules. Therefore, the implementation will need to define actual type matching rules for any aspects allowed on formal types; there are no default matching rules defined by the language
{AI05-0183-1} {AI05-0267-1} {AI12-0105-1} {AI12-0380-1} Unless specified otherwise, a A language-defined aspect shall not be specified in an aspect_specification given on a subprogram_body or subprogram_body_stub that is a completion of program unit subprogram or generic subprogram another declaration.
Reason: Most language-defined aspects (for example, preconditions) are intended to be available to callers, and specifying them on a body that has a separate declaration hides them from callers. Specific language-defined aspects may allow this, but they have to do so explicitly (by defining an alternative Legality Rule), and provide any needed rules about visibility. Note that this rule does not apply to implementation-defined aspects, so implementers need to carefully define whether such aspects can be applied to bodies and stubs, and what happens if they are specified on both the declaration and body of a unit. 
  {AI05-0183-1} {AI12-0138-1} If an aspect of a derived type is inherited from an ancestor type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type, unless otherwise specified in this document.
Reason: Most boolean-valued language-defined aspects are associated with a representation pragma. The existing rules for such pragmas assume that the aspect cannot be removed. For instance, if a type T is declared to be Atomic, then all descendants of T are also Atomic. This rule ensures that remains the case when using the aspect notation instead of pragmas. 
Discussion: This definition leaves holes for Boolean aspects that can be specified on non-first subtypes. Such aspects (for instance, Nonblocking) must have their own rules (that is, "otherwise specify" rules) that define the effects of inheriting from subtypes (both first subtypes and nonfirst subtypes). 
  {AI12-0396-1} If a given aspect is type-related and inherited, then within an aspect_definition for the aspect, if a name resolves to denote multiple visible subprograms, all or none of the denoted subprograms shall be primitives of the associated type.
Reason: {AI12-0396-1} This is necessary because the inheritance rules for names denoting primitive subprograms are different from those for names denoting other entities — see 13.1.
  {AI12-0138-1} {AI12-0206-1} {AI12-0419-1} Certain type-related aspects are defined to be nonoverridable;; all such aspects are specified using an aspect_definition that is a name. all such aspects are inherited by derived types according to the rules given in 13.1. Any legality rule associated with a nonoverridable aspect is re-checked for the derived type, if the derived type is not abstract. Certain type-related and subtype-specific aspects are defined to be additive; such aspects are not inherited, but they can apply to the types derived from, or the subtypes based on, the original type or subtype, as defined for each such aspect. Finally, certain type-related aspects are implicitly composed; such aspects are not inherited, but rather a default implementation for a derived type is provided, as defined for each such aspect, based on that of its parent type, presuming the aspect for the parent type is available where the derived type is declared, plus those of any new components added as part of a type extension.
  {AI12-0138-1} {AI12-0206-1} {AI12-0211-1} {AI12-0396-1} If a nonoverridable aspect is directly specified for a type T, then any explicit specification of that aspect for any other descendant of T (other than T itself) shall be confirming. In the case of an aspect that whose value is a name, this means that; that is, the specified name shall match the inherited aspect in the sense that it, meaning that the specified name shall denote the same declarations as would the inherited name. Similarly, for an aspect that is an expression or an aggregate, confirming means the defining expression is fully conformant (see 6.3.1) with the defining expression for the inherited aspect, with the added rule that an identifier that is specific to the aspect is the same as the corresponding identifier in the inherited aspect.
  {AI12-0138-1} {AI12-0396-1} If a full type has a partial view, and a given nonoverridable aspect is allowed for both the full view and the partial view, then the given aspect for the partial view and the full view shall be the same: the aspect shall be directly specified only on the partial view; if the full type inherits the aspect, then a matching definition shall be specified (directly or by inheritance) for the partial view.
Ramification: In order to enforce these rules without breaking privacy, we cannot allow a private type that could have a particular overridable aspect to have a hidden definition of that aspect. There is no problem if the private type does not allow the aspect (as the aspect could not be specified on descendants in that case). 
  {AI12-0211-1} If a type inherits a nonoverridable aspect from multiple ancestors, the value of the aspect inherited from any given ancestor shall be confirming of the values inherited from all other ancestors.
Reason: {AI12-0005-1} {AI12-0211-1} If more than one progenitor of a type T specifies a nonoverridable aspect, they all have to specify the same or matching values for that aspect. Otherwise, we'd have two different values for the aspect that depend on which progenitor we inherit from.
  {AI12-0138-1} {AI12-0211-1} In addition to the places where Legality Rules normally apply (see 12.3), these rules about nonoverridable aspects also apply in the private part of an instance of a generic unit.
  {AI12-0138-1} {AI12-0206-1} {AI12-0256-1} {AI12-0373-1} {AI12-0437-1} [The Default_Iterator, Iterator_Element, Implicit_Dereference, Constant_Indexing, and Variable_Indexing aspects are nonoverridable.]
Discussion: We don't need an assume-the-worst rule for most nonoverridable aspects as they only work on tagged types and deriving from formal tagged types is not allowed in generic bodies. In the case of Implicit_Dereference, a derivation in a generic body does not cause problems (the ancestor necessarily cannot have the aspect, else specifying the aspect would be illegal), as there could be no place with visibility on both aspects. In the case of Max_Entry_Queue_Length, it is only allowed on task and protected types, and on entries, and there are not formal versions of any of those things. In the case of No_Controlled_Parts, we defined an assume-the-worst rule with the aspect.
{AI12-0437-1} A list of all nonoverridable aspects can be found in the index, under “nonoverridable aspect”. 

Static Semantics

{AI05-0183-1} Depending on which aspect is identified by the aspect_mark, an aspect_definition specifies: 
a name that denotes a subprogram, object, or other kind of entity;
{AI12-0427-1} an expression (other than an aggregate), which is either evaluated to produce a single value, or which (as in a precondition) is to be evaluated at particular points during later execution; or
{AI12-0427-1} an identifier specific to the aspect; or.
{AI12-0427-1} an aggregate, which is positional or named, and is composed of elements of any of these four kinds of constructs. 
{AI05-0183-1} The identified aspect of the associated entity, or in some cases, the view of the entity defined by the declaration, is as specified by the aspect_definition (or by the default of True when boolean). Whether an aspect_specification applies to an entity or only to the particular view of the entity defined by the declaration is determined by the aspect_mark and the kind of entity. The following aspects are view specific:
An aspect specified on an object_declaration;
An aspect specified on a subprogram_declaration;
An aspect specified on a renaming_declaration.
{AI05-0183-1} All other aspect_specifications are associated with the entity, and apply to all views of the entity, unless otherwise specified in this document.
{AI05-0183-1} {AI12-0106-1} If the aspect_mark includes 'Class (a class-wide aspect), then, unless specified otherwise for a particular class-wide aspect
if the associated entity is a tagged type, the specification applies to all descendants of the type;
if the associated entity is a primitive subprogram of a tagged type T, the specification applies to the corresponding primitive subprogram of all descendants of T.
{AI05-0183-1} {AI05-0229-1} All specifiable operational and representation attributes may be specified with an aspect_specification instead of an attribute_definition_clause (see 13.3).
Ramification: The name of the aspect is the same as that of the attribute (see 13.3), so the aspect_mark is the attribute_designator of the attribute.
{AI12-0005-1} Unless specified otherwise, all of the requirements for specifying a particular aspect with an attribute_definition_clause also apply to an aspect_specification for the aspect. These are enforced at the freezing point of the entity. For example, when specifying the Size aspect of a subtype, the expression has to be a static expression with an integer type and a nonnegative value, all of the recommended level of support requirements apply if Annex C is supported (see C.2), and so on. 
{AI05-0229-1} {AI12-0154-1} {AI12-0417-1} Some aspects are defined to be library unit aspects. Library unit aspects are Any aspect specified by a representation pragma or library unit pragma that has a local_name as its single argument may be specified by an aspect_specification, with the entity being the local_name. The aspect_definition is expected to be of type Boolean. The expression specifying a library unit aspect shall be static. Library unit aspects are defined for all program units, but shall be specified only for library units. Notwithstanding what this document says elsewhere, the expression of a library unit an aspect that can be specified by a library unit pragma is resolved and evaluated at the point where it occurs in the aspect_specification[, rather than the first freezing point of the associated unit package ].
Ramification: The name of the aspect is the same as that of the pragma (see 13.1), so the aspect_mark is the name of the pragma. 
{AI05-0229-1} In addition, other operational and representation aspects not associated with specifiable attributes or representation pragmas may be specified, as specified elsewhere in this document.
This paragraph was deleted.{AI05-0183-1} {AI12-0138-1} If an aspect of a derived type is inherited from an ancestor type and has the boolean value True, the inherited value shall not be overridden to have the value False for the derived type, unless otherwise specified in this document.
{AI05-0183-1} If a Legality Rule or Static Semantics rule only applies when a particular aspect has been specified, the aspect is considered to have been specified only when the aspect_specification or attribute_definition_clause is visible (see 8.3) at the point of the application of the rule.
Reason: Some rules only apply when an aspect has been specified (for instance, an indexable type is one that has aspect Variable_Indexing specified). In order to prevent privacy breaking, this can only be true when the specification of the aspect is visible. In particular, if the Variable_Indexing aspect is specified on the full view of a private type, the private type is not considered an indexable type. 
{AI05-0183-1} Alternative legality and semantics rules may apply for particular aspects, as specified elsewhere in this document.

Dynamic Semantics

{AI05-0183-1} {AI12-0355-2} At the freezing point of the associated entity, the aspect_specification is elaborated. When appearing in a construct other than a declaration, an aspect_specification is elaborated as part of the execution of the construct. The elaboration of the aspect_specification consists of the elaboration of each aspect_definition in an arbitrary order. The elaboration of an aspect_definition includes the evaluation of any the name or expression that is part of the aspect_definition, if any, unless the part is itself aspect itself is an expression. If the corresponding aspect (or part thereof) represents an expression (as in a precondition), the elaboration of that part has no effect; the expression is evaluated later at points within the execution as specified elsewhere in this document for the particular aspect. 

Implementation Permissions

{AI05-0183-1} Implementations may support implementation-defined aspects. The aspect_specification for an implementation-defined aspect may use an implementation-defined syntax for the aspect_definition, and may follow implementation-defined legality and semantics rules. 
Discussion: {AI12-0389-1} The intent is to allow implementations to support aspects that are defined, for example, by a subtype_indication rather than an expression or a name. We chose not to try to enumerate all possible aspect_definition syntaxes, but to give implementations maximum freedom. Unrecognized aspects are illegal whether or not they use custom syntax, so this freedom does not reduce portability. 
Implementation defined: Implementation-defined aspects, including the syntax for specifying such aspects and the legality rules for such aspects.
{AI12-0389-1} An implementation may ignore the specification of an unrecognized aspect; if an implementation chooses to ignore such an aspect specification (as opposed to rejecting it), then it has no effect on the semantics of the program except for possibly (and this is not required) the rejection of syntax errors within the aspect_definition.
Discussion: {AI12-0389-1} Identifying the textual end of an aspect_definition for an unrecognized aspect may be challenging, particularly if the syntax for the unrecognized aspect's aspect_definition is implementation-defined. It is not specified how an implementation might accomplish this. Note that an implementation is never required to be able to do this; if an aspect_definition for an unrecognized aspect is problematic in any way, then it can always be rejected (as opposed to being ignored). 

Extensions to Ada 2005

{AI05-0183-1} {AI05-0229-1} {AI05-0267-1} Aspect specifications are new. 

Inconsistencies With Ada 2012

{AI12-0180-1} Correction: Names of protected subprograms and entries are now directly visible in an aspect of a type declaration. This was always intended to be the case, but it was omitted from the Reference Manual by an editing error. In the unlikely case that a parameterless protected function has the same name and type as an entity used in a type invariant expression, the meaning would change from the outside entity which would now be hidden by the protected function. It is much more likely that a conflict (itself rather unlikely) would cause a resolution failure. 

Incompatibilities With Ada 2012

{AI12-0154-1} Corrigendum: Added a clarification that aspects that correspond to library unit pragmas are resolved and evaluated immediately. This is incompatible, as a reference to an entity defined after the aspect will now be illegal. However, this would have required retroactive enforcement of such aspects, which is a new capability not available from the associated pragma, and moreover no known Ada 2012 implementation has ever allowed late evaluation of such aspects. As such, there should be no practical incompatibility.
{AI12-0005-1} {AI12-0220-1} Parameters of access-to-subprogram types are now visible in aspect specifications. This can be incompatible if some entity with the same name as a parameter is used in an existing aspect specification. We believe that all such aspects require either static expressions or a subprogram that is statically denoted; since a parameter can be neither of these and hides everything else, all such cases will be caught at compile-time. In addition, we expect such cases to be very rare.

Extensions to Ada 2012

{AI12-0212-1} An aspect can be an unresolved aggregate, these can be used to specify a list of entities, or to set a group of different but related properties with a single aspect.
{AI12-0355-2} Aspect specifications can appear in, and apply to, constructs other than declarations.
{AI12-0389-1} An unrecognized aspect specification can be ignored.

Wording Changes from Ada 2012

{AI12-0105-1} Corrigendum: Clarified the wording so that the restriction against language-defined aspects on subprogram completions includes completions that are expressions functions and null procedures.
{AI12-0106-1} Corrigendum: Defined class-wide aspect for use in rules in 13.13.2.
{AI12-0138-1} Corrigendum: Added a definition of nonoverridable aspects. This is necessary to prevent generic contract problems with formal derived types.
{AI12-0194-1} Correction: Added entry_body to the list of entities that don't allow any language-defined aspects. This was an oversight in AI12-0169-1 which allowed aspect_specifications on an entry_body in the first place.
{AI12-0206-1} Correction: Extended the definition of nonoverridable aspects to cover most kinds of aspects.
{AI12-0211-1} Correction: Added a rule so that the a nonoverridable aspect has to be the same for every ancestor of a type.
{AI12-0355-2} {AI12-0427-1} Clarified when elaboration and resolution of aspect_specifications not associated with a declaration occur.
{AI12-0380-1} {AI12-0407-1} Revised the rules about entities that cannot have specified language-defined aspects. The body portion of the rule was changed to a general prohibition on specifying language-defined aspects on completions (this allows specifying aspects on bodies that act as a declaration, and eliminates the list of entities, which was a maintenance nightmare). Then the remaining entities (renamings and generic formal parameters) were revised to allow specific aspects, since Nonblocking (see 9.5), as well as Pre and Post, are now allowed on generic formal parameters.
{AI12-0373-1} Added the missing definition for resolution of entities found in aspects of library units.
{AI12-0396-1} Correction: Defined confirming for nonoverridable aspects that are expressions or aggregates.
{AI12-0419-1} Added a description of additive and implicitly composed aspects in order to explain the different inheritance mechanisms used by existing aspects. 

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