------------------------------------------------------------------------------ -- -- -- GNAT DOCUMENTS -- -- -- -- I N T R O -- -- -- -- $Revision: 1.103 $ -- -- -- -- Copyright (C) 1992,1993,1994,1995,1996 Free Software Foundation, Inc. -- -- -- -- 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 Soft- -- -- ware Foundation; either version 2, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- 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 distributed with GNAT; see file COPYING. If not, write -- -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- -- MA 02111-1307, USA. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). -- -- -- ------------------------------------------------------------------------------ Note: Version 1.103 of this document corresponds to the public release of GNAT 3.07. Contents. --------- What is Ada 95 ? What is GNAT ? Public GNAT Releases. Running GNAT. A small example. Using gcc to compile. Using gcc for syntax checking. Using gcc for semantics checking. GNAT Options. Constraint Checking and Pragma Suppress. Software Overflow Checking. Using the binder. Gnatlink. Building a Program where the Main Program is not in Ada Search Paths and the Run Time Library (RTL). Gnatmake (*new features*). Order of Compilation Issues. File Name Rules. GNAT specific pragmas. pragma Source_File_Name. Machine Code Insertions Gnatk8. Compiling Files With Several Compilation Units. Cross Reference Tool. Implementation of Intrinsic Functions. Getting Internal Debugging Information. GNAT Trouble-Shooting. Using gdb. Performance Considerations. New WARNING messages related to accessibility checks and private packages Features supported/unsupported. Files. Ada Mode for Emacs. Copyright considerations. How to get in touch with us. Schedule. A short gnat paper. Ada information resources on the Internet. The GNAT development team. ------------------------------------------------------------------------------ What is Ada 95 ? ---------------- Ada 95 is the latest Ada standard. It is also the first ISO and ANSI standard programming language to fully support object-oriented programming. Ada 95 is fully upward compatible with Ada 83 (ISO 87) and has the same robust foundation in Software Engineering. At the same time, it provides up-to-date features for today's megaprogramming tasks, including: - object-oriented programming, inheritance, polymorphism and dynamic dispatching, within the strong-typing discipline of Ada 83. - Hierarchical program libraries, for composition of subsystems and support of multiple implementations. - Well-defined support for interfacing to other languages such as C, Fortran and COBOL. - Support for specialized application areas such as: System Programming, Real-Time Systems, Distributed Systems, Information Systems, and Scientific Programming. All of this makes Ada 95 into the ideal language for large industrial projects. The ease with which Ada 95 can interface with other languages make it an ideal choice as well for the multilanguage systems of today and the coming century. What is GNAT ? -------------- GNAT is an industrial-quality Ada 95 compiler, integrated into the GCC retargetable compiler system. GNAT is a complete compiler, validated on several platforms, that includes support for all the Ada 95 annexes specified in the Ada Reference manual. Because of its integration into the GCC system, GNAT is available on a large number of hardware/operating system platforms, and can be used as a cross-compiler from any of its targets to any other one. Because of the common code-generator technology of GCC, GNAT has excellent support for multi-language programming: Ada, C, C++, Fortran, etc. GNAT also represents a substantial improvement in Ada compilation technology. Its open-system philosophy stands in contrast with the opaque approach of older Ada compilers. There are no hidden and complex central libraries whose use requires a totally new set of commands, and no rigid development environments that often force needless recompilations. While preserving all of Ada's safety, GNAT's source-based model provides the flexibility and efficiency typically encountered in C development environments. Furthermore, GNAT's flexibility greatly facilitates its integration within third-party development environments and CASE tools. A number of standard editors, debuggers, profilers, memory analyzers, test coverage or configuration-management tools, etc. can be used with GNAT, which coexists confortably with familiar programming tools (unlike older Ada compilation systems). GCC is a highly portable compilation system with multiple front-ends, advanced cross-compilation features, and a common code generator with multiple targets. Originally designed as a compiler for C, it now includes front ends for C++, Objective-C, Fortran77, Pascal, Chill, and most recently Ada 95. The innovative architecture of the GCC back end allows new hardware targets to be described compactly, for use by a machine-independent and language-independent multi-pass code generator. This technique produces code of excellent quality both for CISC machines such as the Intel x86 and Motorola 68K families, and for RISC machines such as the Power/PC, the DEC Alpha, the HP-PA RISC, the RS6000, and the MIPS R4000. Public GNAT Releases. --------------------- GNAT is not public domain software. GNAT, like GCC, is covered by the GPL (General Public Licence) which preserves the freedom of the software community by guaranteeing that GNAT and its sources will always be freely available. This greatly helps the spread of GNAT and Ada 95 technology in research and academic environments and allows its free evaluation before industrial deployment. Public GNAT releases in various ftp sites around the world are made at 6 to 8 week intervals. If you intend to evaluate GNAT for industrial or commercial use please get in touch with `support@gnat.com'. 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 are linked together to produce an executable. A tool has been provided to combine all these 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 is the command for building and running it: gnatmake hello create the executable called "hello" or "hello.exe" in your current directory. Typing hello will allow you to verify that the system is alive and willing to enter into a primitive dialogue. In the above example, Gnatmake performs the following steps (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 gnatbind -x hello.ali Unix: gnatlink -o hello hello.ali OS/2: gnatlink -o hello.exe hello.ali DOS : gnatlink -o hello.exe hello.ali The gcc switch -c indicates that we only want to compile, not link. 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 gnatbind (see below) as the ALI file of the main procedure or function, and gnatbind uses it to create a file called the bind file, and to gather all the needed object files for linking. Gnatbind creates a file b_hello.c which contains the calls to the necessary elaboration procedures. This information is collected from the closure of all ALI files determinable from the root ALI file (hello.ali). A list of all dependent object files is also generated and appended to the end of the bind file. Gnatlink compiles b_hello and links the b_hello object file with all the object files listed in the bind file. 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 gnatlink, the two files are not removed since it is assumed they might be required for debugging. Linking is accomplished by 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. (Note that gnatbl is obsolete and has been replaced by gnatlink. The gnatbind step must now be performed separately. This is done automatically by gnatmake. For the DOS version of gnatlink, the extra step of running a modified coff2exe is incorporated, which will create a stripped executable. In order to lessen the proliferation of normally unused files, the extensionless COFF version is also automatically deleted unless -g is specified.) 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 explained in your gcc documentation. In addition, gcc passes certain switches 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 are the object and ALI files for foo. In the future, the gcc and the GNAT-specific switches may 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 quite robust. If you find an error message you think could be improved, let us know (see separate section below). 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: o The needed source files must be accessible. See the section on search paths below. o Each file must contain only one compilation unit. See the section below on file name rules. o The file name and unit name must match as described below, under File name rules. 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. Note that 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. GNAT 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? Identifier char set (?=1/2/3/4/8/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 nnn characters (k = krunch) l Output full source listing with embedded error messages mnnn Limit number of detected errors to nnn (1-999) n Inlining of subprograms (apply pragma Inline across units) 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 first-time users, and for first-compilation attempts, the following mode of operation is recommended: gcc -c -gnatc lets_try_this.adb 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: range checks on signed integer and enumeration types (assignment, in parameters and initial values in object declarations) index checks access checks 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. Using the Binder. ----------------- In the "Hello World" example above, the second step (performed by gnatmake) is to create the bind file with the command: gnatbind -x 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 that calls all of the elaboration routines for 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 gnatlink finds the list of object files required. The options of gnatbind are summarized below. 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 -aOdir Specify library files search path -aIdir Specify source files search path -Idir Specify source & library files search path -I- Don't look for sources & library files in default directory -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 Gnatlink -------- gnatlink [-o exec_name] [-v] -- verbose mode [-g] -- include debugging information [-gnatlink name] -- full name for the linker (gcc) [list of objects] -- non Ada binaries [linker options] -- other options for the linker The program gnatlink provides for linking using the GNAT RTL. The typical use of GNAT (currently -- in the presence of gnatlink) 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 gnatbind is used to produce the bind file. Finally, gnatlink constructs the executable. All arguments to gnatlink 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 gnatlink sees a .ali file it compiles the associated bind file, extracts a list of needed object files from that 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) gnatlink -o main main.ali bar.o would cause gnatlink to: assume the presence of the bind file 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 gnatlink 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 gnatlink is similar.) (Under DOS, the additional step of calling "coff2exe main" is done, which will create a stripped executable.) [-o exec_name] Under unix if the -o option is omitted the executable is called the name of the main unit. So "gnatlink 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. Note that on DOS it is impractical to debug without gnatlinking with -g, since the debugger only works on COFF files. [-gnatlink name] -- full name for the linker (gcc) Building a Program where the Main Program is not in Ada ------------------------------------------------------- To build a program where the main program is not in Ada, we compile the Ada units as usual. Then bind using gnatbind with the -n switch, and then gnatlink mentioning the object files for the main program. Consider the following example: Main program (m.c) main() { adainit(); Header(); adafinal(); } Ada subroutine (header.adb) with Text_IO; use Text_IO; procedure Header is begin put_line ("Header"); end; pragma Export (C, Header, "Header"); Compile the units gcc -c m.c gcc -c header.adb Bind gnatbind -n header.ali Link gnatlink header.ali m.o Run header Notes: If more than one Ada routine is called from the non-Ada main program, then the ali files for all such Ada routines must be supplied to the binder. The binder will take care of any transitively referenced units (e.g. if B with's C, then mentioning b.ali will automatically cause c.ali to be also read, but if C is only mentioned by the main program, then c.ali must appear on the gnatbind line). The name of the program is by default the name of the ali file given to the gnatlink command. This can be changed using a -o switch. The calls to adainit and adafinal ensure that the Ada code is properly elaborated, and that any required finalization at the end of the run is properly performed. 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. Both 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 given 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: o The first directory searched is the directory containing the source file of the main unit being compiled (the file name on the command line). This directory is the current working directory only if the input file contains no relative or absolute path information. Otherwise if the input file is specified as dir/file then the first directory searched is dir. Note, however, that option `-I-' inhibits the use of this directory as the default search directory. You can still have this directory on your search path, but this must be explicitely requested with a -Idir flag if -I- is specified. See below for -I. o Next, the compiler looks in each directory named by a "-I" option given to gcc (in the order given on the command line). o Then the compiler looks in each of the directories listed in the value of the ADA_INCLUDE_PATH environment variable. This value is constructed exactly as the PATH environment variable -- a list of directory names separated by ':' or ';' (Unix or OS/2, respectively) characters. Under OS/2, this mechanism is used to locate the RTL source files in place of the default location described next for Unix. o (Unix only) Finally the compiler looks in the default location for the GNAT Run Time Library (RTL) source files that is determined at the time that GNAT is built and installed on your system. 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: o The first directory searched is the directory containing the ALI file named in the command line. This directory is the current working directory only if the input ALI file contains no relative or absolute path information. Otherwise if the input ALI file is specified as dir/ali-file then the first directory searched is dir. Note, that option `-I-' inhibits the use of this directory as the default search directory. You can still have this directory on your search path, but this must be explicitely requested with a -Idir or -aOdir flag if -I- is specified. o Next, the binder looks in directories named in "-Idir" or "-aOdir" options on the gnatbind command line (in the order given). o Next, the binder looks in each of the directories listed in the value of the ADA_OBJECTS_PATH environment variable. This value is constructed exactly as the PATH environment variable -- a list of directory names separated by ':' or ';' (Unix or OS/2, respectively) characters. Under OS/2, this mechanism is used to locate the RTL object files in place of the default location described next for Unix. o (Unix only) Finally the binder looks in the default location for the GNAT Run Time Library (RTL) object files that is determined at the time that GNAT is built and installed on your system. 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. Specifically, the directory where the gnatbind command was invoked is searched first (unless -I- is present), then the directories specified with -I or -aI, then those in ADA_INCLUDE_PATH, etc. Because no source file is specified to the binder, the first directory which is searched for sources is the current working directory. To avoid searching this directory use -I-. The difference betwen flags -aI, -aO and -I is that -aI specifies source files search path (ada includes), -aO specifies library/object files search path (ada objects), while -I implies both -aI and -aO. 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 gnatbind/gnatlink -- 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). Gnatmake -------- In the following command line description we use BNF notation. [X] means zero or one occurrence of X. {Y} means zero, one or arbitrarily many occurrences of Y. * stands for any sequence of characters. gnatmake [-a] [-c] [-f] [-jnum] [-k] [-M] [-o exec_name] [-n] [-q] [-v] [compiler_switch] { [-Adir] [-aOdir] [-aIdir] [-Idir] [-I-] [-Ldir] } 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. The bind and link steps are also performed if objects were found to be out-of-date. In previous versions of gnatmake the bind and link steps were always performed. This was, at times, inconvenient. The latest gnatmake will perform the bind and link step only if some object file is more recent than the executable (this also correctly works if you use the -o option of gnatmake. See below fro the -o option). There are two ways to specify the actual compilation unit: * By giving the full name of the source file containing it ("gnatmake file.adb" or "gnatmake dir/file.adb" or "gnatmake file.ads" or "gnatmake dir/file.ads" or in general "gnatmake file.*" or "gnatmake dir/file.*") * As above but you can omit the .adb or .ads suffix (`gnatmake file or `gnatmake dir/file) To decide whether gnatmake needs to recompile a source file, gnatmake needs to locate other source files as well as the corresponding object/library files. The search for source files is done in *exactly* the same fashion as for gcc, whereas the search for object/library files is done *exactly* like for the binder (both are described in the section on search paths above). In particular the switches -I, -I-, -aI and -aO are directly available in gnatmake (see below). The only missing precision is the definition of the default source/library search directory for gnatmake. For library/object files the default search directory (ie the directory where object/library files are searched first) is the directory where gnatmake was invoked (ie "."). By using switch -I- you can disable lookup in this default directory. For source files if the user types gnatmake -aIdir_2 ... -aIdir_n dir_1/file or gnatmake -aIdir_2 ... -aIdir_n dir_1/file.adb the search path seen by gnatmake is dir_1 dir_2 ... dir_n (note that dir_1 may be ".") and the default source search directory is dir_1. To disable initial search in dir_1 use -I-. The only difference between the two gnatmake calls above is that in the first call gnatmake will look for file.adb/file.ads in dir_1 dir_2 ... dir_n, whereas in the second call gnatmake will look for file.adb only in dir_1 and will fail if it cannot find it there. Please note that you cannot use -I- if you give the full source name of the main unit (ie "gnatmake -I- ... file.adb" is forbidden) because gnatmake will be unable to recreate the same source search path for subsequent calls to gcc. Note that gnatmake will invoke gcc in the directory where gnatmake was invoked. This means that all object and library files that will be generated from the various compilations will be output to the current directory. For the time being there is no way to redirect this output to some other directory (unless you move it there yourself). To build several executables which share a common set of sources you need to create a separate directory for each executable and generate the executable in that directory. To select the appropriate sources use the -aI, -I and -I- switches (see below). Note that the switches -aL and -aO will allow to specify the location of object and ALI files which already exist and do not have to be recreated. Because gnamake invokes gcc in the current gnatmake switches are of 4 kinds: * gnatmake switches. These switches directly control gnatmake's behavior. * gcc switches. These switches are passed as is to gcc by gnatmake. * Source & library search path switches. * General compiler, binder & linker switches. All gnatmake output (except for -M) is to stderr. The output produced by the -M switch is to standard output. gnatmake switches: [-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. Note that by default "gnatmake -a" compiles all GNAT internal files with "gcc -c -gnatg" rather than just "gcc -c". [-c] Compile only. Do not perform binding and linking. If the root unit specified by unit_or_file_name is not a main unit this is the default. Otherwise gnatmake will attempt binding and linking unless all objects are up to date and the executable is more recent than the objects. [-f] Force recompilations. Recompile all sources even though some object files may be up to date but don't recompile predefined units or GNAT internal files unless the -a switch is set. [-jnum] Use "num" processes to carry out the (re)complations. If you have a multiprocessor machine compilations will occur in parallel. In the event of compilation errors, messages from various compilations might get interspersed (but gnatmake will give you the full ordered list of failing compiles at the end). This can at times be annoying. To get a clean list of error messages don't use -j. [-k] Keep going. Continue as much as possible after a compilation error. To ease the programmers's take in case of compilation errors, the list of sources for which the compile fails is given when gnatmake terminates. [-M] Checks if all objects are up to date. If they are "gnatmake -M" outputs the object dependences to standard output in a form that can be directly exploited in a Makefile. By default each source file is prefixed with its (relative or absolute) directory name. This name is whatever was specified in the various -aI -I switches. If you use "gnatmake -M -q" (see flag -q below) then only the source file names without relative path are output. If you just invoke "gnatmake -M" dependencies of the GNAT internal system files are omitted. This is typically what you want. If you use "gnatmake -a -M" dependencies of the gnat internal files are also listed. Note that dependencies of the objects in external Ada libraries (see switch -aLdir below) are never reported. [-n] Don't compile, bind or link. Checks if all objects are up to date. If they are "gnatmake -n" reports that no recompilations needed. Otherwise "gnatmake -n" stops and prints the full name of the first encountered file that needs to be recompiled. Note that if you specify "-n -f" together, gnatmake will return the full name of the main unit. [-o exec_name] Output executable name. The name of the final executable program will be "exec_name". Like for gnatlink if the -o option is omitted the default name for the executable will be the name of the input file without the suffix (Unix systems) or the name of the input file with an ".exe" extension (DOS and OS/2). Note that exec_name can be prefixed with a relative or absolute directory path. [-q] Quiet. Without this flag set the commands carried out by gnatmake are displayed. Flag -q has a special use when flag -M is also set. See -M above. [-v] Verbose. Motivates all (re)compilations (ie gives *one* reason for (re)compiling a source file). gcc switches: The switch -g or any upper case switch (other than -A, or -L) or switch that is more than one character is passed to gcc (e.g. -O, -gnato, etc.) Source & Library search path switches: [-aL] Ada Library. gnatmake tries to locate the bodies of all compilation units in the program. If the program uses an Ada library containing only the objects and library information for its units (i.e. the sources for the corresponding bodies are unavailable) gnatmake will fail. To avoid this use flag -aL. It instructs gnatmake to skip compilation units whose ali information has been located in directory "dir". Another reason for skiping units in Ada libraries is efficiency. It would be very wasteful for gnatmake to systematically check the consistency of every external Ada library used in a program. The binder is already in charge of catching potential inconsistencies. Note that this switch allows to have missing *bodies* for the units that are in your library. You still need to locate the specs for these units. Switches -aIdir or -I below can be used for this purpose. [-Adir] Equivalent to "-aLdir -aIdir". See below for -aI. [-aOdir] When looking for library and object files look also into directory "dir". The order in which library files search is undertaken is described in section "Search Paths and the Run Time Library" above. [-aIdir] When looking for source files look also into directory "dir". [-Idir] Equivalent to "-aOdir -aIdir". [-I-] Do not look for source, library or object files in the default directory. [-Ldir] Add directory "dir" to the list of directories in which the linker will search for libraries. This is equivalent to typing -largs -Ldir. See below for the meaning of -largs. General compiler, binder or linker switches: [-cargs options] Compiler arguments. gnatmake allows you to pass some switches directly to gcc. These switches have been given above under `gcc switches'. If you want to pass other arguments to gcc type "gnatmake ... unit -cargs c_opts ..." and gnatmake will invoke gcc with "c_opts" in its parameter list. The list "c_opts" is terminated upon encounter of another -cargs, -bargs or -largs. [-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 "gnatlink unit.ali" to link. Otherwise gnatmake uses "gnatlink l_opts unit.ali". "l_opts" is akin to "c_opts" and "b_opts" above but is obtained from "-largs options". Note that you are not allowed to use the -o option within a -largs. Use the -o option which is directly provided by gnatmake to give a specific name to your executable. NOTES: 1. gnatmake examines both an ali file and its corresponding object file for consistency. If an ali is more recent than its corresponding object, or the object is missing, the corresponding source will be recompiled. Note that gnatmake expects an ali and the corresponding object file to be in the same directory. 2. If there are no recompilations gnatmake tells you so, unless you've used -q, in which case gnatmake is silent. Thus when you type "gnatmake -n -q unit", gnatmake will either return the full path name of the first file that needs to be recompiled, or it will be silent. Thus "gnatmake -n -q" can be used as input to further tools. 3. If the user types "gnatmake file.adb" where file.adb is the body of a generic unit, then gnatmake will recompile file.adb systematically because it finds no ali and then will stop. In particular beware that in this case "gnatmake -n -q file.adb" will always return "file.adb". 4. If you gnatmake a spec that has a body (say "unit.ads") or a sub-unit you will get % gnatmake unit.ads gcc -c unit.ads No code generated for t1 (spec) in file t1.ads gnatmake: *** compilation failed. The compilation "fails" because specs or sub-units generate no code. To avoid the message use the -gnatc flag (semantics only). % gnatmake -gnatc unit.ads gcc -c -gnatc unit.ads 5. gnatmake has been designed to make the use of Ada libraries particularly convenient. Assume you have an Ada library organized as follows: obj-dir contains the objects and ALI information for of your Ada compilation units, whereas include-dir contains the specs of these units, but no bodies. Then to compile a unit stored in main.adb, which uses this Ada library you would just type % gnatmake -aI"include-dir" -aL"obj-dir" main 6. If you type % gnatmake -aO"dir2" file.adb and "dir2" contains an up-to-date file.ali file.adb will not be recompiled. 7. If you type % gnatmake -I- -Idir file gnatmake will look for file.ali in "dir" only. This means that if file.ali is obsolete, gnatmake will recompile file.adb in the current directory but will not be able to re-read file.ali because library file search was disabled in the current directory by -I-. In this even, gnatmake will warn you and will keep going but will not perform the bind and link steps. 8. The switch -M can be very useful if, after having created an executable, you want to know which source files were used and in which directory they lie. For this just type % gnatmake whatever-switches file-name this will generate the executable. Then add the -M switch to see the exact list of dependencies % gnatmake -M whatever-switches file-name 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: o There is no point in compiling generics or specifications (except for package specifications with no bodies), since these are compiled as needed by clients. If you do attempt a useless compilation, you will get a warning message. It is also useless to compile subunits in this mode, since they are compiled as needed by the parent. o There are no order of compilation requirements, and performing a compilation never obsoletes anything. The only way you can obsolete something and require recompilations is if one of the relevant source files is modified. o There is no library as such, apart from the .ali files, whose format is also described in libfmt.ads. For now, we find it convenient to create separate .ali files, but eventually the information therein may be incorporated into the object file directly. o When you compile a unit, the source files for the specs of all units that it WITH's, all its subunits, and the bodies of any generics it instantiates must be around (findable by the search paths mechanism described above), or you will get a fatal error message. 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 --------------- Operating in default mode, GNAT requires that file names match compilation unit names. The default matching rules are as follows: o The file name is obtained by replacing dots in the unit name with minus signs, and adding a suffix distinguishing bodies and specs. The suffix for specs is ".ads" and for bodies is ".adb". For example, files containing the unit very_long_unit_name would be called: very_long_unit_name.ads very_long_unit_name.adb on systems supporting long file names. o When running under systems which permit only short file names, (like DOS and OS/2 under FAT) the file name itself needs to be crunched to 8 characters. You can always find out the name it expects by running gnatk8 or compiling it (since it warns you if it's wrong). So in DOS or OS/2 under FAT the filenames above would be crunched to: velounna.ads velounna.adb (The full details of the crunching algorithm are in source code of krunch.ads and krunch.adb) Under DOS -gnatk8 is the default, so crunching always takes place. On all systems the RTL files are all crunched to 8 characters. GNAT specific pragmas and attributes ------------------------------------ Full documentation of the GNAT specific pragmas and attributes can be found in the file features which is included in all releases of GNAT. pragma Source_File_Name ----------------------- The source file name pragma allows a program to override the normal naming convention. It is a configuration pragma, and so has the usual applicability of configuration pragmas (i.e. it applies to either an entire partition, or to all units in a compilation, or to a single unit, depending on how it is used. The form of the pragma is: pragma Source_File_Name ( [UNIT_NAME =>] unit_NAME, [BODY_FILE_NAME | SPEC_FILE_NAME] => STRING_LITERAL) The given unit name is mapped to the given file name. The identifier for the second argument is required, and indicates whether this is the file name for the spec or for the body. Any number of Source_File_Name pragmas can be put in a file called gnat.adc and will apply to compilations in the current directory. Unless the extension of the filename is ".ads", ".adb", or ".ada", you must prefix the filename with "-x ada" on the gcc command you use to compile it. That prefix applies to all subsequent filenames on the command unless you disable it with "-x none". Machine Code Insertions ----------------------- Package Machine_Code provides machine code support as described in the RM in two separate forms: Machine code statements, consisting of qualified expressions that fit the requirements of RM section 13.8. An intrinsic callable procedure, providing an alternative mechanism of including machine instructions in a subprogram. The two features are similar, and both closely related to the mechanism provided by the asm instruction in the GNU C cmpiler. Full understanding and use of the facilities in this package requires understanding the asm instruction as described in "Using and Porting GNU CC" by Richard Stallman. Calls to the function Asm and the procedure Asm have identical semantic restrictions and effects as described below. Both are provided so that the procedure call can be used as a statement, and the function call can be used to form a code_statement. The first example given in the GNU CC documentation is the C asm instruction: asm ("fsinx %1 %0" : "=f" (result) : "f" (angle)); The equivalent can be written for GNAT as: Asm ("fsinx %1 %0", My_Float'Asm_Output ("=f", access), My_Float'Asm_Input ("f", angle)); The first argument to Asm is the assembler template, and is identical to what is used in GNU CC. This string must be a static expression. The second argument is the output operand list. It is either a single Asm_Output attribute reference, or a list of such references enclosed in parentheses (technically an array aggregate of such references). The Asm_Output attribute denotes a function that takes two parameters. The first is a string, the second is the name of a variable of the type designated by the attribute prefix. The first (string) argument is required to be a static expression and designates the constraint for the parameter (e.g. what kind of register is required). The second argument is the variable to be updated with the result. The possible values for constraint are the same as those used in the RTL, and are dependent on the configuration file used to build the GCC back end. If there are no output operands, then this argument may either be omitted, or explicitly given as No_Output_Operands. Note: the second argument of My_Float'Asm_Output functions as though it were an OUT parameter, which is a little curious, but all names have the form of expressions, so there is no syntactic irregularity, even though normally functions would not be permitted OUT parameters. The third argument is the list of input operands. It is either a single Asm_Input attribute reference, or a list of such references enclosed in parentheses (technically an array aggregate of such references). The Asm_Input attribute denotes a function that takes two parameters. The first is a string, the second is an expression of the type designated by the prefix. The first (string) argument is required to be a static expression, and is the constraint for the parameter, (e.g. what kind of register is required). The second argument is the value to be used as the input argument. The possible values for the constrant are the same as those used in the RTL, and are dependent on the configuration file used to built the GCC back end. If there are no input operands, then this argument may either be omitted, or explicitly given as No_Input_Operands. The fourth argument, not present in the above example, is a list of register names, called the "clobber" argument. This argument, if given, must be a static string expression, and is a space or comma separated list of names of registers that must be considered destroyed as a result of the Asm call. If this argument is the null string (the default value), then the code generator assumes that no additional registers are destroyed. The fifth argument, not present in the above example, called the "volatile" argument, is by default False, it can be set to the literal value True to indicate to the code generator that all optimizations with respect to the instruction specified should be suppressed, and that in particular, for an instruction that has outputs, the instruction will still be generated, even if none of the outputs are used. See the full description in the GCC manual for further details. The Asm subprograms may be used in two ways. First the procedure forms can be used anywhere a procedure call would be valid, and correspond to what the RM calls "intrinsic" routines. Such calls can be used to intersperse machine instructions with other Ada statements. Second, the function forms, which return a (dummy) value of the limited private type Asm_Insn, can be used in code statements, and indeed this is the only context where such calls are allowed. Code statements appear as aggregates of the form: Asm_Insn'(Asm ( .....)); Asm_Insn'(Asm_Volatile (....)); In accordance with RM rules, such code statements are allowed only within subprograms whose entire body consists of such statements. It is not permissible to intermix such statements with other Ada statements. Typically the form using intrinsic procedure calls is more convenient and more flexible. The code statement form is provided to meet the RM suggestion that such a facility should be made available. The following is the exact syntax of the call to asm (of course if named notation is used, the arguments may be given in arbitrary order, following the normal rules for use of positional and named arguments) ASM_CALL ::= asm ( [Template =>] static_string_EXPRESSION [,[Outputs =>] OUTPUT_OPERAND_LIST ] [,[Inputs =>] INPUT_OPERAND_LIST ] [,[Clobber =>] static_string_EXPRESSION ] [,[Volatile =>] static_boolean_EXPRESSION] ) OUTPUT_OPERAND_LIST ::= No_Output_Operands | OUTPUT_OPERAND_ATTRIBUTE | (OUTPUT_OPERAND_ATTRIBUTE {,OUTPUT_OPERAND_ATTRIBUTE}) OUTPUT_OPERAND_ATTRIBUTE ::= SUBTYPE_MARK'Asm_Output (static_string_EXPRESSION, NAME) INPUT_OPERAND_LIST ::= No_Input_Operands | INPUT_OPERAND_ATTRIBUTE | (INPUT_OPERAND_ATTRIBUTE {,INPUT_OPERAND_ATTRIBUTE}) INPUT_OPERAND_ATTRIBUTE ::= SUBTYPE_MARK'Asm_Input (static_string_EXPRESSION, EXPRESSION) 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: - A compilation unit which is withed but never used (this works with child library units as well). - A compilation unit which is withed in a body (resp. subunit) if the same with clause already appears in the spec (resp. spec or body for subunits). - A compilation unit which is withed within a spec but is used only by the body or a subunit. -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: - Record fields, since they could be referenced indirectly by an aggregate. - Enumeration entities, since they could be referenced indirectly by enumeration ranges: for i in Color'First .. Color'Last - Loop parameters for I in 1 .. 80 loop Put ('x'); end loop; -x[345] Generate cross-reference information. Flag -x3 gives the most succinct 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: * The full graph of the source files directly or indirectly loaded as a result of compiling "Unit" along with their time stamp. This graph includes the with-ed unit graph rooted at "Unit" but contains also other units automatically loaded by gnat during code generation (generic bodies, subunits, bodies of inlined subprograms). This graph is created only for flags -x[345]. * The list of entities that can be exported from "Unit" to other Ada sources along with their line and column of definition and use in "Unit". If "Unit" is a subprogram or package spec, the notion of exported entity matches the set of entities listed therein. If "Unit" is a package body with no generics or inlined subprograms then no entities are exported. In general, however, the set of entities exported from "Unit" is the set of entities that are needed across compilation units by gnat when generating code. Specifically inlined subprogram bodies or generic bodies are always exported since these are inlined at the point of use or instantiation. The same happens for subunits, which are inlined in the parent unit. The difference between flags -x3 and -x4 is that -x3 omits all generic bodies or inlined subprograms from the exported entities, while flag -x4 includes them. Both -x3 and -x4 consider subunits as exported entities. In addition we only consider outermost visible entities to be exported. That is a record or enumeration type may be exported but its inner fields or enumeration literals are never considered exported entities. Likewise for subprogram parameters and discriminants. * The list of entities *directly* imported by "Unit" from other Ada sources, along with their lines and columns where they are used in "Unit". The notion of imported entities falls off the notion of exported entities (what is exported by one unit may be imported by another). 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: The function must have one of the five standard names There must be two arguments The first argument can be of any integer type with a size of 8, 16, 32, 64 either signed or unsigned. The return type must be the same as the first argument type The second argument (the shift count), can be of any integer type 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). GNAT Trouble-Shooting. ---------------------- 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 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 has been modified to handle most of Ada properly. Forthcoming Gdb releases will be ada-aware. For the time being the distribution contains the appropriate gdb patches (for more info send an e-mail to report@gnat.com). Note that you can still debug your Ada programs by using Gdb, even if you have not yet installed the `Ada aware' Gdb patches provided you use the standard C syntax in Gdb and use the following naming conventions to find the Ada entities defined in your program: a) The names of all entities (variables, subprograms, etc.) are converted to lower case. b) 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. PERFORMANCE CONSIDERATIONS -------------------------- The GNAT system provides a number of options that allow a trade off between o performance of the generated code o speed of compilation o minimization of dependencies and recompilation o degree of runtime checking The defaults if no options are selected are aimed at improving the speed of compilation and minimizing dependences at the expense of performance of the generated code: o no optimization o no inlining of subprogram calls o all runtime checks enabled except overflow and elaboration checks These options are suitable for most program development purposes. This section of the documentation describes how these options can be modified. Runtime Checks -------------- The default is to include all runtime checks except arithmetic overflow checking for integer operations (including division by zero), and checks for access before elaboration on subprogram calls. Two gcc switches allow this default to be modified: -gnatp This switch suppresses all runtime checks. This will improve the performance of the code at the expense of safety in the presence of invalid data or program bugs. -gnato This switch enables overflow checking for integer operations and checks for access before elaboration on subprogram calls. This will generate slower and larger executable programs. Our experience is that the default is suitable for most development purposes. The reason that we treat integer overflow and elaboration checks specially is that these are quite expensive, and in our experience are not so important as other runtime checks in the development process. Note that the setting of the switches controls the default setting of the checks. They may be modified using either Suppress (to remove checks) or Unsuppress (to add back suppressed checks) pragmas in the program source. Optimization Levels ------------------- The default is optimization off. This results in the fastest compile times, but GNAT makes absolutely no attempt to optimize, and the generated programs are considerably larger and slower. The switch -On where n is an integer from 0 to 3, can be used on the GCC command to control the optimization level: -O0 no optimization (the default) -O1 medium level optimization -O2 full optimization -O3 full optimization, and also attempt automatic inlining of small subprograms within a unit (see next section for further details). The penalty in compilation time, and the improvement in execution time, both depend on the particular application and the hardware environment. You should experiment to find the best level for your application. Note: unlike the case with some other compiler systems, GCC has been tested extensively at all optimization levels. There are some bugs which appear only with optimization turned on, but there have also been bugs which show up only in unoptimized code. Selecting a lower level of optimization does not improve the reliability of the code generator, which in practice is highly reliable at all optimization levels. Inlining of Subprograms ----------------------- A call to a subprogram in the current unit is inlined if all the following conditions are met: o The optimization level is at least -O1 o The called subprogram is suitable for inlining. It must be small enough and not contain nested subprograms or anything else that GCC cannot support in inlined subprograms. o The call occurs after the definition of the body of the subprogram. o Either pragma Inline applies to the subprogram, or it is very small and automatic inlining (optimization level -O3) is specified. Calls to subprograms in with'ed units are normally not inlined. To achieve this level of inlining, the following conditions must be true. o The optimization level is at least -O1 o The called subprogram is suitable for inlining. It must be small enough and not contain nested subprograms or anything else that GCC cannot support in inlined subprograms. o The call appears in a body (not in a package spec). o There is a pragma Inline for the subprogram o The -gnatn switch is used in the GCC command line Note that specifying the -gnatn switch causes additional compilation dependencies. Consider the following: package R is procedure Q; pragma Inline Q; end R; package body R is ... end R; with R; procedure Main is begin ... R.Q; end Main; With the default behavior (no -gnatn switch specified), the compilation of the Main procedure depends only on its own source, main.adb, and the spec of the package in file r.ads. This means that editing the body of R does not require recompiling Main. On the other hand, the call R.Q is not inlined under these circumstances. If the -gnatn switch is present when Main is compiled, then the call will be inlined if the body of Q is small enough, but now Main depends on the body of R in r.adb as well as the spec. This means that if the body is edited, then the main program must be recompiled. Note that this extra dependency occurs whether or not the call is in fact inlined by GCC. Note: the GCC switch -fno-inline can be used to prevent all inlining. This switch overrides all other conditions, and ensures that no inlining occurs. The extra dependencies resulting from -gnatn will still be active, even if the -fno-inline switch is used. 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 ------------------------ Everything is copyrighted 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 is possible to use GNAT to generate software that is not itself covered by the GNU license. This is because all library and runtime units are covered by a modified version of the GPL which explicitly permits this use. 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 try to process all bug reports from both users supported by Ada Core Technologies, and from unsupported users. Naturally supported users have our priority attention, so we cannot guarantee any specific response for unsupported users. We only receive bug reports by internet, addressed to report@gnat.com. 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 report@gnat.com To contact team members, send messages to: banner@gnat.com comar@gnat.com cruz@gnat.com dewar@gnat.com dismukes@gnat.com kenner@gnat.com rupp@gnat.com schenker@gnat.com schonberg@gnat.com or visit our home page at http://www.gnat.com 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. 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://www.gnat.com The home page of Ada Core Technologies, the maintainers of GNAT 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.