AUGUST 1995

GNAT DOCUMENTS INTRO

Copyright (c) 1992,1993,1994 NYU, All Rights Reserved

GNAT is free software; you can redistribute it and/or modify it under terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNAT is distributed in the hope that it will be useful, but but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT- ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNAT; see file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.


Contents


Running GNAT

Three steps are needed to create an executable file from an Ada source file: it must first be compiled, it then must go through the gnat binder, and then all appropriate object files it needs are then linked together to produce an executable. A tool has been provided to combine the last 2 steps into one command.

A small example

The file hello.adb contains the source of our modest version of the "Hello World" program. Other components of this program are contained in the GNAT Runtime Library (RTL). You needn't mention the files containing these other components but you can find the sources (g-io.ads, g-io.adb, and a-cio.c) in the RTL source directory (described below).

The file hello.adb can be found in the current distribution in the examples directory. Here are the commands for building and running it (Since this documentation is for systems running Unix and also for those running DOS, IBM OS/2 2.x and Windows NT, in places where the instructions differ a prefix "Unix:" or "OS/2:" or "DOS:" indicates what is relevant for each system):

gcc -c hello.adb Unix: gnatbl -o hello hello.ali OS/2: gnatbl -o hello.exe hello.ali DOS : gnatbl -o hello.exe hello.ali

create the executable called "hello" or "hello.exe" in your current directory.

In the example above, gnatbl calls the binder and creates a file b_hello.c which contains among things the calls to the necessary elaboration procedures. b_hello is then compiled and linked with all the other object files. After the link is completed, both b_hello.c and b_hello.o (b_hello.obj) are removed by default. If -g was specified on the call to gnatbl, the two files are not removed since it is assumed they might be required for debugging.

(Note that the operation of the DOS version of gnatbl changed with GNAT 2.00. Previously the file hello (no extension) was created. The extra step of running coff2exe has now been incorporated into gnatbl. In order to lessen the proliferation of normally unused files, the extensionless coff version is automatically deleted. If you need it, for example for debugging, it can be recreated by running exe2coff.)

Typing

hello

will allow you to verify that the system is alive and willing to enter into a primitive dialogue.

The gcc switch -c indicates that we only want to compile, not link. The gnatbl step produces the executable by means of calling the GNAT binder, compiling its output, and calling gcc with the needed object files and libraries to link the executable. The -o switch is passed to the linker to name the resulting executable file.

As the example suggests, the gcc command recognizes the extension .adb as an indication of an Ada source file and calls the appropriate programs to generate an object file (hello.o or hello.obj) and an Ada Library Information (ALI) file (hello.ali) containing dependency information used by the binder to verify consistency and determine order of elaboration. The "ali" extension is recognized by gnatbl as the ALI file of the main procedure or function, and gnatbl uses it to create a file called the bind file, and to gather all the needed object files for linking.

Gnatbl

gnatbl

[-o exec_name]
[-v]                  -- verbose mode
[-g]                  -- include debugging information
[-linkonly]           -- doesn't call the binder
[-gnatbind name]      -- full name for gnatbind
[-gnatlink name]      -- full name for the linker (gcc)
[list of objects]     -- non Ada binaries
[linker options]      -- other options for the linker

The program gnatbl provides for binding and linking using the GNAT RTL. Gnatbl calls gnatbind which creates a C file (b_hello.c in our simple example) containing calls to all of the elaboration routines. Gnatbind is described more fully below. The typical use of GNAT (currently -- in the presence of gnatbl) to construct a program consisting of a mix of Ada and C sources is to compile all of the sources using "gcc -c" to generate object (.o or .obj) files. In the case of Ada sources, ALI files with the extension .ali are also produced. Then gnatbl is used to construct the executable. All arguments to gnatbl are simply passed through to gcc to link the objects together, with the exception of a file name with the .ali extension. Such an argument is presumed to be the ALI file of the main procedure of the program. When gnatbl sees a .ali file it calls gnatbind to create the bind file, compiles the bind file, extracts a list of needed object files from the bind file, and replaces the .ali argument with the a list of object files (the result of compiling the bind file and the list extracted from the bind file) in the gcc command it makes. As a quick illustration consider a program comprising main.adb, foo.adb and bar.c. After compiling these sources into object files, the command (under Unix)

gnatbl -o main main.ali bar.o

would cause gnatbl to:

  call "gnatbind main.ali", generating b_main.c
  call "gcc -c b_main.c"
  call "gcc -o main b_main.o main.o foo.o bar.o (+ gnat library args)"

In the last step, the "main.ali" argument has been replaced by all of the object files needed by main (the binder file, main itself, and foo -- upon which main depends). All other gnatbl arguments are passed through unchanged to gcc. Finally a -l and a -L argument are added to the end of the gcc call to point it to the gnatlib library. (Under OS/2, the command line and behavior of gnatbl is similar.) (Under DOS, the additional step of calling "coff2exe main" is done.)

A current limitation of gnatbl is that the main program must be Ada and that it depends on all of the necessary library units. In other words, there can be only one .ali file listed and it must be the main program. This particularly restricts gnatbl's use when a routine written in another language calls an Ada subprogram which is not also called from Ada.

[-o exec_name]

Under unix if the -o option is omitted the executable is called the name of the main unit. So "gnatbl try.ali" will create an executable called try. Under DOS and OS/2 it would create an exectuable called try.exe.

[-v]

The verbose option is most useful when the user wants to see what set of object files that are being used in the link step.

[-g]

