![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Package Compilation_Units Package Compilation_Units provides access to Ada compilation units (Ada83 LRM 10.1, Ada95 LRM 10.1.1).
The functions in this package allow you to identify and obtain the compilation units belonging to a library, to obtain the properties of those units, to obtain related units, and to transition from a compilation unit to the elements that comprise the unit or from the elements back to the compilation unit.
For more information, click on a topic:
Resources in Package Compilation_UnitsThe subprograms in package Compilation_Units fall into several functional groups, as shown below.
To see detailed reference information, click on the name of a subprogram:
Determining compilation-unit kind and origin:
Kind Origin
Library content:
Compilation_Units Library_Unit Secondary_Unit Enclosing_Library Library_Units Secondary_Units
Corresponding units:
Corresponding_Library_Unit Corresponding_Secondary_Unit
Compilation-unit properties:
Body_Is_Optional Can_Be_Main_Program
Compilation_Command_Line_Options
Compilation_Cpu_Time Is_Equal Is_Nil Object_File_Form Text_File_Form Time_Of_Last_Update Exists Is_Identical Name Object_File_Name Text_File_Name Unique_Name
Compilation-unit attributes:
Attribute_Time Attribute_Values Attribute_Value_Delimiter Has_Attribute
Element gateway and context clause decomposition:
Compilation_Pragmas Enclosing_Compilation_Unit Unit_Declaration Context_Clause_Elements Referenced_Units
Key Concepts for Package Compilation_Units
Package Compilation_Units provides access to Ada compilation units. Information related to the processing of compilation units is provided in the following sections:
- "Terminology for Compilation_Units"
- "Compilation-Unit Locking"
- "Evaluating Compilation-Unit Values"
- "Determining Compilation-Unit Kind"
- "Determining Compilation-Unit Origin"
- "Library Content"
- "Finding Corresponding Units"
- "Compilation-Unit Properties"
- "Compilation-Unit Attributes"
- "Element Gateway and Context Clause Decomposition"
- "Analyzing Subunits"
- "Finding Related Compilation Units"
- "Consistent and Obsolete Compilation Units"
Terminology for Compilation_Units
The ASIS Compilation_Unit type is a handle to, and is intended to correspond closely with, an Ada compilation unit (Ada83 LRM 10.1, Ada95 LRM 10.1.1). A variable of the Compilation_Unit type references, at most, a single Ada compilation unit.
Because of the similarity in definition, it is not often important whether Compilation_Unit or compilation unit is used. In this documentation, however, we use the following definitions:
- compilation unit or unit: refers to the ASIS concept of a compilation unit.
If the distinction between an Ada compilation unit and an ASIS compilation unit is required, the term is qualified. For example, "physical compilation unit" or "Ada library unit."
- Compilation_Unit: appears often as the name of a parameter and a type. In these cases, Compilation_Unit without a qualifier refers to the parameter having that name. The value of the parameter references a compilation unit.
If the distinction between the parameter and type is required, the term is qualified. For example, "Compilation_Unit parameter" or "Compilation_Unit type."
- library unit, secondary unit, and subunit: refer to variables of the Compilation_Unit type that reference Ada library units, Ada secondary units, and subunits.
- physical compilation unit: refers to a compilation unit as represented in a vendor's Ada library implementation.
ASIS is responsible for mapping the physical compilation units into ASIS compilation units. Because of this mapping, ASIS applications are portable between implementations.
For more terminology about compilation units, click on a topic:
Belonging to a Library
As with Ada, a compilation unit belongs to a particular library and ASIS remembers the library that a compilation unit was obtained from. Because of the vendor's underlying program library implementation, or the implementation of the ASIS library concept, it is possible for the same physical compilation unit to belong to multiple libraries.
A compilation unit is usable only while the library it belongs to remains open. An attempt to use a unit after its library has been closed results in the Asis_Inappropriate_Compilation_Unit exception being raised.
Mapping Physical Units to Compilation Units
At the implementation level, the ASIS standard allows two exact copies of the same physical compilation unit information to be treated as the same physical entity. Similarly, library references to same physical unit information can be treated as the same physical entity.
From an ASIS perspective, two compilation units appear physically the same if there are no ASIS operations, or sequence of operations, that can be used to differentiate them.
This allows, for example, an ASIS implementation to treat all instances of Text_Io (whether physically distinct or not), or references to Text_Io contained within libraries, as the same physical compilation unit. The elements that make up the units (see package Elements), and the element-ids derived from the units (see package Ids), will also be identical.
This is not, however, a requirement. Each instance of Text_Io, or any other compilation unit, whether physically distinct or not, can be represented by ASIS as a different compilation unit.
Compilation-Unit Locking
The ASIS standard describes all operations as if the ASIS application had exclusive use of the Ada program libraries.
Whether simultaneous access or updates to Ada program libraries are permitted is defined by the compiler vendor. The effects of simultaneous use, in terms of ASIS, is implementation-defined. There is no requirement for the use of locking or other methods guaranteeing the accuracy and integrity of the information processed by ASIS.
Rational Apex permits simultaneous library access. However, no locks are maintained on any of the data required by ASIS and a simultaneous Ada library update can invalidate data obtained by ASIS resulting in a variety of exceptions (see package Asis, "Package Exceptions"). Because of this, you should avoid updates to your Ada libraries while running ASIS applications.
Closure Evaluation
Rational ASIS uses lazy evaluation, doing work only as required by the ASIS subprogram being invoked. For example, the compilation units contained within a library are not (typically) determined when the library is opened but when a request for compilation-unit information is made. Once this information is obtained, it is not "refreshed" unless the library is closed and then reopened (see package Libraries, "Opening Libraries").
Similarly, the elements that comprise a compilation unit are not accessed until there is a need. When an element is requested, the complete representation of the compilation unit is read into internal structures.
The number of libraries, compilation units, and elements accessible at any one time, is dependent on the amount of memory available.
Evaluating Compilation-Unit Values
The Asis.Compilation_Unit type represents a handle to a physical Ada compilation unit. Because comparisons of handles are not typically meaningful, the type is implemented as private. The relational operators, including the equality operator, are not exported by the ASIS interfaces.
To determine whether two compilation-unit values represent the same physical compilation unit, call Is_Equal. To determine whether two compilation-unit values represent the same physical compilation unit, and have been derived from the same ASIS library, call Is_Identical.
An uninitialized compilation unit variable tests as Is_Nil. An Is_Nil compilation unit Is_Equal and Is_Identical to Asis.Nil_Compilation_Unit.
ASIS also defines a Compilation_Unit_List type; it is an array of Compilation_Units. Arrays of compilation units are required by, and returned from, many of the functions contained in this package. An uninitialized component of a Compilation_Unit_List type tests as Is_Nil. An Is_Nil Compilation_Unit_List is equal to Asis.Nil_Compilation_Unit_List.
Various functions for the manipulation and comparison of Compilation_Unit values, Compilation_Unit_List values, and other types defined in this package, are contained in the nested package Operations.
Determining Compilation-Unit Kind
Each compilation unit has an associated Compilation_Unit_Kinds value that indicates the kind of unit represented. You obtain the kind of a compilation unit with the Kind function. The type includes not only the Ada compilation units defined in Ada83 LRM 10.1, Ada95 LRM 10.1.1, but also values for nonexistent compilation units, unknown (possibly implementation-defined) units, and nil units.
A compilation unit has a nonexistent kind when the unit is known to be required but does not physically exist in the library. For example, a body_stub (Ada83 LRM 10.2, Ada95 LRM 10.1.3) introduces a nonexistent secondary unit (until the subunit is compiled). Entries for nonexistent units might or might not be physically represented in the vendor's Ada library; if they do not exist, the ASIS implementation must deduce their values and return them from the appropriate functions.
You can determine whether a compilation unit is of a nonexistent kind, or is nil, with the Exists function. This function returns False for nonexistent and nil compilation units.
Determining Compilation-Unit Origin
Each compilation unit has an associated Compilation_Unit_Origins value that indicates the origin of the compilation unit. You obtain the origin of a compilation unit with the Origin function.
A compilation unit can either be predefined by Ada (LRM Annex C), supplied by the compiler vendor, or user-defined. Because of insufficient library data, it is possible that all compilation units supplied by the compiler vendor will appear to be user defined compilation units. Similarly, it is possible that all compilation units that have a name identical to an Ada predefined compilation unit will appear to be an Ada predefined compilation unit.
Rational ASIS cannot yet identify compiler defined units; such units appear to be user-defined units.
Under Apex, whether a unit is an Ada predefined unit is based on the name; user-defined units having the same name as an Ada predefined unit will incorrectly be reported as being that Ada predefined unit.
Library Content
ASIS provides five functions that return compilation units by class (library units, secondary units, or both) or by name within a class. These functions are presented in the following table:
To obtain a particular compilation unit, a name must be specified. In the case of a library unit, the name is a simple name ("A"). In the case of a secondary unit, the name is either a simple name or an expanded name ("A.B"); expanded names are used for subunits.
Each compilation unit obtained with these functions, or with any other ASIS function, belongs to a particular library. ASIS maintains this information and you can use the Enclosing_Library function to retrieve it.
Since the Library type is limited private, the result of this function is typically used as a parameter to another function that requires a library value.
Finding Corresponding Units
Compilation units typically come in pairs: a library unit that represents the specification (declaration or instantiation) and a secondary unit that represents the implementation (body). The implementation can alternately be represented as a library unit (Ada83 LRM 10.1, Ada95 LRM 10.1.1) when a subprogram body is compiled and the library does not contain a library unit with the same simple name.
To traverse between secondary units and associated library units, use Corresponding_Library_Unit. If the specified unit:
- Is a secondary unit, the function:
- Returns Asis.Nil_Compilation_Unit if the corresponding library unit does not belong to the specified library
- Returns the corresponding library unit if the unit belongs to the specified library
- Is a library unit and not a secondary unit, the function:
- Returns Asis.Nil_Compilation_Unit if the unit does not belong to the specified library
- Acts as an identify function and returns the library unit if the unit belongs to the specified library
To traverse between library units and associated secondary units, use Corresponding_Secondary_Unit. If the specified unit:
- Is a library unit that exists, the function:
- Returns Asis.Nil_Compilation_Unit if the corresponding library unit does not belong to the specified library
- Returns the corresponding library unit if the unit belongs to the specified library
- Is a secondary unit and not a library unit, the function:
- Returns Asis.Nil_Compilation_Unit if the unit does not belong to the specified library
- Acts as an identify function and returns the secondary unit if the unit belongs to the specified library
Compilation-Unit Properties
Every compilation unit has an associated set of properties. The values assigned to these properties are derived primarily from two sources:
- The name of the source file, the unit name, and the command-line options are typically determined when a compilation is performed and are specified one way or another by the user
- The duration of the compilation, the name of the object file generated, and a number of other property values are typically determined by the compiler
The following sections describe the properties associated with each compilation unit. The properties are grouped into the following sections:
- "Text and Object Files"
- "Compilation-Unit Names"
- "Times and Compilation Options"
- "Miscellaneous Properties"
Text and Object Files
Most Ada compilers accept source code from a text file and many create a named file that contains the object code created by the compilation.
The Text_File_Name function can be used to obtain the name of the text file, or other structure, that contains the source code for a particular compilation unit. Many Ada systems allow multiple compilation units within a single compilation; the file can contain more than just the unit specified.
The Text_File_Form function returns a Text_Io Form parameter suitable for accessing the text file. In many compilation systems a Form parameter is not required to open the text file and so Asis.Nil_Asis_String is returned.
ASIS does not verify that the text file currently exists, that it can be read, or that it contains the same information as when the compilation unit was created.
ASIS provides functions that return the text image of elements and portions of compilation units in the package Text.
The Object_File_Name function can be used to obtain the name of the object file, or other structure, that contains the machine-code result of the compilation of a particular compilation unit. The Object_File_Form function returns a Text_Io Form parameter suitable for accessing the object file.
Whether a distinct object file exists, and whether it can be opened, is implementation-defined. In many cases, the machine-code result of a compilation is placed into several files, or into a single file containing multiple compilations. In these cases, the Object_File_Name function can return Asis.Nil_Asis_String.
Except for the Text_File_Name function, Rational ASIS returns Asis.Nil_Asis_String for these functions. The value returned by the Text_File_Name function is the fully qualified file name of the specified compilation unit.
Compilation-Unit Names
Every compilation unit has an associated name. This name can be a simple name ("A") for a package or subprogram, or an expanded name ("A.B") for a subunit.
You can obtain the name of the compilation unit with the Name function
Conversely, given a name, functions are available that return the library unit or secondary unit with that name. See "Library Content" for more information.
The name of a compilation unit is unique within a particular library, but can be reused in other libraries. ASIS applications that access multiple libraries simultaneously might need to be able to uniquely identify a compilation unit across all Ada libraries.
The Unique_Name function returns a system-wide unique name.The unique name can include the name and parameters of the library, file-system paths, sub-library names, version numbers, unit kind, or any other information that a vendor needs to uniquely identify the compilation unit.
Times and Compilation Options
Many Ada compilers record "management" information about compilations. ASIS provides access to three of these items:
- The Compilation_Command_Line_Options function returns the command-line options used for the compilation of which the specified compilation unit was a part. Rational ASIS does not support command-line options; it always returns Asis.Nil_Asis_String.
- The Compilation_Cpu_Time function returns the amount of CPU time used during the compilation of which the specified compilation unit was a part. Rational ASIS does not support compilation CPU times; it always returns Asis.Nil_Asis_Time.
- The Time_Of_Last_Update function returns the time that the physical compilation unit was last updated in the Ada library. Rational ASIS returns the file system modification time of the file containing the Ada source corresponding to the specified compilation unit.
Miscellaneous Properties
The following additional properties are associated with compilation units:
- Body_Is_Optional: Returns a Boolean value indicating whether a the body is required for the specified compilation unit (Ada83 LRM 7.1, Ada95 LRM 7.1)
- Can_Be_Main_Program: Returns a Boolean value indicating whether the specified compilation unit can be a main program (Ada83 LRM 10.1, Ada95 LRM 10.1.1)
- Exists: Returns a Boolean value indicating whether the specified compilation unit exists
Compilation-Unit Attributes
Compilation-unit attributes are name-value pairs assigned to a compilation unit. Because of Ada library implementation variations not all ASIS implementations support compilation-unit attributes. You can use the Environment.Attributes_Are_Supported function to determine whether the ASIS implementation supports compilation-unit attributes.
How compilation-unit attributes are defined and given values is implementation-defined. Common methods include:
- Start-up files used by the Ada environment or compiler
- Command-line options to the compiler
- Environment variable values
Rational ASIS does not support compilation-unit attributes. All functions related to compilation-unit attributes return either Asis.Nil_Asis_Time or Asis.Nil_Asis_String.
Element Gateway and Context Clause
DecompositionDetailed semantic analysis of compilation units takes place using the elements that comprise the units. Package Compilation_Units provides functions that transition from compilation units to those elements, a function to perform limited analysis on elements that represent the context clauses of a compilation unit, and a function to transition from an element back to a compilation unit.
The following functions are provided to transition from a compilation unit to an element in the compilation unit:
- The Context_Clause_Elements function returns a list of the with and use clauses and, optionally, pragmas that appear in the context clause of a specified compilation unit
- The Compilation_Pragmas function returns a list of the pragmas that apply to the whole of a compilation that contained the specified compilation unit
- The Unit_Declaration function returns the element representing the declaration of a specified compilation unit
The Referenced_Units function can be used to obtain a list containing the simple names referenced in the with and use clauses returned by the Context_Clause_Elements function.
Functions in package Elements can be used to obtain the names, argument associations, and parameters from the argument associations of pragmas returned by the Context_Clause_Elements and Compilation_Pragmas function.
The Enclosing_Compilation_Unit function returns the compilation unit which physically contains a specified element. The function can be given any element that is a part of the unit, whether the element was obtained from a function in the package Compilation_Units or by any other function that returns an element.
Analyzing Subunits
A subunit is used for the separate compilation of the proper body of an Ada program unit declared within another Ada compilation unit. This method of splitting a program permits hierarchical program development (Ada83 LRM 10.2, Ada95 LRM 10.1.3).
Body stubs and subunits are defined by the following syntax:
Ada83 LRM 10.2, Ada95 LRM 10.1.3
body_stub ::=
subprogram_specification is separate;
| package body package_simple_name
is separate;
| task body task_simple_name is separate;subunit ::=
separate (parent_unit_name) proper_bodyCompilation-unit information related to the above constructs can be obtained by calling the subprograms in the following table:
Finding Related Compilation Units
Relationship functions locate compilation units that are related, in some specific fashion, to one or more given compilation units. The possible relationships are:
- Direct supporters and supporters: Compilation units that must be compiled before a particular unit can be compiled. Direct supporters are those mentioned in the unit's with clause. Supporters are those mentioned in the unit's with clause and, recursively, any with clauses in those units.
- Direct dependents and dependents: Compilation units that must be recompiled when a specified unit is recompiled. For example, a package body is a direct dependent of its specification and a subunit is a direct dependent of its parent unit. Dependents are any units that must be compiled when a particular unit is recompiled and, recursively, all units that must be recompiled when those units are recompiled.
- Family and extended family: The family of a compilation unit consists of the specification, body, subunits, and, recursively, all subunits of subunits; the extended family consists of the families of all supporting units. The extended family is also referred to as the program closure of the unit.
The relationships are fully described in the Relation_Kinds type.
There are two sets of functions to provide lists of related compilation units:
Getting a Simple List of Related Units
ASIS provides four functions that return lists of compilation units related to a specified unit in a particular way. The units appearing in the list can be restricted, by specifying a list of candidate units. Often, this candidate list includes all units that belong to a library.
Information Desired Call to Use
Directly supporting units Direct_Supporters
All supporting units Supporters
Directly dependent units Direct_Dependents
All dependent units Dependents
For a description of what units are supporters, direct supporters, dependents, and direct dependents, see "Type Relation_Kinds."
Getting Detailed Relationship Information
While the functions that return lists of related units are easy to use, sometimes you need additional information about the related units, such as whether the related units are inconsistent or form circular dependencies.
Such information is returned by these functions along with the list of related units:
Except in the Elaboration_Order function, you specify the relationship that must exist between the units you specify and those returned by the function. The related units are returned in an Asis.Relationship record.
Asis.Relationship values provide great flexibility but are also somewhat complex to use.
For a description of an Asis.Relationship record, click here.
Asis.Relationship Record Description
The Asis.Relationship record contains four lists of compilation units:
- Existing: Existing compilation units
- Inconsistent: Compilation units that are inconsistent due to recompilation of one or more supporting units
- Missing: Compilation units that are nonexistent but are known to be needed
- Circular: Compilation units that form circular dependencies
All returned compilation-unit values have the same Enclosing_Library.
For more information, click on a topic:
- "The Existing Units List"
- "The Inconsistent Units List"
- "The Missing Units List"
- "The Circular Units List"
The Existing Units List
The content and order of the compilation units in this list depends on the function called.
The compilation-unit values in the list are unique; no duplicates exist and no two units in the list are Is_Equal or Is_Identical.
The Inconsistent Units List
The inconsistent units list contains pairs or units. Each pair includes an inconsistent unit followed by a unit causing the inconsistency.
Inconsistent units exist in the library, but are obsolete due to the recompilation of one or more supporting units (Ada83 LRM 10.3, Ada95 LRM 10.3).
The list is returned in one of two forms: minimal or maximal. You can determine which by calling Environment.Minimal_Inconsistent_Units. In a minimal list, only the inconsistent direct supporters are returned; each set of inconsistencies is reported only once. In a maximal list, all inconsistent supporters are returned, and thus, each chain of inconsistencies is reported each time it occurs.
See "Type Relation_Kinds" for more information on units that constitute direct supporters and supporters.
For example: Given four units such that A withs B, B withs C, and C withs D, and that D is then recompiled, thus making A, B, and C obsolete.
The returned minimal list is (A B B C C D).
From this list it can be determined that:
- A is inconsistent because its supporter B is obsolete
- B is inconsistent because its supporter C is obsolete
- C is inconsistent because D has been recompiled
The returned maximal list is (A B A C A D B C B D C D).
From the list it can be determined that:
- A is inconsistent because its supporters B and C are obsolete, and D has been recompiled
- B is inconsistent because its supporter C is obsolete, and D has been recompiled
- C is inconsistent because D has been recompiled
The Missing Units List
The missing units list contains pairs of units. Each pair includes an existing unit followed by a missing related unit.
A missing unit is one that is known to be required to form the program closure of the units. The unit has a known name, and has a Compilation_Unit_Kinds of A_Nonexistent_Library_Unit or A_Nonexistent_Secondary_Unit. Package bodies that are optional (See "Function Body_Is_Optional"), and that do not exist, are not considered missing.
A unit is reported as missing only if Ada requires that the missing unit be created before an executable can be created. Missing units include:
- Package or subprogram specifications without corresponding bodies
- Package bodies with missing specifications
- Missing subunits
- Compilation subunits with missing parent units
For example: Given that three units such that B and C are part of the extended family of A, that the Compilation_Unit_Kinds of B is A_Nonexistent_Library_Unit, and that the Compilation_Unit_Kinds of C is A_Nonexistent_Secondary_Unit, the returned missing units list is (A B A C).
From the list it can be determined that:
- A is missing its supporter B
- A is missing a related secondary unit C. Depending on the Ada Compilation_Unit_Kinds of A, C might be A's body or some subunit of A
The Circular Units List
The circular units list contains pairs of units. Each pair includes a unit followed by a supporting unit. Multiple pairs form a set and each set describes a circle of dependencies or circularity. A circularity is established when a unit's supporting unit is equal to the first unit of the set.
The list can contain multiple circularities. The ordering of the circularities, and the first unit that appears in a circularity, is implementation-defined.
An individual compilation unit can be part of multiple circularities. However, for any one circularity, a particular compilation unit is only reported once.
The list never contains a compilation unit with a Compilation_Unit_Kinds of A_Nonexistent_Library_Unit or A_Nonexistent_Secondary_Unit.
For example: Given seven units such that A depends on B, B depends on C, C depends on A; and that D depends on E, E depends on F, F depends on G, and G depends on D.
The returned circular units list is (A B B C C A D E E F F G G D).
From the list it can be determined that:
- The units A, B, and C form a circularity
- The units D, E, F, and G form a circularity
Consistent and Obsolete Compilation Units
At any given time, and within a specific library, a compilation unit is either consistent or obsolete.
A consistent unit is one that can be linked into an executable. An obsolete unit is one that has had a supporting unit, or other required unit, recompiled or removed, and that cannot be linked into an executable.
In order for a unit to be consistent, the unit's specification, body (if required), subunits, and all supporters of the unit must be consistent.
The Is_Consistent function returns True when a specified compilation unit is consistent and False when the unit is obsolete.
The Is_Obsolete function return True when a specified compilation unit is obsolete and True when the unit is consistent.
Not every unit that is consistent can be a main unit. For example, a package can be consistent but cannot be a main unit. You can determine whether a specified compilation unit can be a main unit with the Can_Be_Main_Program function; which returns True if the specified compilation unit meets a particular Ada vendor's implementation requirements for a main program.
Rational Software Corporation
http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2001, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |