TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Package Elements

Package Elements provides access to the syntactic elements that make up program units. Functions are available that traverse the element hierarchy, identify the kinds of elements encountered, and obtain the element logically enclosing another element.

Package Elements also provides functions to analyze pragmas.

For more information, click on a topic:


Resources in Package Elements

The resources in package Elements fall into several functional groups, as shown below.

To see detailed referenced information, click on the name of a resource:
Determining element kind and properties:
Element_Kind Is_Identical
Is_Equal Is_Nil
Traversing the element hierarchy:
Enclosing_Element
Traverse_Element
Processing pragmas:
Argument_Associations Is_Predefined Pragma_Kind
Associated_Pragmas Name Pragmas


Key Concepts for Package Elements

The following sections describe elements and how to use package Elements. For more information, click on a topic:

Elements Defined

Elements are handles for the syntactic and semantic information available from most Ada libraries. Elements are either syntactic terminal elements or syntactic composite elements. Composite elements reference other terminal or composite elements. For example, a simple name (Ada83 LRM 4.1, Ada95 LRM 4.1) is a terminal element, whereas a selected component (Ada83 LRM 4.1.3, Ada95 LRM 4.1.3) is a composite element consisting of two subcomponents: a prefix and a selector.

Compilers use different intermediate representations for source code. A common one is the DIANA1 form. Most representations, including DIANA, consist of an annotated parse tree. The tree contains the composite and terminal nodes that contain information of importance to the compiler or associated tools.

It is unlikely that any existing intermediate form is identical to the representation required by ASIS. Thus, the ASIS implementation must convert or augment the library content to present the element structure required by the ASIS standard.

For more information, click on a topic

Compilation Units and Elements

ASIS interfaces allow you to view as a tree the elements that compose a compilation unit (Ada83 LRM 10.1, Ada95 LRM 10.1). Each element represents a nonterminal or terminal node in the tree. Functions are available to traverse the tree depth first (see "Traversing the Element Tree") or to work up the tree to the root element.

The root element is one that represents the declaration portion of a compilation unit. You obtain this root element from the Compilation_Units.Unit_Declaration function. This function is the gateway between the compilation units and the elements that make up the units.

Assuming that a library is already open, a typical sequence of calls to obtain and process the root elements for all units in a library would be:

The Compilation_Units.Enclosing_Compilation_Unit function allows you to reverse the process. This function takes any non-nil element as input and returns the compilation unit from which the element was obtained.

ASIS provides functions that allow you to decompose the elements representing composite structures into the elements representing the components. These functions perform structural traversal. Structural traversal is performed within a single compilation unit.

ASIS also provides functions that allow you to obtain semantically related elements. This includes such things as the body corresponding to a specification or the full type definition of a private type definition. These functions perform nonstructural, or semantic, traversal. Semantic traversal can take place between different compilation units. These traversals can cause the Obsolete_Reference_Error exception to be raised if the target unit of the traversal does not exist in the library or is obsolete.

ASIS is not required to lock libraries or their contents while it is in use. Simultaneous access to a library by a compiler or tool that updates the library can invalidate internal ASIS structures or the elements in use by the ASIS application. This is described in more detail in the "Compilation-Unit Locking" section of package Compilation_Units.

Element Origins

The origin of an element can be either explicit or implicit. If the origin is explicit, the element represents something that physically appears in the source code. If the origin is implicit, the element was created as a side effect of a declaration or some other construct in the source code but does not itself represent something that appears in the source code. You can determine whether an element's origin is implicit with the Declarations.Is-_Part_Of_Implicit function.

Elements whose origins are explicit occupy column positions and lines and have an associated text image. Elements whose origins are implicit have no positions and no text image. A terminal element is constrained by the Ada LRM to fit on one line of program text, but a composite element can span many lines. Package Text contains functions for processing the text images of elements.

Element Kinds and Properties

The kinds of elements known to ASIS are described by the Element_Kinds type. This type classifies elements into declarations, statements, expressions, type definitions, and several other classes. You can obtain the kind of an element with the Element_Kind function.

The Element_Kinds type includes the value Not_An_Element; this value is returned from the Element_Kind function if the specified element is Asis.Nil_Element. You can also determine whether an element is Asis.Nil_Element by calling the Is_Nil function.