The option to include debugging information causes the C bind file, i.e. b_foo.c, to be compiled with -g. In addition the b_foo.c and b_foo.o file will not be removed (without -g the default action is to remove the binder generated files). Additionally on DOS, it causes the COFF output file to be preserved and on Windows NT causes extra debugging information to be linked into the executable.

[-linkonly]

-- doesn't call the binder

Do not call gnatbind but rather use the bind file that has already been generated. This option is useful if the user wants to pass options to gnatbind which is not directly possible with gnatbl. The sequence would be:

  
  gnatbind binder_options file.ali
  gnatbl -linkonly file.ali

[-gnatbind name]

-- full name for the linker (gcc)

Using the Binder

In the "Hello World" example, if gnatbl were not used, the second step would have been to call the binder directly with the command:

       gnatbind hello.ali

This command generates a file named b_hello.c which needs to be compiled and linked together with hello.o (or hello.obj). The file b_hello.c contains a program which contains calls to all of the elaboration routines of all of the units required by the subprogram whose ALI file is given on the command line. Then it calls the Ada subprogram itself. By default, this C function is called "main". (For other options, see the section on options below.) The program gnatbind works by recursively processing the ALI files of all of the units that are needed. These ALI files are found using the search path mechanism described below. Since object and ALI files are always kept together, the object files needed for linking are found at the same time and are listed in a comment at the end of the bind file. This is where gnatbl finds the list of object files required.

The options of gnatbind are summarized below. Normally gnatbind is called by default from gnatbl. If you want to invoke gnatbind explicitly with some of the options mentioned below, your invoke gnatbind with the options on the ali file and then invoke gnatbl with the -linkonly option so that the binder will not be called again.

Usage: gnatbind switches lfile

  -b      Generate brief messages to stderr even if verbose mode set
  -c      Check only, no generation of binder output file
  -e      Output complete list of elaboration order dependencies
  -Idir   Specify library and source files search path
  -l      Output chosen elaboration order
  -mnnn   Limit number of detected errors to nnn (1-999)
  -n      No main program
  -o file give the Output name (default is b_xxx.c) 
  -s      Require all source files to be present
  -t      Ignore time stamp errors
  -v      Verbose mode. Error messages,header, summary output to stdout-wx     Warning mode. (x=s/e for suppress/treat as error)
  -x      Exclude source files (check object consistency only)
  lfile   Library file names

Using gcc to compile

In the usual procedures for using GNAT, Ada source programs are compiled into object files using the driver program 'gcc' with the option '-c' (compile only). Gcc recognizes the ada filename extensions .ads and .adb (discussed more thoroughly below) and calls the actual compiler, 'gnat1' to compile the source file. Gcc has many switches which you will need your gcc documentation to learn about. In addition, gcc passes gnat1 switches through to gnat1. These (with a couple of exceptional abbreviations) are spelled on the gcc command line by "-gnatXXX". Thus

        gcc -c -gnata foo.adb

causes gcc to call the Ada compiler gnat1 with gnat1's '-a' switch; the '-c' is understood by gcc to mean that it is done after producing the object file (it won't try to link). The output of this command is the object and ALI files for foo.

In the future, the gcc and the GNAT-specific switches will be more fully integrated. At this time, there is the "-gnatXXX" mechanism for passing switches through to gnat1. Some of these switches are described in specific sections of this document; a more complete discussion is in the options section below. Note that gcc passes these switches to gnat1 with the "gnat" prefix, where it is stripped off. This means that when gnat1 is executed the "gnat" prefix is required; but in all of the documentation the switches are described without the prefix.

Three gcc options are translated to gnat1 arguments when seen on the gcc command line. These are "k8" (file name limit), "83" (Ada83 syntax) and "w" (warning mode). Thus, the following commands are identical:

     gcc -ws -k8 file.adb
     gcc -gnatws -gnatk8 file.adb

i.e., both of them suppress warning messages from GNAT, and expect file names to be 8 characters long at most (see below for usage).

In addition, the following gcc switches are passed through and recognized by gnat1 with the same effects as in cc1 (as for C files): "-g*" (other than "-gnat*"); "-O*"; "-p"; "-pg"; "-f*"; "-d*"; "-S". For example,

 

      gcc -c -g math.adb

will generate debugging information that can be used with the debugger gdb (see below).

The other flags that control gcc itself (notably -B and -c) and the assembler, behave as usual. Please consult your GCC documentation for details.

Using gcc for syntax checking

The current release of GNAT implements the full Ada 95 grammar as described in annotated Ada Reference Manual for Ada 95 (AARM, version 5.95). We think the parser gives excellent error messages (try it and see!) and is pleasantly fast (again, try and see!).

To run GNAT in syntax checking only mode, use the switch "s", that is to say, enter the command:

	gcc -c -gnats file

where file is the name of the file to be checked. (Under Unix, wild cards can be used to check a set of files, as in *.adb.) Note that the 'compile only' flag has to be given for gcc, as well as the 'syntax only' flag, which is GNAT-specific. We will remove this redundancy in subsequent releases.

The syntax checker is complete, and quite robust. If you manage to blow it up, or if it fails to diagnose an error, or lets a syntactically invalid program through, definitely let us know (see separate section below). If you find an error message you think could be improved, let us know as well. Of course, no compiler can ever have perfect error messages (that would involve mind reading), but we are committed to doing as well as possible, so we are happy to get suggestions in this department.

Using gcc for semantics checking

The command to perform semantic checking is:

	gcc -c -gnatc file

To operate in this mode, since WITH'ed files must be accessed, the GNAT semantic restrictions on file structuring must be followed:

Note that the use of search paths and the flexibility of the File name rules will increase in the future as described in the sections on these facilities.

