ASIS-for-GNAT User's Guide: ASIS Context

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 4. ASIS `Context`

From an ASIS application viewpoint we may view an ASIS `Context` as a set of ASIS `Compilation_Unit`s accessible through ASIS queries. The common ASIS implementation technique is to base an implementation of an ASIS `Context` on some persistent data structures created by the underlying Ada compiler when compiling Ada compilation units maintained by this compiler. An ASIS `Context` can only contain compilable (that is, legal) compilation units.

> 4.1 ASIS `Context` and Tree Files |  |
> 4.2 Creating Tree Files for Use by ASIS |  |
> 4.3 Different Ways to Define an ASIS `Context` in ASIS-for-GNAT |  |
> 4.4 Consistency Problems |  |
> 4.5 Processing Several `Context`s at a Time |  |
> 4.6 Using ASIS with a cross-compiler |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.1 ASIS `Context` and Tree Files

The ASIS-for-GNAT implementation is based on tree output files, or, simply, tree files. When called with the special option ``-gnatt'`, GNAT creates and outputs a tree file if no error was detected during the compilation. The tree file is a kind of snapshot of the compiler internal data structures (basically, of the Abstract Syntax Tree (AST)) at the end of the successful compilation. ASIS then inputs tree files and recreates in its internal data structures exactly the same picture the compiler had at the end of the corresponding successful compilation.

An important consequence of the GNAT source-based compilation model is that the AST contains full information not only about the unit being compiled, but also about all the units upon which this unit depends semantically. Therefore, having read a tree file, ASIS can in general provide information about more than one unit. By processing a tree file, a tool can provide information about the unit for which this tree was created and about all the units upon which it depends semantically. However, to process several units, ASIS sometimes has to change the tree being processed (in particular, this occurs when an application switches between units which do not semantically depend on each other, for example, two package bodies). Therefore, in the course of an ASIS application, ASIS may read different tree files and it may read the same tree file more then once.

The name of a tree file is obtained from the name of the source file being compiled by replacing its suffix with '``.adt'`'. For example, the tree file for ``foo.adb'` is named ``foo.adt'`.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.2 Creating Tree Files for Use by ASIS

> 4.2.1 Creating Trees for Data Decomposition Annex |  |

Neither `gcc` nor `gnatmake` will create tree files automatically when you are working with your Ada program. It is your responsibility as a user of an ASIS application to create a set of tree files that correctly reflect the set of the Ada components to be processed by the ASIS application, as well as to maintain the consistency of the trees and the related source files.

To create a tree file for a given source file, you need to compile the corresponding source file with the ``-gnatct'` option.

    $ gcc -c -gnatct foo.adb

will produce ``foo.adt'`, provided that ``foo.adb'` contains the source of a legal Ada compilation unit. Actially, the ``-gnatct'` is an ASIS-specific combination of two compileation options, ``-gnatt'` and ``-gnatc'`. The ``-gnatt'` option generates a tree file, and ``-gnatc'` turns off AST expansion. ASIS needs tree files created without AST expansion, whereas to create an object file, GNAT needs an expanded AST. Therefore it is impossible for one compilation command to to produce both a tree file and an object file for a given source file.

The following points are important to remember when generating and dealing with tree files:

- ASIS-for-GNAT is distributed for a particular version of GNAT. All the trees to be processed by an ASIS application should be generated by this specific version of the compiler.

- A tree file is not created if an error has been detected during the compilation.

- In contrast with object files, a tree file may be generated for any legal Ada compilation unit, including a library package declaration requiring a body or a subunit.

- A set of tree files processed by an ASIS application may be inconsistent; for example, two tree files may have been created with different versions of the source of the same unit. This will lead to inconsistencies in the corresponding ASIS `Context`. See 4.4 Consistency Problems, for more details.

- Do not move tree, object or source files among directories in the underlying file system! ASIS might assume an inconsistency between tree and source files when opening a `Context`, or you may get wrong results when querying the source or object file for a given ASIS `Compilation_Unit`.

- When invoking `gcc` or `gnatmake` to create tree files, make sure that all file and directory names containing relative path information start from ``./'` or ``../'` (``.\'` and ``..\'` respectively in MS Windows). That is, to create a tree file for the source file ``foo.adb'` located in the inner directory named ``inner'`, you should invoke gcc (assuming an MS Windows platform) as:

      $ gcc -c -gnatct  .\inner\foo.adb

  but not as

      $ gcc -c -gnatct inner\foo.ads

  Otherwise ASIS will not perform correctly.