Element values can be compared with the Is_Equal and Is_Identical functions. Is_Equal returns True if the elements represent the same semantic element from the same physical compilation unit. Is_Identical returns True if the elements are Is_Equal and have been obtained using the same library value.

For many Element_Kinds, ASIS provides other enumeration types that provide further categorization. For example, a statement could be an assignment statement, a loop statement, or a raise statement. See the Element_Kinds type for a table that details this additional categorization. The description of the Element_Kind function contains a table that indicates the packages to use to further categorize an element of a particular kind.

Traversing the Element Tree

As described earlier, the content of an Ada library typically contains some form of annotated parse tree. An ASIS implementation is required to convert and augment the information in the parse tree into a corresponding tree containing the element structure required by the ASIS standard

Elements are either syntactic terminal elements or syntactic composite elements. Composite elements reference other terminal or composite elements. A composite element is the parent element of each terminal or composite element it references. The referenced elements are child elements. Child elements with the same parent element are sibling elements of each other.

Since the elements form a tree, many elements are simultaneously parent and child elements. The only element that has no parent element is the root element, and the only elements that have no child elements are the terminal elements.

The root element typically represents the declaration of an Ada compilation unit. The terminal elements represent the tokens that compose the compilation unit. For example, a package declaration could be the root of an element tree; the name of the package being declared is a child to the declaration and is a terminal element.

These relationships are shown in the following diagram:

ASIS provides three methods of syntactically traversing an element tree or subtree:

The Traverse_Element generic procedure and Enclosing_Element function provide a general interface to traversal. Functions in packages Declarations, Expressions, Representation-_Clauses, Statements, and Type_Definitions provide a context-specific interface to traversal.

For example, if you used Traverse_Element to walk the tree representing an if statement with an else part, you would first encounter the condition after the reserved word if, then the statements after the reserved word then, followed by the else arm, and then the statements that constitute the arm. Alternatively, you can use functions in package Statements to obtain the element representing the condition after the reserved word if, the elements list representing the arms that make up the statement, and the element list of the statements that constitute each arm.

For more information, click on a topic:

Enclosing Elements

You can call the Enclosing_Element function to obtain the parent element of a specified element. For example, given an element representing A_Statement from a sequence of statements enclosed within a loop statement, the enclosing element is A_Loop_Statement.

If an Element has an enclosing element, repetitive invocations of Enclosing_Element will eventually result in A_Declaration Element that represents the compilation unit and the root of the element tree.

Certain elements have no parent element. Enclosing_Element returns Asis.Nil_Element in these cases:

Traversing Elements

Element traversal is performed by an instantiation of the Traverse_Element generic procedure. To instantiate this procedure, you must provide a type and two formal procedures:

To initiate a traversal, you call your instantiation with an element, your state data, and a Control parameter. The element represents the root of the tree you want to traverse. The state data is not used by the generic and so can be set to whatever is appropriate for your application. The Control parameter value determines how the traversal should proceed, as described in "Controlling Traversal."

Elements that are Declarations.Is_Part_Of_Implicit are not normally reached by a traversal starting with an element that is not Is_Part_Of_Implicit. This means that implicit predefined and implicit derived subprogram declarations are not visited when A_Type_Definition is traversed, generic instances are not visited when a generic instantiation is traversed, and all parameter and argument lists are traversed in their unnormalized forms.

Element structures that are Is_Part_Of_Implicit can be traversed by starting the traversal with an Is_Part_Of_Implicit element. Typically, the traversal will start with the outermost enclosing element.

Implicit declarations, generic instances, and normalized parameter and argument lists can be made part of a traversal by explicitly calling the appropriate interfaces when a type definition, generic instantiation, call, or aggregate is encountered.

Applications that need to traverse normalized association lists can do so by querying at the appropriate locations to obtain the normalized list. This list then can be traversed by calling the instantiation of the traversal generic for each element.

Controlling Traversal

The Control parameter value is normally Continue. This indicates that the traversal should be performed normally, depth first and left to right. Other settings allow you to ignore children of the current element, to ignore siblings of the current element, and to immediately terminate the traversal. The effect of each option is described more fully in the description of the Traverse_Element generic procedure.