The coverage of semantic checks is still incomplete, and the system is not very robust in the presence of semantically illegal programs. Nevertheless, this release supports many more features of Ada 95 than the previous one, and semantic checking is correspondingly more extensive.

Here, use of the 'report errors immediately' switch ("-e", i.e., "-gnate" on the gcc command line) will help pinpoint the source of the trouble if the system misbehaves.

Search paths and the Run Time Library (RTL)

With GNAT's source based library system, the compiler must be able to find source files for units that are needed by the unit being compiled. Also, during binding, ALI files are needed to do the required checking of compilation order and to determine elaboration requirements. Botyh the compiler and binder use search paths to locate the files that they need. The rules are straightforward.

The compiler compiles one source file whose name must be givien explicitly on the command line (i.e. there is no searching done for this file). All other source files that are needed (the most common being the specs of WITH'ed units) are found by looking in the following directories:

The compiler outputs its object files and ALI files in the current working directory (NOTE: the object file can be redirected with the -o option; however, gcc and gnat1 have not been coordinated on this so the ALI file will not go to the right place -- DON'T DO THIS).

The binder takes the name of an ALI file as its argument and needs to locate other ALI files in its recursive processing. These are found in the following directories:

If the binder is requested to locate source files (for time stamp verification) the source files are located using the mechanism for source files described above, that is the curent working directory is searched first, then the directories specified with -I, then those in ADA_INCLUDE_PATH, etc. The only difference being that because no source file is specified to the binder, the first directory which is searched for sources is the current working directory.

The binder generates the bind file (a C language source file) in the current working directory.

The packages Ada, System, and Interfaces and their children make up the GNAT Run Time Library, together with the simple System.IO package used in the "Hello World" example. The sources for these units are needed by the compiler and are kept together in one directory (not all of the bodies are needed, but all of the sources are kept together anyway). The ALI files and object files generated by compiling the RTL are needed by the binder and the linker, and are kept together in one directory (typically different from the directory containing the sources). In a normal installation, the user will not need to specify these directory names when compiling or binding (or binding and linking with gnatbl -- though the call to the linker contains explicit pathnames of the object files). Either the environment variables (OS/2) or the builtin defaults will cause these files to be found.

Besides the assistance in using the RTL, a major use of search paths is in compiling sources from multiple directories. This can make development environments much more flexible.

The user might use the search paths to experiment with alternative RTLs, or to create new libraries (not the technical Ada meaning here).

Options

Error reporting, as well as other aspects of the behavior of the system, are controlled by the following flags. All of these must be entered with the prefix '-gnat'. For example, '-gnatv83' specifies verbose mode for output, and Ada83 syntax checking.

a
Assertions enabled. Pragma Assert and Debug to be activated.
b
Generate brief messages to stderr even if verbose mode set.
c
Check syntax and semantics only (no code generation attempted)
e
Error messages generated immediately, not saved up till end
f
Full errors. Normally only the first error on each line is reported.
g
GNAT style checks enabled - col alignment, spacing, capitalization. See any source file for examples.
i?
(?=1/2/3/4/p/f/n/w) default = i1 (Latin-1) 1-4 = Latin 1-4, p = IBM PC, f/n = full/no, upper w=wide_character
j?
Wide character encoding method (?=n/h/u/s/e)
knnn
Limit file names to k characters (k = krunch)
l
Output full source listing with embedded error messages
mnnn
Limit number of detected errors to nnn (1-999)
n
No inlining of subprograms (ignore pragma Inline)
o
Enable integer overflow checking using range checks
p
Automatic suppression of all run-time checks mentioned in LRM 11.7
q
Don't quit, try semantics, even if parse errors
r
Reference manual column layout required
s
Syntax check only
t
Tree output file to be generated
u
List units for this compilation
v
Verbose mode. Full error output with source lines to stdout.
w?
Warning mode. s = suppress, e = treat as error
x?
Cross-reference level and switches (?=1/2/3/4/5/9/b/s)
z?
Distribution stub generation (r/s for receiver/sender stubs)
83
Enforce Ada 83 restrictions
sfile
Source file names (wild cards allowed for multiple files)

Some of these options are explained in more detail elsewhere in this document. For full information, refer to file usage.adb in this distribution.

For first-time users, and for first-compilation attempts, the following mode of operation is recommended: gcc -c -gnatc lets_try_this.adb

gnatmake

In the following command line description we use BNF notation. Hence [X] means zero or one occurrence of X, while {Y} means zero, one or arbitrarily many occurrences of Y.

gnatmake [-a] [-c] [-f] [-g] [-n] [-q] [-s] [-v] {[-Idirname] [-Ldirname]}
           unit_or_file_name
           {[-cargs options] [-bargs options] [-largs options]}

The purpose of gnatmake is to automatically determine and (re)compile the set of ada sources needed by some ada compilation unit, Unit. An ada source needed by Unit is recompiled if its corresponding object file is obsolete with respect to the current sources. By default the bind and link steps are also performed. There are two ways to specify the actual compilation unit:

All gnatmake output is to stderr.

[-a]
Consider all files. Considers all files in the make process, even the GNAT internal system files (for instance the predefined Ada library files). By default gnatmake does not check these internal files (don't worry this is safe, if there is an installation problem this will be caught when gnatmake binds your program). You may have to set this switch if you are working on gnat itself. For the vast majority of gnatmake users you never need to set this flag.
[-c]
Compile only. Do not perform the bind and link steps.
[-f]
Force recompilations. Recompile all sources even though some object files may be up to date but don't recompile predifined units if up to date. If a predified unit is not up to date, then recompile it.
[-g]
Compile with debugging information. Same effect as -cargs -g -largs -g. See below for meaning of -cargs & -largs.
[-n]
Don't compile, bind or link. Issue a (maybe innacurate) list of commands without actually executing them by guessing from the old ali (ada library information). Note that this information is imprecise, because no recompilations are actually carried out. However, if `gnatmake -n' reports no recompilations needed then the user is guaranteed that the objects are up to date. If, during the process, any ali is missing gnatmake is halted and an error message emitted.
[-q]
Quiet. Without this flag set the commands carried out by gnatmake are displayed. If -q is set, they are not.
[-s]
Smart. Performs smart recompilations. See section on smart gnatmake below.
[-v]
Verbose. Motivates all (re)compilations (ie gives *one* reason for (re)compiling a source file).
[-Idirname]
[-Ldirname]
Recognized but not yet implemented.
[-cargs options]
Compiler arguments. Without -cargs, gnatmake simply uses "gcc -c" to perform compilations. Otherwise gnatmake uses "gcc -c c_opts". `c_opts' is a list of parameters. This list includes all the options encoutered in the set of `-cargs options' present on the gnatmake command line. A given sublist of `-cargs options' is terminated upon encounter of another -cargs, -bargs or -largs. Note that by default `gnatmake -a' (see flag -a above) compiles all GNAT internal files with "gcc -c -gnatg" rather than just "gcc -c".
[-bargs options]
Binder arguments. Without -bargs, gnatmake simply uses "gnatbind unit.ali" to bind. Otherwise gnatmake uses "gnatbind b_opts unit.ali". `b_opts' is akin to `c_opts' above but is obtained from `-bargs options'.
[-largs options]
Linker arguments. Without -largs, gnatmake simply uses "gnatbl -linkonly unit.ali" to link. Otherwise gnatmake uses "gnatbl -linkonly l_opts unit.ali". `l_opts' is akin to `c_opts' and `b_opts' above but is obtained from `-largs options'.

NOTES:

  1. If the user types "gnatmake file.adb" where file.adb is a subunit or body of a generic unit, then gnatmake will recompile file.adb systematically because it finds no ali and then will stop issuing a warning.
  2. gnatmake does not examine .o files, only .ali files, so deleting .o files will not force a recompilation. You can force everything to be recompiled either by deleting the .ali files or by using the -f option.

Smart gnatmake

Not implemented yet. Coming to your local ftp site soon.

Constraint Checking and Pragma Suppress

In the current version there are some checks performed that are mentioned in the LRM in section 11.7. These are:

Since this is relatively new, there might still be some cases where exceptions are raised where they shouldn't. To disable constraint checks, compile the program with the "-gnatp" option. This is equivalent to having Pragma suppress applied to everything. Gdb can be used to find where the exception was raised. See the section on "Using gdb" for further information.

Arithmetic Overflow Checking

Compiling with the default options results in code that performs range checking against constraints (see -gnatp for suppressing such checks). However, the default mode does not enable checking for arithmetic overflow and division by zero.

If this checking is required, then the -gnato switch should be set. This causes appropriate additional code to be generated to check for both overflow and division by zero (resulting in raising Constraint_Error as required by the Ada semantics).

Note that the -gnato switch does not affect the code generated for any floating-point operations; it applies only to integer operations. For floating-point, GNAT has Machine_Overflows set to False, and the normal mode of operation is to generate IEEE NaN and infinite values on overflow or invalid operations (such as dividing 0.0 by 0.0)

The checks generated by -gnato are quite expensive, which is why they are not the generated by default. This is because GCC does not yet use specialized hardware features (flags, sticky flags, traps etc.) for the detection of integer overflow. Eventually we plan to implement more efficient integer overflow checking in the future.

Order of Compilation Issues

If, in our example, there were a spec for the hello procedure, it would be contained in the file "hello.ads"; yet this file would not need to be explicitly compiled. This is the result of the model we chose to implement library management. Details of the model can be found in file gnote1. Some of the unexpected consequences of the model (unexpected from the point of view of existing Ada compiler systems) are the following:

The above may seem surprising. Just to provide one immediate assurance, all of this does not mean that we are violating Ada's strict consistency rules; they are enforced instead by the binder.

File Name Rules

The current version of GNAT requires that file names match compilation unit names. The matching rules are as follows:

Under DOS -gnatk8 is the default, so crunching always takes place. On all systems the RTL files are all crunched to 8 characters.

Gnatk8

As mentioned in the previous section, gnatk8 can be used to find out what the krunched name of a file should be when using the -k8 (-gnatk8) option.

The first argument can now be an Ada name with dots or it can be the Gnat name of the unit where the dots representing child units or subunit are replaced by hypens. The only confusion arises if a name ends .ads or .adb, and we take this to be an extension if there are no other dots in the name and the whole name is in lower case.

The second argument represents the length of the krunched name. The default without any argument given is 8 characters. A length of zero stands for unlimited, i.e. no chop except for system files which are always 8.

Examples:

   gnatk8 very_long_unit_name.ads       ---->  velounna.ads
   gnatk8 very_long_unit_name.ads 6     ---->  vlunna.ads
   gnatk8 very_long_unit_name.ads 0     ---->  very_long_unit_name.ads
   gnatk8 grandparent-parent-child.ads  ---->  grparchi.ads
   gnatk8 grandparent.parent.child      ---->  grparchi

Note:

   gnatk8 grandparent.parent.child.adb  -----> grpachad

Here the .adb at the end is taken as part of the unit name as explained in one of the preceeding paragraphs above.

Compiling Files With Several Compilation Units

GNAT can only deal with files that contain a single Ada compilation unit. However, since it is an established style for certain types of programs to contain more than one compilation in a file, such as in test suites, a simple utility program, "gnatchop", is provided to preprocess the file and split it several other files, one for each compilation unit. gnatchop takes a filename with any extension. This name can basically be anything.

Usage : gnatchop [-k] [-r] [-s] [-w] filename [directory]
  k         limit filenames to 8 characters
  r         generate source reference pragmas
  s         generate a compilation script
  w         overwrite existing filenames
  filename  source file
  directory directory to place split files (default is the current directory)

For example, assume archive contains package spec part1, package body part1, package spec part2, package body part2.adb and subprogram part3 in any sequence.

"gnatchop archive" will create five files in the current directory called part1.ads, part1.adb, part2.ads, part2.adb, part3.adb. The optional directory argument places all the split files in that directory rather than the current directory. The directory must already exist otherwise gnatchop will reject it.

If at least one of the files to be split already exists, gnatchop will issue a message and exit unless the -w flag is used to overwrite existing files.

The -r flag causes source reference pragmas to be generated at the start of each file written. These pragmas will cause error message references and debugging source information to refer back to the original unchopped files. This is appropriate if you intend to maintain the program in unchopped form.

The -s flag generates a script which can be used to compile all the units contained in the original source file.

Suppose that you wanted to compile all the units contained in a given file called "archive" with some specific options like -gnatv, -O2 and -g. The gnatchop with -s option will generate a script with the appropriate extension depending on the the operating system. Then the script is invoked with the options following at the end as given below.

  gnatchop -s archive
  In Unix:  sh archive.sh -gnatv -O2 -g 
  In Dos :  archive.bat -gnatv -O2 -g
  In OS/2:  archive.cmd -gnatv -O2 -g

The -k flag krunches the names of the units to be 8 characters followed by the ads or adb extension.

Currently, if you want to specify more than one flag, you need to specify them separately. For example, if you want to split archive.adb and specify both the -s and the -w flags, type "gnatchop -s -w archive" instead of "gnatchop -sw archive". This limitation will be lifted in the near future.

Note: gnatchop works fine for the case of a single compilation unit in a file, and this is useful in dealing with files that do not have names satisfying the GNAT naming requirements.

Cross Reference Tool

The GNAT system provides a standalone tool, gnatf, which allows for syntax and semantics checking without any code generation. This is somewhat faster than using "gcc -gnatc".

Note:
the standard gnat options that do not concern code generation are still available in gnatf. However, they should not be preceeded by -gnat, so to do syntax only checking with gnatf, use `gnatf -s file.adb' not `gnatf -gnats file.adb'.

The real point of gnatf is that it contains a cross reference (xref) tool. The goal of the xref tool is:

  1. Give precise information about all declared entities (where they are defined and where they are used). This is particularly useful in the ada emacs mode that you will find with the distribution (see Ada Emacs Mode below).
  2. Emit warnings if an entity is defined but never used or a with clause is unnecessary, misplaced or redundant (more on this later).
  3. In the future this tool will be the backbone of a smart recompilation system which should reduce the number of recompilations in the event of minor source code modifications.
Usage : gnatf [-x[1-6]] files
files
The list of Ada source files to cross reference.
-x[1-6]
The -x[1-6] flags control the amount of information given by the xref tool. Flags -x1 and -x2 control the level of warnings generated. These warnings are output on standard error (usually the screen). Flags -x1 and -x2 do not cause any cross reference information to be generated. Flags -x[345] distribute cross reference information across several files. Specifically for each file "f.adb" (resp. "f.ads") in the `files' list we create a file "f.xrb" (resp. "f.xrs") containing all cross reference information (more on this below). Flag -x6 centralizes and stores this information in the single file "X.ref".

Flags usage:

-x1
Issues warnings for unnecessary, misplaced or redundant ``with'' clauses. Specifically, a warning message is generated in the following cases:
-x2
Issues warnings on unused entities, that is entities that are declared but never used. Note that we give *no* warnings for unreferenced entities like:
-x[345]
Generate cross-reference information. Flag -x3 gives the most succint xref information, -x5 the most comprehensive. Flag -x4 gives more information than -x3 but not as much as -x5. The information given by flags -x3 and -x4 will be used in the smart recompilation system currently under development and will be described hereafter. Flag -x5 lists all entities defined or used in the analyzed compilation units. It gives the source location of their definition and all their uses in the analyzed units.
-x6
The cross reference output is the same as with -x5 except that with -x6 all cross reference information is stored in the single file "X.ref" and the entity kind of each cross referenced entity is also given.

Cross reference information and smart recompilation

The cross reference information gathered by flags -x3 and -x4 is a subset of the information specified by flag -x5. The -x[34] information is specifically tailored to the smart recompilation system currently under development. When flags -x3 or -x4 are selected, then for each compilation unit "Unit" analyzed by the xref tool we gather the following information:

Cross reference file structure:

The xref file is divided into various sections. There is one section for each compilation unit explicitly requested in `files'. We call these units, the RUs, short for requested units. There is also one section for each AU, short for auxiliary unit, that is, those compilation units that get implicitly loaded by the compiler, but whose compilation has not been explicitly requested by the user. Specs of withed packages are typical auxiliary units.

All entities exported by RUs (flags -x3 and -x4) or all entities belonging to RUs (flags -x5 and -x6) appear in the xref file(s).

However, only the entities defined in AUs that are imported in RUs appear in the xref file. Their order is the order of declaration in the source files.

The sections in the xref referring to RUs and AUs are respectively denoted:

            %% unit.ad[sb]     for a RU.

            -- unit.ad[sb]     for an AU.

Note: An entitiy defined inside a generic and used through a generic instantiation, is listed under the xref section of the generic unit.

Example: Follows a list of files and the corresponding cross reference.

                        test.adb
            01  with Part1;  --  unused
            02  with Part2; use Part2;
            03  procedure Test is
            04
            05     Thing : Number;
            06     type Client is record
            07        Number : Integer;
            08        State  : Boolean;
            09     end record;
            10     type Color is (Red, Green);  -- unused
            11     My_Client : Client;
            12
            13  begin
            14     My_Client.Number := 1;
            15     My_Client.State  := True;
            16     Thing := 20;
            17     Thing := Thing + Thing;
            18  end;
                      part1.ads
               ^^^^^^^^^
            01  package Part1 is
            02     type Useless is new Integer;
            03  end;
                      part2.ads
                  ^^^^^^
            01  package Part2 is
            02     type Number is new Integer range 1 .. 1000;
            03     The_Number : constant := 42;
            04  end;

The result of invoking `gnatf -x5 test.adb' is the following (just skim the "test.xrb", explanations follow):

                    Warnings on stderr (the screen)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
             test.adb:1:06: warning: "Part1" withed but unused.
             test.adb:3:11: warning: "Test" unused
             test.adb:10:09: warning: "Color" unused

                           test.xrb
                           ^^^^^^^^
             01 V "SGNAT v1.0      "
             02 test.adb                941012154746 2 3 
             03 part1.ads               941012154531 
             04 part2.ads               941012154620 
             05 
             06 %% test.adb
             07 test 3:11 
             08 thing 5:4 
             09  {16:4 17:4 17:13 17:21}
             10 client 6:9 
             11  {11:16}
             12 client.number 7:7 
             13  {14:14}
             14 client.state 8:7 
             15  {15:14}
             16 color 10:9 
             17 red 10:19 
             18 green 10:24 
             19 my_client 11:4 
             20  {14:4 15:4}
             21 
             22 -- part1.ads
             23 part1 1:9 
             24  {1:6}
             25 
             26 -- part2.ads
             27 part2 1:9 
             28  {2:6 2:17}
             29 number 2:9 
             30  {5:14}

  Explanations:
  ^^^^^^^^^^^^

File "Test" is the only RU (requested unit). AUs (auxiliary units are packages "Part1" and "Part2". First the graph of the loaded units with their time stamps is given

             02 test.adb                941012154746 2 3 
             03 part1.ads               941012154531 
             04 part2.ads               941012154620

Unit "Test" requires the loading of units "Part1" and "Part2" (the second and third units listed in the inclusion graph). Entry:

             06 %% test.adb
             07 [...]
             08 thing 5:4 
             09  {16:4 17:4 17:13 17:21}

means that "Thing" is an entity (a variable) defined in line 5 column 4 and used in line 16 column 4, line 17 columns 4, 13 and 21 in file "test.adb".

Note that entity "Useless" may be used in units other than "Test" but that information is not contained in the "test.xrb" since "Test" does not use "Useless".

Implementation of Intrinsic Functions

GNAT version 1.79 begins to implement intrinsic functions. In particular, the shift functions predefined in Interfaces are now implemented.

The implementation is quite general. You can define shift operations (i.e. one of the five operations, Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, Rotate_Right) on any integer type, signed or unsigned, whose Size is 8, 16, 32 or 64 bits, and then provide an appropriate pragma Import Intrinsic, and everything will work.

In other words, the package Interfaces is not using any special magic, and you can do exactly what it does to make shift operations available for any integer types that meet the size criteria (shift operations for wierd-sized integers seem too marginal to worry about!)

Example:

   type My_Type is new Integer;

   function Shift_Left (Val : My_Type; Count : Natural) return My_Type;
   pragma Import (Intrinsic, Shift_Left);

The exact requirements on the pragma Import are as follows:

Getting Internal Debugging Information

Most compilers have secret internal debugging switches and modes. GNAT is no exception, except that nothing about GNAT is secret. A summary and full description of all the compiler/binder debug flags can be found in the file debug.adb. You will have to get the sources of the compiler to see the full detailed effects of these, but feel free to experiment with them.

The switches that print the source of the program (reconstructed from the internal tree) are of general interest, as are the options to print the full internal tree, and the entity table (that is to say, the symbol table information).

When GNAT crashes

There are several things you can do when GNAT does the unexpected while compiling your Ada program, such as aborting with a segmentation fault or illegal memory access, raising an internal exception, or otherwise terminating abnormally. The following lines of action are of course palliatives that will become unecessary as the system becomes more complete and robust. The following strategies are presented in increasing order of difficulty, corresponding to the sophistication of the user, and her curiosity about the functioning of the compiler.

  1. run gcc with the -gnatf and -gnate switches. The 'f' switch causes all errors on a given line to be reported. In its absence, only the first error on a line is displayed.

    The 'e' switch causes errors to be displayed as soon as they are encountered, rather than after compilation is terminated. Often this will be enough to identify the construct that produced the crash.

  2. run gcc with -v (verbose) switch. In this mode, gcc produces ongoing information about progress of the compilation and in particular the name of each procedure as it begins to generate code for it. This switch allows you to find which Ada procedure it was compiling when it ran into a code generation problem.
  3. run gcc with the -gnatdc switch. This is a GNAT-specific switch that does for the front-end what -v does for the back-end. The system prints the name of each unit, either compilation unit or nested unit, as it is being analyzed.
  4. On systems that have gdb available (like most Unix systems), you can run gdb directly on the gnat1 executable. Gnat1 is the front-end of GNAT, and can be run independently (normally it is just called from gcc). You can use gdb on gnat1 as you would on a C program (but see below for caveats). The "where" command is the first line of attack; the variable "lineno" (seen by "print lineno") used by the second phase of gnat1 and by the gcc back-end, indicates the source line at which the execution stopped, and "input_filename" the name of the source file.

Using gdb

Gdb awaits modifications to handle Ada properly, and for now can only be used as it would be for a c program. (Someone is working on the proper extensions, and these will appear in subsequent releases.) In the meantime, the following naming conventions will allow you to find the Ada entities defined in your program:

  1. The names of all entities (variables, subprograms, etc.) are converted to lower case.
  2. Entities that appear in library package declarations have the name package_name__subprogram_name (Note the two underscores separating package name from subprogram name).

Exceptions can be caught by breaking in the "__gnat_raise" routine and then doing a "bt" or "where" command.

GNAT specific pragmas

Full documentation of the GNAT specific pragmas can be found in the GNAT source file sem_prag.adb. You need to retrieve the latest source distribution to view this file.

New WARNING messages related to accessibility checks and private packages

GNAT version 2.05 implements two new checks that we anticipate will cause some problems to existing programs.

First, static accessibility checks are implemented. These catch two common errors:

Improper use of 'Access attribute. These can usually be "corrected" by the use of 'Unchecked_Access in the variable case, but good Ada style says that the use of 'Unchecked_Access should be restricted, just like the use of Unchecked_Conversion. Unchecked_Access can lead to dangling pointers, and at the least careful analysis is needed.

The invalid use of 'Access for subprograms is harder to fix in a "legitimate" manner. GNAT provides the 'Unrestricted_Access attribute that can be applied to subprograms in defiance of the accessibility rules (e.g. to create downward closures), but this attribute is not portable, and, as described by Bob Duff "naughty". So think twice at least before casually "fixing" your problem this way. Dangling subprogram pointers are particularly unpleasant. Another alternative is to use a generic, and pass the subprogram as a generic formal subprogram.

The other common error is the derivation of a tagged type at a deeper nesting level than the parent type. This is also illegal (because it could cause dangling hidden subprogram pointers in dispatch tables). GNAT is not about to provide a way around this error, you must restructure your program. The simplest approach is to define all tagged types at the library level.

Note in particular that all controlled types are derived from library level types, and so can only be declared at the library level. This is such a common case, that we have special-cased the error message.

The second new check is for the (mis)use of private packages. This caused some unwelcome surprises in the GNAT code itself. Again, the only proper remedy is to restructure (or possibly reconsider the use of private packages). The critical rule is that specs cannot with a private package unless they are themselves private.

We are thinking of introducing a pragma that would provide some protection for withing packages that are not intended to be public, but are needed in specs, stay tuned!

Meanwhile, in version 2.05, these error messages are warnings, but take care, they are really illegalities, and in 2.06 they will be changed to be error messages instead of warnings, so you have one version to clean up your act with respect to accessibility and private packages!

Features supported/unsupported

A full listing of features supported/unsupported is available separately in the file "features" included in the distribution. Note that this usually changes with each distribution, so read often.

Files

If you want to examine the workings of the GNAT system, the following haiku-like description of its organization might be of minimal use:

File with prefix "sc" contain the lexical scanner.

All files prefixed with "par" are components of the parser. The numbers correspond to chapters of the Ada 83 LRM (or the corresponding sections of the Ada 95 LRM). For example, parsing of select statements can be found in par-ch9.

All files prefixed with "sem" perform semantic analysis. Same numbering scheme. For example, all issues involving context clauses can be found in sem_ch10.

All files prefixed with "exp" perform AST normalization and expansion. For example, the construction of record initialization procedures is done in exp_ch3.

The files prefixed with "bind" implement the binder, which verifies the consistency of the compilation, determines an order of elaboration, and generates the bind file.

The file atree details the low-level data structures used by the front-end. The file sinfo details the structure of the AST as produced by the parser. The file einfo details the attributes of all entities, computed during semantic analysis.

Library management issues are dealt with in files with prefix "lib".

Files with prefix a- are GNAT-specific C files. They are the components of Gigi (gnat-to-gnu), the program that translates the Ada AST into gcc tree fragments. Gigi makes use of C versions of atree, einfo and sinfo, called a-atree.[ch], a-einfo.[ch] and a-sinfo.h respectively.

All the other .c files are modifications of common GCC files.

Happy browsing!

Ada Mode for Emacs

In the subdirectory `emacs-ada-mode' you will find a bunch of files implementing an Ada mode under Gnu emacs. The mode is still under development, but a number of features are complete. For instance, the Ada mode has the same indenting friendliness that C programmers get with the c-mode, you can toggle between spec and body with a few keystrokes, etc. This mode also uses gnatf to be able to point to an entity with the mouse, click it and open a window with its definition. This mode is copywrited by Markus Heritsch and Rolf Ebert.

Copyright Considerations

For now, everything is copyrighted by NYU, using the GNU public license. This means that you can copy everything freely, but you can't incorporate the code directly into a commercial program. For more information on the GNU license, see the file header. One important note is that it will be possible to use GNAT to generate software that is not itself covered by the GNU license. Eventually the copyright will be transferred to the Free Software Foundation, so that GNAT can be distributed directly by FSF under the same restrictions (or what we like to think of as lack of restrictions!).

How to Get in Touch with Us

To get on our external INTERNET mailing list, send a message to:

gnat-request@cs.nyu.edu

Submitting Bug Reports

We welcome bug reports, they are of course a vital part of the process of getting GNAT into solid shape. You will help us (and make it more likely that you receive a timely response) if you follow these guidelines.

We only receive bug reports by internet, addressed to gnat-report@cs.nyu.edu. At the moment we cannot process bug reports from any other source.

Note: if you believe you have found a GCC (C language or configuration file) bug rather than an GNAT (Ada language) bug please report it to bug-gcc@prep.ai.mit.edu. If you have found a bug when using GCC to compile C++, please report it to bug-g++@prep.ai.mit.edu.

Please put one bug in a message, and add a short but specific subject (a general subject like "GNAT bug" is not so useful, a title like "bug in visibility with generics" is more useful).

Please include full sources. We can't duplicate errors without the full sources. Include all sources in the single email message with appropriate indications in the multiple file cases, see below.

Please send all sources in plain ASCII form, we can't process compressed, uuencoded etc. messages in our current form (they have to go through extra steps, and easily get lost, separated from the author etc during this process).

Please include COMPLETE identification of the version of the system you are running.

To be maximally helpful, for a report that contains multiple separate compilation units, and hence multiple files, submit them in the form of a single file that is acceptable input to gnatchop (used to be called gnatsplit on versions of GNAT prior to 1.80), i.e. contains no non-Ada text. If you use banners to separate the files, make sure they are composed entirely of blank lines or Ada comments.

If you want to be maximally helpful, try to reduce your example to a simple one but DON'T spend too much time doing this. Especially when you are reporting a blow up during compilation, rather than bad code generated, we can in practice work with big sources if you have trouble narrowing things down.

If a bug involves incorrect operation of the generated code, then the first thing the program should do is to output a line indicating the expected output or behavior. If at all possible, do a test later on that prints out "passed" or "failed" depending on the behavior. Of course it may not always be possible to structure a test this way, but that's the most convenient form (for obvious reasons!)

When we receive a bug report, we take a preliminary look to categorize it into one of the following:

  1. Pilot error, documentation problems, installation problems etc.
  2. Interesting comment, suggestion etc, but not a bug
  3. Bug that we already know about
  4. Bug that is already fixed in our development version
  5. Obvious bug that we correct immediately in our development version
  6. Real genuine new unfixed bug.

In the first 5 cases, you will get a message telling you the status. In the 6th case only, we assign a bug tracking number of the form mmdd-nnn, where mmdd is the date of receipt, and nnn is a serial number (highest value so far 005, but you never know!) In this case, the release notes will tell you what the status of the bug is, and also we will send you a message when it is fixed.

To send reports to us on the system, or ask questions, send messages to

gnat-report@cs.nyu.edu

To contact team members, send messages to:

dewar@cs.nyu.edu

schonberg@cs.nyu.edu

To obtain electronically the latest version of the system, FTP from:

cs.nyu.edu (directory pub/gnat)

This FTP directory also includes full sources for the system, full documentation and technical notes, as well as executables of the system for several targets. We are sorry that our limited resources do not allow us to distribute the system through other media.

We trust that this information will be mirrored at other FTP sites around the world (we encourage such mirroring to occur), which will make it easier for users in other continents to obtain the GNAT system without heavy communication uncertainties.

Schedule

We will make available new releases of GNAT at around 5 or 6 week intervals for the time being. Please recall that releases of the system are still only snapshots of work in progress. We hope that it will be of some use in the work of others, even in its current embryonic form.

A short gnat paper

A TeX file of a short paper describing something about the GNAT project is included under the name gnatdoc1.tex.

Ada Information Resources On the Internet

There is a wealth of Ada-related information available on the Internet. The simplest way to access it is via a World Wide Web (WWW) browser such as Mosaic or Netscape. Start up your browser and "open" the following URLs that interest you:

http://lglwww.epfl.ch/Ada/
The Ada WWW server in Lausanne, Switzerland; this server has a wealth of Ada-related information.
http://lglwww.epfl.ch/Ada/FAQ/comp-lang-ada.html
Ada frequently-asked questions (FAQs).
http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/lovelace.html
Lovelace, a free interactive Ada 95 tutorial.
http://lglwww.epfl.ch/Ada/Resources/Books/Textbooks.html
An annotated list of Ada-oriented textbooks.
http://wuarchive.wustl.edu/languages/ada/
The Public Ada Library (PAL); this contains lots of software.
http://sw-eng.falls-church.va.us/
The Ada Information Clearinghouse.
http://www.acm.org/sigada/
The Association for Computing Machinery (ACM)'s SIGAda home page.

There is also a newsgroup, comp.lang.ada , specifically dedicated to Ada.

The GNAT development team

New York University
	     Bernard Banner (*)
	     Cyrille Comar (*)
	     Robert Dewar (*)
	     Sam Figueroa (*)
	     Richard Kenner (*)
	     Bruno LeClerc (*)
	     Brett Porter (*)
	     Gail Schenker (*)
	     Edmond Schonberg (*)
Florida State University (Tasking runtime work)
	     Ted Baker
	     Ted Giering (*)
	     Frank Muller
Ecole Nationale Superieure de Telecommunications
             Patrick Bazire
	     Franco Gasperoni (*)
	     Yvon Kermarrec
	     Laurent Pautet
Elsewhere
	     Paul Hilfinger (*) (University of California, Berkeley)
	     Jean Pierre Rosen (*) (Paris)
	     Richard Stallman (Free Software Foundation)

(*) partially supported by the NYU GNAT project (ARPA, USAF, AJPO, Ada 9X project office)