- When reading in a tree file, ASIS checks that this tree file was created with the ``-gnatc'` option, and it does not accept trees created without this option.

- If called to create a tree, GNAT does not destroy an ``ALI'` file if the ``ALI'` file already exists for the unit being compiled and if this ``ALI'` file is up-to-date. Moreover, GNAT may place some information from the existing ``ALI'` file into the tree file. If you would like to have both object and tree files for your program, first create the object files, and then the tree files.

- There is only one extension for tree files, namely ``.adt'`, whereas the standard GNAT name convention for the Ada source files uses different extensions for a spec (``.ads'`) and for a body (``.adb'`). This means that if you first generate a tree for a unit's body:

      $ gcc -c -gnatct foo.adb

  and then generate the tree for the corresponding spec:

      $ gcc -c -gnatct foo.ads

  then the tree file ``foo.adt'` will be created twice: first for the body, and then for the spec. The tree for the spec will override the tree for the body, and the information about the body will be lost for ASIS. If you first create the tree for a spec, and then for a body, the second tree will also override the first one, but no information will be lost for ASIS, because the tree for a body contains full information about the corresponding spec.

  To avoid losing information when creating trees for a set of Ada sources, try to use `gnatmake` whenever possible (see 8.4 Using `gnatmake` to Create Tree Files for more details). Otherwise, first create trees for specs and then for bodies:

      $ gcc -c -gnatct *.ads
      $ gcc -c -gnatct *.adb

- Reading tree files is a time-consuming operation. Try to minimize the number of tree files to be processed by your application, and try to avoid unnecessary tree swappings. (See 8. How to Build Efficient ASIS Applications, for some tips).

- It is possible to create tree files "on the fly", as part of the processing of the ASIS queries that obtain units from a `Context`. In this case there is no need to create tree files before running an ASIS application using the corresponding `Context` mode. Note that this possibility goes beyond the ASIS Standard, and there are some limitations imposed on some ASIS queries, but this functionality may be useful for ASIS tools that process only one `Compilation_Unit` at a time. See the ASIS-for-GNAT Reference Manual for more details.

Note that between opening and closing a `Context`, an ASIS application should not change its working directory; otherwise execution of the application is erroneous.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.2.1 Creating Trees for Data Decomposition Annex

Using the ASIS Data Decomposition Annex (DDA) does not require anything special to be done by an ASIS user, with one exception. The implementation of the ASIS DDA is based on some special annotations added by the compiler to the trees used by ASIS. An ASIS user should be aware of the fact that trees created for subunits do not have this special annotation. Therefore ASIS DDA queries do not work correctly on trees created for subunits (and these queries might not work correctly if a set of tree files making up a `Context` contains a tree created for a subunit).

Thus, when working with the ASIS DDA, you should avoid creating separate trees for subunits. Actually, this is not a limitation: to create a tree for a subunit, you should also have the source of the parent body available. If in this situation you create the tree for the parent body, it will contain the full information (including DDA-specific annotation) for all the subunits that are present. From the other side, a tree created for a single subunit has to contain information about the parent body, so it has about the same size as the tree for the parent body.

The best way to create trees when using ASIS DDA is to use `gnatmake`: it will never create separate trees for subunits.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.3 Different Ways to Define an ASIS `Context` in ASIS-for-GNAT

The `Asis.Ada_Environments.Associate` query that defines a `Context` has the following spec:

    procedure Associate
                 (The_Context : in out Asis.Context;
                  Name        : in Wide_String;
                  Parameters  : in Wide_String := Default_Parameters);

In ASIS-for-GNAT, `Name` does not have any special meaning, and the properties of the `Context` are set by "options" specified in the `Parameters` string:

- How to define a set of tree files making up the `Context` (``-C'` options);

- How to deal with tree files when opening a `Context` and when processing ASIS queries (``-F'` options);

- How to process the source files during the consistency check when opening the `Context` (``-S'` options):

- The search path for tree files making up the `Context` (``-T'` options);

- The search path for source files used for calling GNAT to create a tree file "on the fly" (``-I'` options);

The association parameters may (and in some cases must) also contain the names of tree files or directories making up search paths for tree and/or source files. Below is the overview of the `Context` association parameters in ASIS-for-GNAT; for full details refer to the ASIS-for-GNAT Reference Manual.

> 4.3.1 Defining a set of tree files making up a `Context` |  |
> 4.3.2 Dealing with tree files when opening a `Context` and processing ASIS queries |  |
> 4.3.3 Processing source files during the consistency check |  |
> 4.3.4 Setting search paths |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.3.1 Defining a set of tree files making up a `Context`

The following options are available:

``-C1'`
  "One tree" `Context`, defining a `Context` comprising a single tree file; this tree file name should be given explicitly in the `Parameters` string.

``-CN'`
  "N-trees" `Context`, defining a `Context` comprising a set of tree files; the names of the tree files making up the `Context` should be given explicitly in the `Parameters` string.

``-CA'`
  "All trees" `Context`, defining a `Context` comprising all the tree files in the tree search path given in the same `Parameters` string; if this option is set together with ``-FM'` option, ASIS can also create new tree files "on the fly" when processing queries yielding ASIS `Compilation_Unit`s.

The default option is ``-CA'`.

Note that for ``-C1'`, the `Parameters` string should contain the name of exactly one tree file. Moreover, if during the opening of such a `Context` this tree file could not be successfully read in because of any reason, the `Asis_Failed` exception is raised.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.3.2 Dealing with tree files when opening a `Context` and processing ASIS queries

The following options are available:

``-FT'`
  Only pre-created trees are used, no tree file can be created by ASIS.

``-FS'`
  All the trees considered as making up a given `Context` are created "on the fly", whether or not the corresponding tree file already exists; once created, a tree file may then be reused while the `Context` remains open. This option can be set only with ``-CA'` option.

``-FM'`
  Mixed approach: if a needed tree does not exist, the attempt to create it "on the fly" is made. This option can only be set with ``-CA'` option.

The default option is ``-FT'`.

Note that the ``-FS'` and ``-FM'` options go beyond the scope of the official ASIS standard. They may be useful for some ASIS applications with specific requirements for defining and processing an ASIS `Context`, but in each case the ramifications of using such non-standard options should be carefully considered. See the ASIS-for-GNAT Reference Manual for a detailed description of these option.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.3.3 Processing source files during the consistency check

When ASIS reads a tree fule as a part of opening a `Context`, it checks, that the tree is consistent with the source files of the `Compilation_Unit`s represented by this tree.

The following options are available to control this check:

``-SA'`
  Source files for all the `Compilation_Unit`s belonging to the `Context` (except the predefined `Standard` package) have to be available, and all of them are taken into account for consistency checks when opening the `Context`.

``-SE'`
  Only existing source files for all the `Compilation_Unit`s belonging to the `Context` are taken into account for consistency checks when opening the `Context`.

``-SN'`
  None of the source files from the underlying file system are taken into account when checking the consistency of the set of tree files making up a `Context` (that is, no check is made).

The default option is ``-SA'`. See 4.4 Consistency Problems, concerning consistency issues in ASIS-for-GNAT.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.3.4 Setting search paths

Using the ``-I'`, ``-gnatec'` and ``-gnatA'` options for defining an ASIS `Context` is similar to using the same optionsfor `gcc`. The ``-T'` option is used in the same way, for tree files. For full details about the ``-T'` and ``-I'` options, refer to the ASIS-for-GNAT Reference Manual. Note that the ``-T'` option is used only to locate existing tree files, and it has no effect for ``-FS'` `Context`s. On the other hand, the ``-I'` option is used only to construct a set of arguments when ASIS calls GNAT to create a tree file "on the fly"; it has no effect for ``-FT'` `Context`s, and it cannot be used to tell ASIS where it should look for source files for ASIS `Compilation_Unit`s.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.4 Consistency Problems

> 4.4.1 Inconsistent versions of ASIS and GNAT |  |
> 4.4.2 Consistency of a set of tree and source files |  |

There are two different kinds of consistency problems existing for ASIS-for-GNAT, and both of them can show up when opening an ASIS `Context`.

First, a tree file may have been created by another version of GNAT (see the README file about the coordination between the GNAT and ASIS-for-GNAT versions). This means that there is an ASIS-for-GNAT installation problem.

Second, the tree files may be inconsistent with the existing source files or with each other.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.4.1 Inconsistent versions of ASIS and GNAT

When ASIS-for-GNAT reads a tree file created by the version of the compiler for which a given version of ASIS-for-GNAT is not supposed to be used, ASIS treats the situation as an ASIS-for-GNAT installation problem and raises `Program_Error` with a corresponding exception message. In this case, `Program_Error` is not caught by any ASIS query, and it propagates outside ASIS.(3) Note that the real cause may be an old tree file you have forgotten to remove when reinstalling ASIS-for-GNAT. This is also considered an installation error.

ASIS uses the tree files created by the GNAT compiler installed on your machine, and the ASIS implementation includes some compiler components to define and to get access to the corresponding data structures. Therefore, the version of the GNAT compiler installed on your machine and the version of the GNAT compiler whose sources are used as a part of the ASIS implementation should be close enough to define the same data structures. We do not require these versions to be exactly the same, and, by default, when ASIS reads a tree file it only checks for significant differences. That is, it will accept tree files from previous versions of GNAT as long as it is possible for such files to be read. In theory, this check is not 100% safe; that is, a tree created by one version of GNAT might not be correctly processed by ASIS built with GNAT sources taken from another version. But in practice this situation is extremely unlikely.

An ASIS application may set a strong GNAT version check by providing the ``-vs'` parameter for the ASIS `Initialize` procedure, see ASIS-for-GNAT Reference Manual for more details. If the strong version check is set, then only a tree created by exactly the same version of GNAT whose sources are used as a part of the ASIS implementation can be successfully read in, and `Program_Error` will be raised otherwise.

Be careful when using a `when others` exception handler in your ASIS application: do not use it just to catch non-ASIS exceptions and to ignore them without any analysis.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 4.4.2 Consistency of a set of tree and source files

When processing a set of more then one tree file making up the same `Context`, ASIS may face a consistency problem. A set of tree files is inconsistent if it contains two trees representing the same compilation unit, and these trees were created with different versions of the source of this unit. A tree file is inconsistent with a source of a unit represented by this tree if the source file currently available for the unit differs from the source used to create the tree file.

When opening a `Context` (via the `Asis.Ada_Environments.Open` query), ASIS does the following checks for all the tree files making up the `Context`:

- If the ``-SA'` option is set for the `Context`, ASIS checks that for every `Compilation_Unit` represented by a tree, the source file is available and it is the same as the source file used to create the tree (a tree file contains references to all the source files used to create this tree file).

- If the ``-SE'` option is set for the `Context`, then if for a `Compilation_Unit` represented by a tree a source file is available, ASIS checks that this source is the same as the source used to create the tree. If for a `Compilation_Unit` belonging to a `Context` a source file is not available, ASIS checks that all the tree files containing this unit were created with the same version of the source of this unit.

- If the ``-SN'` option is set for the `Context`, ASIS checks that all the trees were created from the same versions of the sources involved. It does not check if any of these sources is available or if this is the same version of the source that has been used to create the tree files.

If any of these checks fail, the `Asis_Failed` exception is raised as a result of opening a `Context`. If the `Context` has been successfully opened, you are guaranteed that ASIS will process only consistent sets of tree and source files until the `Context` is closed (provided that this set is not changed by some non-ASIS actions).

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.5 Processing Several `Context`s at a Time

If your application processes more then one open `Context` at a time, and if at least one of the `Context`s is defined with an ``-FS'` or ``-FM'` option, be aware that all the tree files created by ASIS "on the fly" are placed in the current directory. Therefore, to be on the safe side when processing several opened `Context`s at a time, an ASIS application should have at most one `Context` defined with an ``-FS'` or ``-FM'` option. If the application has such a `Context`, all the other `Context`s should not use tree files located in the current directory.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 4.6 Using ASIS with a cross-compiler

If you would like to use ASIS with a cross-compiler, you should use this cross-compiler to create the tree files to be used for the ASIS `Context` defined with ``-FS'` option. If you would like to use trees created on the fly (that is, to use a `Context` defined with the ``-FS'` or ``-FM'` option), you have to tell ASIS which compiler should be called to perform this function. There are two ways to do this.

- You can use the ``--GCC'` option in the `Context` definition to specify explicitly the name of the command to be called to create the trees on the fly

- You may use the prefix of the name of your ASIS tool to indicate the name of the command to be used to call the compiler. If the name of your tool contains a hyphen character "`-`", for example `some_specific-foo`, then ASIS will try to call the command with the name created as a concatenation of the tool name prefix preceding the rightmost hyphen, the hyphen character itself, and `gcc`. For example, for `some_specific-foo`, ASIS will try to call `some_specific-gcc` to create the tree file.

The algorithm for defining the name of the command to be used to create trees on the fly is as follows. If the ``--GCC'` option is used in the `Context` definition and if the name that is the parameter of this option denotes some executable existing in the path, this executable is used. Otherwise ASIS tries to define the name of the executable from the name of the ASIS application. If the corresponding executable exists on the path, it is used. Otherwise the standard `gcc` installation is used.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by GNAT Mailserver on November, 5 2011 using texi2html