When the Control parameter value is set to Continue, the formal procedure Pre_Operation is called when first visiting an element. All component elements are then visited, and, finally, the formal procedure Post_Operation is called when returning from visiting all component elements.

You can alter the value of the Control parameter in either the Pre_Operation procedure or the Post_Operation procedure. For example, you could traverse an expression until you found the use of a particular variable. Upon finding the variable, you could set the Control parameter to abandon the remaining children. Note that at some point you should reset the value to Continue or the traversal will walk back up the tree and terminate.

To be supplied: examples showing the element heirarchy and include them in this section.

Processing Pragmas

Pragmas are defined in terms of the following Ada syntactic components:

Ada83 LRM 2.8, Ada95 LRM 2.8

 pragma ::=
  pragma identifier [(argument_association
   {, argument_association})];

argument_association ::=
   [argument_identifier =>] name
  | [argument_identifier =>] expression

The components and related information can be obtained by calling the subprograms in the following table:
Information Desired
Call to Use
identifier
Name
argument_association list
Argument_Associations
argument_identifier
Statements.Formal_Parameter
name
expression

Statements.Actual_Parameter

The Ada LRM describes a number of predefined language pragmas in Annex B. Each predefined pragma has a separate enumeration value in the Pragma_Kinds type.

Compilers can accept more pragmas, however, than are described in Annex B. These additional pragmas are described in the compiler's Appendix F. The enumeration value An_Implementation_Defined_Pragma is assigned to these compiler- specific pragmas.

A compiler must also parse, and might even record in its libraries, pragmas that are unkknown to the implementation. The enumeration value An_Unknown_Pragma is assigned to these pragmas.

You can call the Is_Predefined function to determine whether a pragma represents a predefined language pragma.

ASIS provides three methods to obtain elements that represent pragmas:


Function Argument_Associations

Expanded Name Asis.Elements.Argument_Associations

Returns a list of the arguments appearing in the specified pragma.

Description

Pragmas are partially defined by the following syntax:

Ada83 LRM 2.8, Ada95 LRM 2.8

 pragma ::=
  pragma identifier [(argument_association
   {, argument_association})];

 argument_association ::=
   [argument_identifier =>] name
  | [argument_identifier =>] expression

This function returns a list of the argument associations for the specified pragma.

The arguments are returned in their order of appearance in the source code. If no arguments have been specified for the pragma, Asis.Nil_Element_List is returned.

The Statements.Formal_Parameter function can be used to obtain the name of the argument. If named notation has not been used for an argument, the Formal_Parameter function returns Asis.Nil_Element.

The Statements.Actual_Parameter function can be used to obtain the argument expression or name.

Parameters

Specifies the pragma that should be queried. The Pragma_Element must be of the following kind:
Element_Kinds

A_Pragma

The returned list contains elements of the following kind
Element_Kinds

An_Argument_Association
:

Errors

Asis_Inappropriate_Element is raised and Environment.Status is set to Value_Error if a parameter references a Library variable that is no longer open or a parameter is specified that is not appropriate for the query.

Examples

Cross-References

Related subprograms:

Related concept:


Function Associated_Pragmas

Expanded Name Asis.Elements.Associated_Pragmas

Returns a list of the pragmas semantically associated with the specified element.

Description

A semantic association is one in which the pragma affects the specified element. For example, a pragma Pack affects the type it names; a pragma Suppress affects the unit it names.

The elements are returned in their order of appearance in the source code or in any order that does not affect their
interpretation.

If no pragmas are associated with the specified element, Asis.Nil_Element_List is returned.

Parameters

Specifies the element to query. The element must be of the following kinds:
Element_Kinds

A_Declaration

A_Statement

The returned list contains elements of the following kind
Element_Kinds

A_Pragma

:

Errors

Asis_Inappropriate_Element is raised and Environment.Status is set to Value_Error if a parameter references a Library variable that is no longer open or a parameter is specified that is not appropriate for the query.

Examples

Cross-References

Related subprograms:

Related concepts:


Function Debug_Image

Expanded Name Asis.Elements.Debug_Image

Returns implementation-defined debug information for the specified element.

Description

Returns implementation-defined debug information for the specified element.

Update when specification is nailed downParameters

Specifies the element for which debug information is desired.

Rational ASIS returns a single line of text. The content of the line depends on whether the element is nil, invalid, or valid:

  • A valid element returns:

    Where the syntactic categories are defined as follows:
    Syntactic Category
    Content
    column_position
    The first column number of the element. If the element is implicit, the value one is always returned.
    kinds_list
    The kinds of the element and an optional Direction_Matters keyword. These are described in "Representation of Kinds."
    line
    The Text.Debug_Image for the element. If the element is implicit, a nil string is always returned.
    line_number
    The first line number of the element. If the element is implicit, the value one is always returned.
    name
    The Name string specified in Libraries.Associate procedure for the library containing the element.
    parameters
    The Parameters string specified in the Libraries.Associate procedure for the library containing the element.
    tree
    Data useful to maintainers of Rational ASIS. The data might change from release to release.

    Representation of Kinds

    The kinds of an element are represented at follows:

    The Kinds is replaced by the image of the enumeration value. If a particular Kinds is not applicable to an element, that kind is not returned.

    The kinds_list might also include the term Direction_Matters; this is useful to maintainers of Rational ASIS.

    Errors

    None.

    Examples

    Cross-References

    Related subprograms and types:


    Function Element_Kind

    Expanded Name Asis.Elements.Element_Kind

    Returns the kind of the specified element.

    Description

    Package Elements supports the traversal of the element tree and initial analysis of elements with an element kind of A_Pragma. Processing of other element kinds is divided among several other packages. For each element kind, the package for further analysis is shown in the following table:
    Element_Kinds
    Further Processing
    A_Case_Statement_Alternative
    Statements
    A_Choice
    Type_Definitions
    A_Component_Association
    Expressions
    A_Component_Clause
    Representation_Clauses
    A_Constraint
    Type_Definitions
    A_Declaration
    Declarations
    A_Discrete_Range
    Type_Definitions
    A_Discriminant_Association
    Type_Definitions
    A_Null_Component
    Type_Definitions
    A_Parameter_Association
    Statements
    A_Pragma
    Elements
    A_Representation_Clause
    Representation_Clauses
    A_Select_Alternative
    Statements
    A_Select_Statement_Arm
    Statements
    A_Statement
    Statements
    A_Subtype_Indication
    Type_Definitions
    A_Type_Definition
    Type_Definitions
    A_Use_Clause
    Expressions
    A_Variant
    Type_Definitions
    A_Variant_Part
    Type_Definitions
    A_With_Clause
    Compilation_Units
    An_Argument_Association
    Statements
    An_Entity_Name_Definition
    Declarations
    An_Exception_Handler
    Statements
    An_Expression
    Expressions
    An_If_Statement_Arm
    Statements
    Not_An_Element

    Parameters

    Specifies the element to be queried.

    Returns the kind of the specified element. If Asis.Nil_Element is specified, Not_An_Element is returned.

    Errors

    None.

    Examples

    Cross-References

    Related subprograms and types:

    Related concept:


    Type Element_Kinds

    Expanded Name Asis.Elements.Element_Kinds

    Describes the kinds of elements available.

    Description

    Elements are the fundamental component of ASIS semantic processing. Each element has an associated kind. This enumeration describes the kinds that are available.

    Some element kinds can be further categorized. For example, an element with an Element_Kinds of A_Declaration can be further categorized by Declaration_Kinds to indicate the kind of declaration being represented. In some cases, a further categorization is possible. This categorization is described in the following table. See the table in the description of the Element_Kind function for a list of packages to use for further processing of an element of a particular Element_Kinds.
    Element_Kinds
    Further Categorization
    A_Case_Statement-
    _Alternative

    ——
    A_Choice
    Choice_Kinds
    A_Component_Association
    ——
    A_Component_Clause
    ——
    A_Constraint
    Constraint_Kinds
    A_Declaration
    Declaration_Kinds
    Component_Kinds
    Generic_Formal_Subprogram-
    _Default_Kinds
    Parameter_Mode_Kinds

    A_Discrete_Range
    Discrete_Range_Kinds
    A_Discriminant_Association
    ——
    A_Null_Component
    Component_Kinds
    A_Parameter_Association
    ——
    A_Pragma
    Pragma_Kinds
    A_Representation_Clause
    Representation_Clause_Kinds
    Length_Clause_Attribute_Kinds

    A_Select_Alternative
    Select_Alternative_Kinds
    A_Select_Statement_Arm
    Select_Statement_Arm_Kinds
    A_Statement
    Statement_Kinds Loop_Kinds
    A_Subtype_Indication
    ——
    A_Type_Definition
    Type_Definition_Kinds
    A_Use_Clause
    ——
    A_Variant
    ——
    A_Variant_Part
    Component_Kinds
    A_With_Clause
    ——
    An_Argument_Association
    ——
    An_Entity_Name_Definition
    Expression_Kinds
    An_Exception_Handler
    ——
    An_Expression
    Expression_Kinds
    Attribute_Designator_Kinds
    Selection_Kinds
    Special_Operation_Kinds

    An_If_Statement_Arm
    If_Statement_Arm_Kinds
    Not_An_Element
    ——

    Enumerations

    Indicates that the element represents a case-statement alternative of a case statement (Ada83 LRM 5.4, Ada95 LRM 5.4).

    Indicates that the element represents a choice (Ada83 LRM 3.7.3, Ada95 LRM 3.8.1).

    Indicates that the element represents the components of an array or record aggregate value (Ada83 LRM 4.3, Ada95 LRM 4.3).

    Indicates that the element represents the component clause of a record representation clause (Ada83 LRM 13.4, Ada95 LRM 13.5.1).

    Indicates that the element represents a constraint (Ada83 LRM 3.3.2, Ada95 LRM 3.2.2).

    Indicates that the element represents the declaration of an object or number (Ada83 LRM 3.2.2, Ada95 LRM 3.3.2), a full type (Ada83 LRM 3.3.1, Ada95 LRM 3.2.1), a subtype (Ada83 LRM 3.3.2, Ada95 LRM 3.2.2), an incomplete type (Ada83 LRM 3.8.1, Ada95 LRM 3.10.1), a private type (Ada83 LRM 7.4, Ada95 LRM 7.3), a component (Ada83 LRM 3.7, Ada95 LRM 3.8), an enumeration literal (Ada83 LRM 3.5.1, Ada95 LRM 3.5.1), a for loop parameter (Ada83 LRM 5.5, Ada95 LRM 5.5), a subprogram or subprogram parameter (Ada83 LRM 6.1, Ada95 LRM 6.1), a subprogram body (Ada83 LRM 6.3, Ada95 LRM 6.3), a package specification (Ada83 LRM 7.1, Ada95 LRM 7.1), a package body (Ada83 LRM 7.4, Ada95 LRM 7.3), a deferred constant (Ada83 LRM 7.4, Ada95 LRM 7.3), a renames (Ada83 LRM 8.5, Ada95 LRM 8.5), a task or task type or task body (Ada83 LRM 9.1, Ada95 LRM 9.1), a task entry (Ada83 LRM 9.5, Ada95 LRM 9.5), a subunit (Ada83 LRM 10.2, Ada95 LRM 10.1.3), an exception (Ada83 LRM 11.1, Ada95 LRM 11.1), a generic or generic formal parameters (Ada83 LRM 12.1, Ada95 LRM 12.1), or a generic instantiation (Ada83 LRM

    Indicates that the element represents a discrete range (Ada83 LRM 3.6, Ada95 LRM 3.6).

    Indicates that the element represents a discriminant association (Ada83 LRM 3.7.2, Ada95 LRM 3.7.1).

    Indicates that the element represents a null entry in a component list (Ada83 LRM 3.7, Ada95 LRM 3.8).

    Indicates that the element represents the parameter associations of a subprogram definition (Ada83 LRM 6.4, Ada95 LRM 6.4) or a generic instantiation (Ada83 LRM 12.3, Ada95 LRM 12.3).

    Indicates that the element represents a pragma (Ada83 LRM 2.8, Ada95 LRM 2.8).

    Indicates that the element represents a representation clause (Ada83 LRM 13.1, Ada95 LRM 13.1).

    Indicates that the element represents the select alternative of a select statement (Ada83 LRM 9.7.1, Ada95 LRM 9.7.1).

    Indicates that the element represents a select statement arm (Ada83 LRM 9.7, Ada95 LRM 9.7).

    Indicates that the element represents a statement (Ada83 LRM 5.1, Ada95 LRM 5.1).

    Indicates that the element represents a subtype indication (Ada83 LRM 3.3.2, Ada95 LRM 3.2.2).

    Indicates that the element represents a type definition (Ada83 LRM 3.3.1, Ada95 LRM 3.2.1).

    Indicates that the element represents a use clause (Ada83 LRM 8.4 , Ada95 LRM 8.4).

    Indicates that the element represents a record-definition variant (Ada83 LRM 3.7.3, Ada95 LRM 3.8.1).

    Indicates that the element represents a record-definition variant part (Ada83 LRM 3.7.3, Ada95 LRM 3.8.1).

    Indicates that the element represents a with clause (Ada83 LRM 10.1.1, Ada95 LRM 10.1.2).

    Indicates that the element represents an argument association from a pragma (Ada83 LRM 2.8, Ada95 LRM 2.8).

    Indicates the element represents a name definition (Ada83 LRM 3.1, Ada95 LRM 3.1).

    Indicates that the element represents an exception handler (Ada83 LRM 11.2, Ada95 LRM 11.2).

    Indicates that the element represents an expression (Ada83 LRM 4.4., Ada95 LRM 4.4).

    Indicates that the element represents an if-statement arm (Ada83 LRM 5.3, Ada95 LRM 5.3).

    Indicates that the element is Asis.Nil_Element.

    Cross-References

    Related subprogram:

    Related concept:


    Function Enclosing_Element

    Expanded Name Asis.Elements.Enclosing_Element

    Returns the parent element of the specified child element.

    Description

    The Traverse_Element function provides a method to traverse the element hierarchy between program components and the associated subcomponents. This is represented as a parent and child relationship and corresponds to structural traversal. The Enclosing_Element function performs the inverse, returning the parent element for a specified child element.

    The tables appearing in many of the parameter sections of ASIS functions indicate the possible combinations of parent and child elements. The table containing the expected input-element values represent the parent elements and the table containing the returned-element values represent the child elements.

    Description (continued)

    Certain elements have no parent element. Enclosing_Element returns Asis.Nil_Element in these cases:

    Semantic traversals do not move from parent to child. Rather, they obtain an element that is semantically related to the initial element. For example, the Declarations.Corresponding-
    _Type_Declaration
    function returns the full type declaration when given a private or incomplete type declaration. The Enclosing_Element of the full type declaration is the block statement of the declarative region where the full type declaration appears and is not the private or incomplete type declaration.

    Each element is also assumed to be enclosed by a specific compilation unit value and a library value. You can use:

    Parameters

    Specifies the element to query.

    Specifies an optional context for the specified element. In some ASIS implementations, the parameter is needed for performance reasons.

    Rational ASIS verifies that the specified context is not associated with a library value that is closed but does not otherwise use the parameter. You can provide Asis.Nil_Element.

    Returns the value of the enclosing element or Asis.Nil_Element if an enclosing element does not exist.

    Errors

    Asis_Inappropriate_Element is raised and Environment.Status is set to Value_Error if a parameter references a Library variable that is no longer open.

    Asis_Inappropriate_Element is raised and Environment.Status is set to Value_Error if Asis.Nil_Element is specified.

    Examples

    Given A_Declaration Element from a declarative region of a block statement, A_Statement/A_Block_Statement element is returned.

    Given A_Statement Element from within a loop statement, A_Statement/A_Loop_Statement element is returned.

    Given An_Expression/A_Simple_Name element representing the selector of an expanded name, an An_Expression/A_Selected_Component element is returned that comprises the prefix, the dot, and the selector.

    Cross-References

    Related subprograms:

    Related concept:

    1 Descriptive Intermediate Attribute Notation for Ada.


  • Rational Software Corporation  http://www.rational.com
    support@rational.com
    techpubs@rational.com
    Copyright © 1993-2001, Rational Software Corporation. All rights reserved.
    TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS