ada: Update GNAT UG

Also add some LLVM-specific information.

gcc/ada/ChangeLog:

	* doc/gnat_ugn/about_this_guide.rst: Numerous changes to language
	and style and add some LLVM-specific information.
	* doc/gnat_ugn/elaboration_order_handling_in_gnat.rst: Likewise.
	* doc/gnat_ugn/example_of_binder_output.rst: Likewise.
	* doc/gnat_ugn/getting_started_with_gnat.rst: Likewise.
	* doc/gnat_ugn/gnat_and_program_execution.rst: Likewise.
	* doc/gnat_ugn/gnat_utility_programs.rst: Likewise.
	* doc/gnat_ugn/inline_assembler.rst: Likewise.
	* doc/gnat_ugn/platform_specific_information.rst: Likewise.
	* doc/gnat_ugn/the_gnat_compilation_model.rst: Likewise.
	* gnat_ugn.texi: Regenerate.
This commit is contained in:
Richard Kenner 2024-09-05 13:37:33 -04:00 committed by Marc Poulhiès
parent 8af9169fcf
commit 257d0d7769
10 changed files with 4762 additions and 4689 deletions

View File

@ -14,13 +14,13 @@ toolset for the full Ada programming language.
It documents the features of the compiler and tools, and explains
how to use them to build Ada applications.
GNAT implements Ada 95, Ada 2005, Ada 2012, and Ada 202x, and it may also be
invoked in Ada 83 compatibility mode.
By default, GNAT assumes Ada 2012, but you can override with a
compiler switch (:ref:`Compiling_Different_Versions_of_Ada`)
to explicitly specify the language version.
Throughout this manual, references to 'Ada' without a year suffix
apply to all Ada versions of the language, starting with Ada 95.
GNAT implements Ada 95, Ada 2005, Ada 2012, and Ada 2022. You may
also invoke it in Ada 83 compatibility mode. By default, GNAT assumes
Ada 2012, but you can use a compiler switch
(:ref:`Compiling_Different_Versions_of_Ada`) to explicitly specify the
language version. Throughout this manual, references to 'Ada' without
a year suffix apply to all versions of the Ada language starting with
Ada 95.
What This Guide Contains
========================
@ -130,10 +130,10 @@ in this guide:
and then shown this way.
* Commands that are entered by the user are shown as preceded by a prompt string
* Commands that you enter are shown as preceded by a prompt string
comprising the ``$`` character followed by a space.
* Full file names are shown with the '/' character
as the directory separator; e.g., :file:`parent-dir/subdir/myfile.adb`.
If you are using GNAT on a Windows platform, please note that
the '\\' character should be used instead.
you should use the '\\' character instead.

View File

@ -17,8 +17,8 @@ Elaboration Order Handling in GNAT
.. index:: Order of elaboration
.. index:: Elaboration control
This appendix describes the handling of elaboration code in Ada and GNAT, and
discusses how the order of elaboration of program units can be controlled in
This appendix describes the handling of elaboration code in Ada and GNAT and
discusses how you can control the order of elaboration of program units in
GNAT, either automatically or with explicit programming features.
.. _Elaboration_Code:
@ -36,7 +36,7 @@ initializing data. These sections are referred to as **elaboration code**.
Elaboration code is executed as follows:
* All partitions of an Ada program are executed in parallel with one another,
possibly in a separate address space, and possibly on a separate computer.
possibly in a separate address space and possibly on a separate computer.
* The execution of a partition involves running the environment task for that
partition.
@ -71,8 +71,9 @@ In addition to the Ada terminology, this appendix defines the following terms:
* *Target*
A construct elaborated by a scenario is referred to as *elaboration target*
or simply **target**. GNAT recognizes the following targets:
A construct elaborated by a scenario is referred to as an
*elaboration target* or simply a **target**. GNAT recognizes the
following targets:
- For ``'Access`` of entries, operators, and subprograms, the target is the
entry, operator, or subprogram being aliased.
@ -188,7 +189,8 @@ factors:
* invocations performed in elaboration code
A program may have several elaboration orders depending on its structure.
A program may have several possible elaboration orders depending on
its structure:
.. code-block:: ada
@ -256,7 +258,7 @@ Ada states that a total elaboration order must exist, but it does not define
what this order is. A compiler is thus tasked with choosing a suitable
elaboration order which satisfies the dependencies imposed by |with| clauses,
unit categorization, elaboration-control pragmas, and invocations performed in
elaboration code. Ideally an order that avoids ABE problems should be chosen,
elaboration code. Ideally, an order that avoids ABE problems should be chosen,
however a compiler may not always find such an order due to complications with
respect to control and data flow.
@ -277,7 +279,7 @@ provides three lines of defense:
* *Dynamic semantics*
Dynamic checks are performed at run time, to ensure that a target is
Dynamic checks are performed at run time to ensure that a target is
elaborated prior to a scenario that invokes it, thus avoiding ABE problems.
A failed run-time check raises exception ``Program_Error``. The following
restrictions apply:
@ -304,7 +306,7 @@ provides three lines of defense:
* *Elaboration control*
Pragmas are provided for the programmer to specify the desired elaboration
Ada provides pragmas for you to specify the desired elaboration
order.
.. _Controlling_the_Elaboration_Order_in_Ada:
@ -312,12 +314,12 @@ provides three lines of defense:
Controlling the Elaboration Order in Ada
========================================
Ada provides several idioms and pragmas to aid the programmer with specifying
the desired elaboration order and avoiding ABE problems altogether.
Ada provides several idioms and pragmas to aid you in specifying your
desired elaboration order and avoiding ABE problems.
* *Packages without a body*
A library package which does not require a completing body does not suffer
A library package that does not require a completing body does not suffer
from ABE problems.
.. code-block:: ada
@ -391,9 +393,9 @@ the desired elaboration order and avoiding ABE problems altogether.
body of Server
spec of Client
because the spec of ``Server`` must be elaborated prior to ``Client`` by
virtue of the |with| clause, and in addition the body of ``Server`` must be
elaborated immediately after the spec of ``Server``.
because the spec of ``Server`` must be elaborated prior to
``Client`` by virtue of the |with| clause and the body of ``Server``
must be elaborated immediately after the spec of ``Server``.
Removing pragma ``Elaborate_Body`` could result in the following incorrect
elaboration order:
@ -420,7 +422,7 @@ depend on.
* *pragma Elaborate (Unit)*
Pragma ``Elaborate`` can be placed in the context clauses of a unit, after a
You can place pragma ``Elaborate`` in the context clauses of a unit, after a
|with| clause. It guarantees that both the spec and body of its argument will
be elaborated prior to the unit with the pragma. Note that other unrelated
units may be elaborated in between the spec and the body.
@ -473,11 +475,12 @@ depend on.
* *pragma Elaborate_All (Unit)*
Pragma ``Elaborate_All`` is placed in the context clauses of a unit, after
a |with| clause. It guarantees that both the spec and body of its argument
will be elaborated prior to the unit with the pragma, as well as all units
|withed| by the spec and body of the argument, recursively. Note that other
unrelated units may be elaborated in between the spec and the body.
You can place pragma ``Elaborate_All`` in the context clauses of a
unit, after a |with| clause. It guarantees that both the spec and
body of its argument will be elaborated prior to the unit with the
pragma as well as all units |withed| by the spec and body of the
argument, recursively. Note that other unrelated units may be
elaborated in between the spec and the body.
.. code-block:: ada
@ -566,12 +569,12 @@ the server unit requires a body and does not have pragma Pure, Preelaborate,
or Elaborate_Body, then the client unit should have pragma Elaborate or
Elaborate_All for the server unit.*
If the rule outlined above is not followed, then a program may fall in one of
the following states:
If you do not follow the rule outlined above, a program may fall in one of
the following ways:
* *No elaboration order exists*
In this case a compiler must diagnose the situation, and refuse to build an
In this case a compiler must diagnose the situation and refuse to build an
executable program.
* *One or more incorrect elaboration orders exist*
@ -581,17 +584,17 @@ the following states:
* *Several elaboration orders exist, some correct, some incorrect*
In this case the programmer has not controlled the elaboration order. As a
result, a compiler may or may not pick one of the correct orders, and the
In this case, you have not controlled the elaboration order. As a
result, a compiler may or may not pick one of the correct orders and the
program may or may not raise ``Program_Error`` when it is run. This is the
worst possible state because the program may fail on another compiler, or
even another version of the same compiler.
worst possible state because the program may fail on another compiler or
even a different version of the same compiler.
* *One or more correct orders exist*
In this case a compiler can build an executable program, and the program is
In this case a compiler can build an executable program and the program is
run successfully. This state may be guaranteed by following the outlined
rules, or may be the result of good program architecture.
rules or may be the result of good program architecture.
Note that one additional advantage of using ``Elaborate`` and ``Elaborate_All``
is that the program continues to stay in the last state (one or more correct
@ -602,9 +605,9 @@ orders exist) even if maintenance changes the bodies of targets.
Controlling the Elaboration Order in GNAT
=========================================
In addition to Ada semantics and rules synthesized from them, GNAT offers
three elaboration models to aid the programmer with specifying the correct
elaboration order and to diagnose elaboration problems.
In addition to Ada semantics and rules synthesized from them, GNAT
offers three elaboration models to aid you in specifying the correct
elaboration order and in diagnosing elaboration problems.
.. index:: Dynamic elaboration model
@ -631,7 +634,7 @@ elaboration order and to diagnose elaboration problems.
assumptions stated above. An order obtained using the dynamic model may fail
an ABE check at run time when GNAT ignored an invocation.
The dynamic model is enabled with compiler switch :switch:`-gnatE`.
You enable the dynamic model with the compiler switch :switch:`-gnatE`.
.. index:: Static elaboration model
@ -678,24 +681,25 @@ elaboration order and to diagnose elaboration problems.
following legacy models:
- `Legacy elaboration-checking model` available in pre-18.x versions of GNAT.
This model is enabled with compiler switch :switch:`-gnatH`.
You can enable this model with compiler switch :switch:`-gnatH`.
- `Legacy elaboration-order model` available in pre-20.x versions of GNAT.
This model is enabled with binder switch :switch:`-H`.
You can enable this model with binder switch :switch:`-H`.
.. index:: Relaxed elaboration mode
The dynamic, legacy, and static models can be relaxed using compiler switch
:switch:`-gnatJ`, making them more permissive. Note that in this mode, GNAT
may not diagnose certain elaboration issues or install run-time checks.
You can relax the dynamic, legacy, and static models by specifying
compiler switch :switch:`-gnatJ`, which makes them more permissive. Note
that in this mode, GNAT may not diagnose certain elaboration issues or
install run-time checks.
.. _Mixing_Elaboration_Models:
Mixing Elaboration Models
=========================
It is possible to mix units compiled with a different elaboration model,
however the following rules must be observed:
You can mix units compiled with different elaboration models. However
you must observe the following rules:
* A client unit compiled with the dynamic model can only |with| a server unit
that meets at least one of the following criteria:
@ -718,7 +722,7 @@ violated, the binder emits a warning:
warning: "x.ads" has dynamic elaboration checks and with's
warning: "y.ads" which has static elaboration checks
The warnings can be suppressed by binder switch :switch:`-ws`.
You can suppress these warnings by specifying binder switch :switch:`-ws`.
.. _ABE_Diagnostics:
@ -729,14 +733,14 @@ GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
that invoke internal targets, regardless of whether the dynamic, SPARK, or
static model is in effect.
Note that GNAT emits warnings rather than hard errors whenever it encounters an
Note that GNAT emits warnings rather than errors whenever it encounters an
elaboration problem. This is because the elaboration model in effect may be too
conservative, or a particular scenario may not be invoked due conditional
execution. The warnings can be suppressed selectively with ``pragma Warnings
conservative or a particular scenario may not be invoked due to conditional
execution. You can selectively suppress the warnings with ``pragma Warnings
(Off)`` or globally with compiler switch :switch:`-gnatwL`.
A *guaranteed ABE* arises when the body of a target is not elaborated early
enough, and causes *all* scenarios that directly invoke the target to fail.
enough and causes *all* scenarios that directly invoke the target to fail.
.. code-block:: ada
@ -763,7 +767,7 @@ the declaration of ``Val``. This invokes function ``ABE``, however the body of
>>> warning: Program_Error will be raised at run time
A *conditional ABE* arises when the body of a target is not elaborated early
enough, and causes *some* scenarios that directly invoke the target to fail.
enough and causes *some* scenarios that directly invoke the target to fail.
.. code-block:: ada
@ -821,8 +825,8 @@ SPARK Diagnostics
=================
GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference
Manual section 7.7 when compiler switch :switch:`-gnatd.v` is in effect. Note
that GNAT emits hard errors whenever it encounters a violation of the SPARK
Manual section 7.7 when you specify compiler switch :switch:`-gnatd.v`. Note
that GNAT emits errors whenever it encounters a violation of the SPARK
rules.
::
@ -938,7 +942,7 @@ subprograms, where the program controls the order of initialization explicitly.
Although this is the most desirable option, it may be impractical and involve
too much modification, especially in the case of complex legacy code.
When faced with an elaboration circularity, the programmer should also consider
When faced with an elaboration circularity, you should also consider
the tactics given in the suggestions section of the circularity diagnostic.
Depending on the units involved in the circularity, their |with| clauses,
purity, preelaborability, presence of elaboration-control pragmas and
@ -951,10 +955,9 @@ following tactics to eliminate the circularity:
remove pragma Elaborate for unit "..." in unit "..."
This tactic is suggested when the binder has determined that pragma
``Elaborate``:
The binder suggests this tactic when it has determined that:
- Prevents a set of units from being elaborated.
- pragma ``Elaborate`` prevents a set of units from being elaborated.
- The removal of the pragma will not eliminate the semantic effects of the
pragma. In other words, the argument of the pragma will still be elaborated
@ -962,7 +965,7 @@ following tactics to eliminate the circularity:
- The removal of the pragma will enable the successful ordering of the units.
The programmer should remove the pragma as advised, and rebuild the program.
You should remove the pragma as advised and rebuild the program.
* Pragma Elaborate_All elimination
@ -970,10 +973,10 @@ following tactics to eliminate the circularity:
remove pragma Elaborate_All for unit "..." in unit "..."
This tactic is suggested when the binder has determined that pragma
``Elaborate_All``:
The binder suggests this tactic when it has determined that:
- Prevents a set of units from being elaborated.
- pragma ``Elaborate_All`` prevents a set of units from being
elaborated.
- The removal of the pragma will not eliminate the semantic effects of the
pragma. In other words, the argument of the pragma along with its |with|
@ -981,7 +984,7 @@ following tactics to eliminate the circularity:
- The removal of the pragma will enable the successful ordering of the units.
The programmer should remove the pragma as advised, and rebuild the program.
You should remove the pragma as advised and rebuild the program.
* Pragma Elaborate_All downgrade
@ -989,12 +992,12 @@ following tactics to eliminate the circularity:
change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
This tactic is always suggested with the pragma ``Elaborate_All`` elimination
tactic. It offers a different alternative of guaranteeing that the argument
of the pragma will still be elaborated prior to the unit containing the
pragma.
The binder always suggests this tactic when it suggests the pragma
``Elaborate_All`` elimination tactic. It offers a different
alternative of guaranteeing that the argument of the pragma will
still be elaborated prior to the unit containing the pragma.
The programmer should update the pragma as advised, and rebuild the program.
You should update the pragma as advised and rebuild the program.
* Pragma Elaborate_Body elimination
@ -1002,10 +1005,9 @@ following tactics to eliminate the circularity:
remove pragma Elaborate_Body in unit "..."
This tactic is suggested when the binder has determined that pragma
``Elaborate_Body``:
The binder suggests this tactic when it has determined that:
- Prevents a set of units from being elaborated.
- pragma ``Elaborate_Body`` prevents a set of units from being elaborated.
- The removal of the pragma will enable the successful ordering of the units.
@ -1013,7 +1015,8 @@ following tactics to eliminate the circularity:
other purposes, such as guaranteeing the initialization of a variable
declared in the spec by elaboration code in the body.
The programmer should remove the pragma as advised, and rebuild the program.
If the pragma is not required for another purpose, you should remove
the pragma as advised and rebuild the program.
* Use of pragma Restrictions
@ -1021,7 +1024,7 @@ following tactics to eliminate the circularity:
use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code)
This tactic is suggested when the binder has determined that a task
The binder suggests this tactic when it has determined that a task
activation at elaboration time:
- Prevents a set of units from being elaborated.
@ -1046,16 +1049,16 @@ following tactics to eliminate the circularity:
- The use of the dynamic model will enable the successful ordering of the
units.
The programmer has two options:
You have two options:
- Determine the units involved in the invocation using the detailed
invocation information, and add compiler switch :switch:`-gnatE` to the
compilation arguments of selected files only. This approach will yield
invocation information and add compiler switch :switch:`-gnatE` to the
compilation arguments of those units only. This approach will yield
safer elaboration orders compared to the other option because it will
minimize the opportunities presented to the dynamic model for ignoring
invocations.
- Add compiler switch :switch:`-gnatE` to the general compilation arguments.
- Add compiler switch :switch:`-gnatE` to the global compilation arguments.
* Use of detailed invocation information
@ -1063,13 +1066,13 @@ following tactics to eliminate the circularity:
use detailed invocation information (compiler switch -gnatd_F)
This tactic is always suggested with the use of the dynamic model tactic. It
causes the circularity section of the circularity diagnostic to describe the
flow of elaboration code from a unit to a unit, enumerating all such paths in
the process.
The binder always suggests this tactic when it suggests use of the
dynamic model tactic. It causes the circularity section of the
circularity diagnostic to describe the flow of elaboration code from
a unit to a unit, enumerating all such paths in the process.
The programmer should analyze this information to determine which units
should be compiled with the dynamic model.
You should analyze this information to determine which units should
be compiled with the dynamic model.
* Forced-dependency elimination
@ -1077,16 +1080,16 @@ following tactics to eliminate the circularity:
remove the dependency of unit "..." on unit "..." from the argument of switch -f
This tactic is suggested when the binder has determined that a dependency
present in the forced-elaboration-order file indicated by binder switch
:switch:`-f`:
The binder suggests this tactic when it has determined that a
dependency present in the forced-elaboration-order file indicated by
binder switch :switch:`-f`:
- Prevents a set of units from being elaborated.
- The removal of the dependency will enable the successful ordering of the
units.
The programmer should edit the forced-elaboration-order file, remove the
You should edit the forced-elaboration-order file, remove the
dependency, and rebind the program.
* All forced-dependency elimination
@ -1095,11 +1098,11 @@ following tactics to eliminate the circularity:
remove switch -f
This tactic is suggested in case editing the forced-elaboration-order file is
not an option.
The binder suggests this tactic when editing the
forced-elaboration-order file is not an option.
The programmer should remove binder switch :switch:`-f` from the binder
arguments, and rebind.
You should remove binder switch :switch:`-f` from the binder
arguments and rebind.
* Multiple-circularities diagnostic
@ -1107,16 +1110,16 @@ following tactics to eliminate the circularity:
diagnose all circularities (binder switch -d_C)
By default, the binder will diagnose only the highest-precedence circularity.
If the program contains multiple circularities, the binder will suggest the
use of binder switch :switch:`-d_C` in order to obtain the diagnostics of all
circularities.
By default, the binder only diagnoses the highest-precedence
circularity. If the program contains multiple circularities, the
binder will suggest the use of binder switch :switch:`-d_C` in order
to obtain the diagnostics for each circularity.
The programmer should add binder switch :switch:`-d_C` to the binder
arguments, and rebind.
You should add binder switch :switch:`-d_C` to the binder arguments
and rebind.
If none of the tactics suggested by the binder eliminate the elaboration
circularity, the programmer should consider using one of the legacy elaboration
circularity, you should consider using one of the legacy elaboration
models, in the following order:
* Use the pre-20.x legacy elaboration-order model, with binder switch
@ -1150,7 +1153,7 @@ the elaboration order chosen by the binder.
.. index:: -gnatel (gnat)
:switch:`-gnatel`
Turn on info messages on generated Elaborate[_All] pragmas
Turn on informational messages on generated Elaborate[_All] pragmas
This switch is only applicable to the pre-20.x legacy elaboration models.
The post-20.x elaboration model no longer relies on implicitly generated
@ -1280,23 +1283,23 @@ the elaboration order chosen by the binder.
Summary of Procedures for Elaboration Control
=============================================
A programmer should first compile the program with the default options, using
You should first compile the program with the default options, using
none of the binder or compiler switches. If the binder succeeds in finding an
elaboration order, then apart from possible cases involving dispatching calls
and access-to-subprogram types, the program is free of elaboration errors.
If it is important for the program to be portable to compilers other than GNAT,
then the programmer should use compiler switch :switch:`-gnatel` and consider
the messages about missing or implicitly created ``Elaborate`` and
``Elaborate_All`` pragmas.
If it is important for the program to be portable to compilers other
than GNAT, you should use compiler switch :switch:`-gnatel` and
consider the messages about missing or implicitly created
``Elaborate`` and ``Elaborate_All`` pragmas.
If the binder reports an elaboration circularity, the programmer has several
If the binder reports an elaboration circularity, you have several
options:
* Ensure that elaboration warnings are enabled. This will allow the static
* Ensure that elaboration warnings are enabled. This allows the static
model to output trace information of elaboration issues. The trace
information could shed light on previously unforeseen dependencies, as well
as their origins. Elaboration warnings are enabled with compiler switch
information could shed light on previously unforeseen dependencies as well
as their origins. You enable elaboration warnings with compiler switch
:switch:`-gnatwl`.
* Cosider the tactics given in the suggestions section of the circularity

View File

@ -7,7 +7,7 @@ Example of Binder Output File
.. index:: Binder output (example)
This Appendix displays the source code for the output file
generated by *gnatbind* for a simple 'Hello World' program.
generated by ``gnatbind`` for a simple 'Hello World' program.
Comments have been added for clarification purposes.
@ -24,8 +24,7 @@ Comments have been added for clarification purposes.
-- The main program saves the parameters (argument count,
-- argument values, environment pointer) in global variables
-- for later access by other units including
-- Ada.Command_Line.
-- for later access by other units including Ada.Command_Line.
gnat_argc : Integer;
gnat_argv : System.Address;
@ -400,8 +399,8 @@ Comments have been added for clarification purposes.
package body ada_main is
pragma Warnings (Off);
-- These values are reference counter associated to units which have
-- been elaborated. It is also used to avoid elaborating the
-- These values are reference counters associated with units that have
-- been elaborated. They are used to avoid elaborating the
-- same unit twice.
E72 : Short_Integer; pragma Import (Ada, E72, "system__os_lib_E");
@ -559,8 +558,8 @@ Comments have been added for clarification purposes.
-- Now we have the elaboration calls for all units in the partition.
-- The Elab_Spec and Elab_Body attributes generate references to the
-- implicit elaboration procedures generated by the compiler for
-- each unit that requires elaboration. Increment a counter of
-- reference for each unit.
-- each unit that requires elaboration. Also increment a reference
-- counter for each unit.
System.Soft_Links'Elab_Spec;
System.Exception_Table'Elab_Body;
@ -625,11 +624,10 @@ Comments have been added for clarification purposes.
end adafinal;
-- We get to the main program of the partition by using
-- pragma Import because if we try to with the unit and
-- call it Ada style, then not only do we waste time
-- recompiling it, but also, we don't really know the right
-- switches (e.g.@: identifier character set) to be used
-- to compile it.
-- pragma Import because if we try to 'with' the unit and
-- call it in Ada style, not only do we waste time recompiling it,
-- but we don't know the right switches (e.g.@: identifier
-- character set) to be used to compile it.
procedure Ada_Main_Program;
pragma Import (Ada, Ada_Main_Program, "_ada_hello");
@ -734,9 +732,9 @@ binder. We have added comments to more clearly indicate the function
of each part of the generated ``Ada_Main`` package.
The code is standard Ada in all respects, and can be processed by any
tools that handle Ada. In particular, it is possible to use the debugger
tools that handle Ada. In particular, you can use the debugger
in Ada mode to debug the generated ``Ada_Main`` package. For example,
suppose that for reasons that you do not understand, your program is crashing
suppose that for reasons you don't understand, your program is crashing
during elaboration of the body of ``Ada.Text_IO``. To locate this bug,
you can place a breakpoint on the call:
@ -745,5 +743,5 @@ you can place a breakpoint on the call:
Ada.Text_Io'Elab_Body;
and trace the elaboration routine for this package to find out where
the problem might be (more usually of course you would be debugging
the problem might be (more usually, of course, you would be debugging
elaboration code in your own application).

View File

@ -22,57 +22,58 @@ For information on GNAT Studio please refer to the
System Requirements
===================
Even though any machine can run the GNAT toolset and GNAT Studio IDE, in order
to get the best experience, we recommend using a machine with as many cores
as possible since all individual compilations can run in parallel.
Even though any machine can run the GNAT toolset and GNAT Studio IDE,
to get the best experience we recommend using a machine with as many cores
as possible, allowing individual compilations to run in parallel.
A comfortable setup for a compiler server is a machine with 24 physical cores
or more, with at least 48 GB of memory (2 GB per core).
For a desktop machine, a minimum of 4 cores is recommended (8 preferred),
For a desktop machine, we recommend a minimum of 4 cores (8 is preferred),
with at least 2GB per core (so 8 to 16GB).
In addition, for running and navigating sources in GNAT Studio smoothly, we
recommend at least 1.5 GB plus 3 GB of RAM per 1 million source line of code.
In other words, we recommend at least 3 GB for for 500K lines of code and
In addition, for running and smoothly navigating sources in GNAT Studio, we
recommend at least 1.5 GB, plus 3 GB of RAM per million source lines of code.
So we recommend at least 3 GB for 500K lines of code and
7.5 GB for 2 million lines of code.
Note that using local and fast drives will also make a difference in terms of
build and link time. Network drives such as NFS, SMB, or worse, configuration
management filesystems (such as ClearCase dynamic views) should be avoided as
much as possible and will produce very degraded performance (typically 2 to 3
times slower than on local fast drives). If such slow drives cannot be avoided
for accessing the source code, then you should at least configure your project
file so that the result of the compilation is stored on a drive local to the
machine performing the run. This can be achieved by setting the ``Object_Dir``
project file attribute.
Using fast, local drives can make a significant difference in build
and link times. You should avoid network drives such as NFS, SMB, or
worse, configuration management filesystems (such as ClearCase dynamic
views) as much as possible since these will produce very degraded
performance (typically 2 to 3 times slower than on fast, local
drives). If you cannot avoid using such slow drives for accessing
source code, you should at least configure your project file so
the result of the compilation is stored on a drive local to the
machine performing the compilation. You can do this by setting the
``Object_Dir`` project file attribute.
.. _Running_GNAT:
Running GNAT
============
Three steps are needed to create an executable file from an Ada source
file:
You need to take three steps to create an executable file from an Ada
source file:
* The source file(s) must be compiled.
* The file(s) must be bound using the GNAT binder.
* All appropriate object files must be linked to produce an executable.
* You must compile the source file(s).
* You must bind the file(s) using the GNAT binder.
* You must link all appropriate object files to produce an executable.
All three steps are most commonly handled by using the ``gnatmake``
utility program that, given the name of the main program, automatically
performs the necessary compilation, binding and linking steps.
You most commonly perform all three steps by using the ``gnatmake``
utility program. You pass it the name of the main program and it automatically
performs the necessary compilation, binding, and linking steps.
.. _Running_a_Simple_Ada_Program:
Running a Simple Ada Program
============================
Any text editor may be used to prepare an Ada program.
(If Emacs is used, the optional Ada mode may be helpful in laying out the
You may use any text editor to prepare an Ada program.
(If you use Emacs, an optional Ada mode may be helpful in laying out the
program.)
The program text is a normal text file. We will assume in our initial
example that you have used your editor to prepare the following
standard format text file:
standard format text file named :file:`hello.adb`:
.. code-block:: ada
@ -83,21 +84,18 @@ standard format text file:
Put_Line ("Hello WORLD!");
end Hello;
This file should be named :file:`hello.adb`.
With the normal default file naming conventions, GNAT requires
that each file
contain a single compilation unit whose file name is the
unit name,
with periods replaced by hyphens; the
unit name with periods replaced by hyphens; the
extension is :file:`ads` for a
spec and :file:`adb` for a body.
You can override this default file naming convention by use of the
special pragma ``Source_File_Name`` (for further information please
see :ref:`Using_Other_File_Names`).
special pragma ``Source_File_Name`` (see :ref:`Using_Other_File_Names`).
Alternatively, if you want to rename your files according to this default
convention, which is probably more convenient if you will be using GNAT
for all your compilations, then the ``gnatchop`` utility
can be used to generate correctly-named source files
for all your compilations, then you use can use the ``gnatchop`` utility
to generate correctly-named source files
(see :ref:`Renaming_Files_with_gnatchop`).
You can compile the program using the following command (``$`` is used
@ -108,16 +106,16 @@ as the command prompt in the examples in this document):
$ gcc -c hello.adb
``gcc`` is the command used to run the compiler. This compiler is
``gcc`` is the command used to run the compiler. It is
capable of compiling programs in several languages, including Ada and
C. It assumes that you have given it an Ada program if the file extension is
either :file:`.ads` or :file:`.adb`, and it will then call
C. It assumes you have given it an Ada program if the file extension is
either :file:`.ads` or :file:`.adb`, in which case it will call
the GNAT compiler to compile the specified file.
The :switch:`-c` switch is required. It tells ``gcc`` to only do a
compilation. (For C programs, ``gcc`` can also do linking, but this
capability is not used directly for Ada programs, so the :switch:`-c`
switch must always be present.)
capability is not used directly for Ada programs, so you must always
specify the :switch:`-c`.)
This compile command generates a file
:file:`hello.o`, which is the object
@ -126,11 +124,11 @@ an 'Ada Library Information' file :file:`hello.ali`,
which contains additional information used to check
that an Ada program is consistent.
To build an executable file, use either ``gnatmake`` or gprbuild with
the name of the main file: these tools are builders that will take care of
To build an executable file, use either ``gnatmake`` or ``gprbuild`` with
the name of the main file: these tools are builders that perform
all the necessary build steps in the correct order.
In particular, these builders automatically recompile any sources that have
been modified since they were last compiled, or sources that depend
been modified since they were last compiled, as well as sources that depend
on such modified sources, so that 'version skew' is avoided.
.. index:: Version skew (avoided by ``gnatmake``)
@ -139,7 +137,7 @@ on such modified sources, so that 'version skew' is avoided.
$ gnatmake hello.adb
The result is an executable program called :file:`hello`, which can be
The result is an executable program called :file:`hello`, which you can
run by entering:
.. code-block:: sh
@ -160,8 +158,8 @@ appear in response to this command.
Running a Program with Multiple Units
=====================================
Consider a slightly more complicated example that has three files: a
main program, and the spec and body of a package:
Consider a slightly more complicated example with three files: a
main program and the spec and body of a package:
.. code-block:: ada
@ -210,15 +208,15 @@ following three separate files:
Note that there is no required order of compilation when using GNAT.
In particular it is perfectly fine to compile the main program first.
Also, it is not necessary to compile package specs in the case where
there is an accompanying body; you only need to compile the body. If you want
there is an accompanying body; you only need compile the body. If you want
to submit these files to the compiler for semantic checking and not code
generation, then use the :switch:`-gnatc` switch:
generation, use the :switch:`-gnatc` switch:
.. code-block:: sh
$ gcc -c greetings.ads -gnatc
Although the compilation can be done in separate steps, in practice it is
Although you can do the compilation in separate steps, in practice it's
almost always more convenient to use the ``gnatmake`` or ``gprbuild`` tools:
.. code-block:: sh

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,10 +9,10 @@ Inline Assembler
.. index:: Inline Assembler
If you need to write low-level software that interacts directly
with the hardware, Ada provides two ways to incorporate assembly
with the hardware, Ada provides two ways for you to incorporate assembly
language code into your program. First, you can import and invoke
external routines written in assembly language, an Ada feature fully
supported by GNAT. However, for small sections of code it may be simpler
supported by GNAT. However, for small sections of code, it may be simpler
or more efficient to include assembly language statements directly
in your Ada source program, using the facilities of the implementation-defined
package ``System.Machine_Code``, which incorporates the gcc
@ -24,14 +24,14 @@ including the following:
* Automatic usage of the proper calling conventions
* Access to Ada constants and variables
* Definition of intrinsic routines
* Possibility of inlining a subprogram comprising assembler code
* Possibility of inlining a subprogram consisting of assembler code
* Code optimizer can take Inline Assembler code into account
This appendix presents a series of examples to show you how to use
the Inline Assembler. Although it focuses on the Intel x86,
the general approach applies also to other processors.
It is assumed that you are familiar with Ada
and with assembly language programming.
It is assumed you are familiar with both Ada
and assembly language programming.
.. _Basic_Assembler_Syntax:
@ -99,9 +99,9 @@ pre-processor) documentation for further information.
A Simple Example of Inline Assembler
====================================
The following example will generate a single assembly language statement,
The following example generate a single assembly language statement,
``nop``, which does nothing. Despite its lack of run-time effect,
the example will be useful in illustrating the basics of
the example is useful in illustrating the basics of
the Inline Assembler facility.
.. code-block:: ada
@ -114,18 +114,18 @@ the Inline Assembler facility.
``Asm`` is a procedure declared in package ``System.Machine_Code``;
here it takes one parameter, a *template string* that must be a static
expression and that will form the generated instruction.
expression that produces the generated instruction.
``Asm`` may be regarded as a compile-time procedure that parses
the template string and additional parameters (none here),
from which it generates a sequence of assembly language instructions.
the template string and any additional parameters (none, in this case)
and generates one or more assembly language instructions.
The examples in this chapter will illustrate several of the forms
for invoking ``Asm``; a complete specification of the syntax
is found in the ``Machine_Code_Insertions`` section of the
:title:`GNAT Reference Manual`.
Under the standard GNAT conventions, the ``Nothing`` procedure
should be in a file named :file:`nothing.adb`.
Under the standard GNAT conventions, you should put the ``Nothing`` procedure
in a file named :file:`nothing.adb`.
You can build the executable in the usual way:
::
@ -155,7 +155,7 @@ where the options are:
do not add runtime checks
This gives a human-readable assembler version of the code. The resulting
file will have the same name as the Ada source file, but with a ``.s``
file has the same name as the Ada source file but with a ``.s``
extension. In our example, the file :file:`nothing.s` has the following
contents:
@ -183,8 +183,8 @@ can differ on different targets. For example, GNU/Linux uses '#APP' while
on NT you will see '/APP'.
If you make a mistake in your assembler code (such as using the
wrong size modifier, or using a wrong operand for the instruction) GNAT
will report this error in a temporary file, which will be deleted when
wrong size modifier or using a wrong operand for the instruction) GNAT
will report this error in a temporary file, which is deleted when
the compilation is finished. Generating an assembler file will help
in such cases, since you can assemble this file separately using the
``as`` assembler that comes with gcc.
@ -197,7 +197,7 @@ Assembling the file using the command
will give you error messages whose lines correspond to the assembler
input file, so you can easily find and correct any mistakes you made.
If there are no errors, ``as`` will generate an object file
If there are no errors, ``as`` generates an object file called
:file:`nothing.out`.
@ -227,10 +227,10 @@ statements.
Put_Line ("Flags register:" & Flags'Img);
end Get_Flags;
In order to have a nicely aligned assembly listing, we have separated
multiple assembler statements in the Asm template string with linefeed
(ASCII.LF) and horizontal tab (ASCII.HT) characters.
The resulting section of the assembly output file is:
We have separated multiple assembler statements in the Asm template
string with linefeed (ASCII.LF) and horizontal tab (ASCII.HT)
characters in order to have a nicely aligned assembly listing. The
resulting section of the assembly output file is:
::
@ -269,20 +269,21 @@ In the generated assembly code, one of the percent signs will be stripped off.
Names such as ``%0``, ``%1``, ``%2``, etc., denote input or output
variables: operands you later define using ``Input`` or ``Output``
parameters to ``Asm``.
An output variable is illustrated in
the third statement in the Asm template string:
An output variable is shown in
the third section of the Asm template string:
::
movl %%eax, %0
The intent is to store the contents of the eax register in a variable that can
be accessed in Ada. Simply writing ``movl %%eax, Flags`` would not
necessarily work, since the compiler might optimize by using a register
to hold Flags, and the expansion of the ``movl`` instruction would not be
aware of this optimization. The solution is not to store the result directly
but rather to advise the compiler to choose the correct operand form;
that is the purpose of the ``%0`` output variable.
The intent of this section is to store the contents of the ``eax``
register in a variable that can be accessed in Ada. Simply writing
``movl %%eax, Flags`` would not necessarily work, since the compiler
might optimize by using a register to hold ``Flags``, and the expansion of
the ``movl`` instruction would not be aware of this optimization. The
solution is not to store the result directly but rather to advise the
compiler to choose the correct operand form; that is the purpose of
the ``%0`` output variable.
Information about the output variable is supplied in the ``Outputs``
parameter to ``Asm``:
@ -292,14 +293,14 @@ parameter to ``Asm``:
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
The output is defined by the ``Asm_Output`` attribute of the target type;
the general format is
the general format is:
.. code-block:: ada
Type'Asm_Output (constraint_string, variable_name)
The constraint string directs the compiler how
to store/access the associated variable. In the example
to store/access the associated variable. In the example:
.. code-block:: ada
@ -316,14 +317,14 @@ the optimizer from keeping it in a register. In contrast,
uses the ``"r"`` (register) constraint, telling the compiler to
store the variable in a register.
If the constraint is preceded by the equal character '=', it tells
the compiler that the variable will be used to store data into it.
If you precede the constraint with the equal character ('='), it tells
the compiler that the variable will have data stored into it.
In the ``Get_Flags`` example, we used the ``"g"`` (global) constraint,
allowing the optimizer to choose whatever it deems best.
allowing the optimizer to choose whatever operand it deems best.
There are a fairly large number of constraints, but the ones that are
most useful (for the Intel x86 processor) are the following:
most useful for the Intel x86 processor are the following:
====== ==========================================
*=* output constraint
@ -340,9 +341,9 @@ most useful (for the Intel x86 processor) are the following:
*q* use one of eax, ebx, ecx, edx, esi or edi
====== ==========================================
The full set of constraints is described in the gcc and ``as``
documentation; note that it is possible to combine certain constraints
in one constraint string.
The full set of constraints is described in the ``gcc`` and ``as``
documentation; note that you can combine certain constraints
into one constraint string.
You specify the association of an output variable with an assembler operand
through the :samp:`%{n}` notation, where *n* is a non-negative
@ -356,9 +357,8 @@ integer. Thus in
Outputs => Unsigned_32'Asm_Output ("=g", Flags));
``%0`` will be replaced in the expanded code by the appropriate operand,
whatever
the compiler decided for the ``Flags`` variable.
``%0`` is replaced in the expanded code by the appropriate operand,
whatever the compiler chose for the ``Flags`` variable.
In general, you may have any number of output variables:
@ -381,8 +381,8 @@ For example:
where ``Var_A``, ``Var_B``, and ``Var_C`` are variables
in the Ada program.
As a variation on the ``Get_Flags`` example, we can use the constraints
string to direct the compiler to store the eax register into the ``Flags``
As a variation on the ``Get_Flags`` example, we can use the constraint
string to direct the compiler to store the ``eax`` register into the ``Flags``
variable, instead of including the store instruction explicitly in the
``Asm`` template string:
@ -402,7 +402,7 @@ variable, instead of including the store instruction explicitly in the
end Get_Flags_2;
The ``"a"`` constraint tells the compiler that the ``Flags``
variable will come from the eax register. Here is the resulting code:
variable will come from the ``eax`` register. Here is the resulting code:
::
@ -415,7 +415,7 @@ variable will come from the eax register. Here is the resulting code:
The compiler generated the store of eax into Flags after
expanding the assembler code.
Actually, there was no need to pop the flags into the eax register;
In fact, there was no need to pop the flags into the ``eax`` register;
more simply, we could just pop the flags directly into the program variable:
.. code-block:: ada
@ -441,7 +441,7 @@ Input Variables in Inline Assembler
The example in this section illustrates how to specify the source operands
for assembly language statements.
The program simply increments its input value by 1:
The procedure simply increments its input value by 1:
.. code-block:: ada
@ -469,27 +469,27 @@ The program simply increments its input value by 1:
end Increment;
The ``Outputs`` parameter to ``Asm`` specifies
that the result will be in the eax register and that it is to be stored
that the result is in the ``eax`` register and that it is to be stored
in the ``Result`` variable.
The ``Inputs`` parameter looks much like the ``Outputs`` parameter,
but with an ``Asm_Input`` attribute.
The ``"="`` constraint, indicating an output value, is not present.
You can have multiple input variables, in the same way that you can have more
You can have multiple input variables in the same way you can have more
than one output variable.
The parameter count (%0, %1) etc, still starts at the first output statement,
and continues with the input statements.
Just as the ``Outputs`` parameter causes the register to be stored into the
target variable after execution of the assembler statements, so does the
``Inputs`` parameter cause its variable to be loaded into the register
target variable after execution of the assembler statements, the
``Inputs`` parameter causes its variable to be loaded into the register
before execution of the assembler statements.
Thus the effect of the ``Asm`` invocation is:
* load the 32-bit value of ``Value`` into eax
* load the 32-bit value of ``Value`` into ``eax``
* execute the ``incl %eax`` instruction
* store the contents of eax into the ``Result`` variable
@ -520,7 +520,7 @@ frame) can be significant, compared to the amount of code in the subprogram
body. A solution is to apply Ada's ``Inline`` pragma to the subprogram,
which directs the compiler to expand invocations of the subprogram at the
point(s) of call, instead of setting up a stack frame for out-of-line calls.
Here is the resulting program:
Here's the resulting program:
.. code-block:: ada
@ -593,14 +593,14 @@ such as Ada is that the compiler needs to be aware of which registers are
being used by the assembly code. In some cases, such as the earlier examples,
the constraint string is sufficient to indicate register usage (e.g.,
``"a"`` for
the eax register). But more generally, the compiler needs an explicit
the ``eax`` register). But, more generally, the compiler needs an explicit
identification of the registers that are used by the Inline Assembly
statements.
Using a register that the compiler doesn't know about
could be a side effect of an instruction (like ``mull``
storing its result in both eax and edx).
It can also arise from explicit register usage in your
could be a side effect of an instruction (like ``mull``, which
stores its result into both ``eax`` and ``edx``).
It can also arise from explicit register usage within your
assembly code; for example:
.. code-block:: ada
@ -611,10 +611,10 @@ assembly code; for example:
Inputs => Unsigned_32'Asm_Input ("g", Var_In));
where the compiler (since it does not analyze the ``Asm`` template string)
does not know you are using the ebx register.
does not know you are using the ``ebx`` register.
In such cases you need to supply the ``Clobber`` parameter to ``Asm``,
to identify the registers that will be used by your assembly code:
to identify the registers used by your assembly code:
.. code-block:: ada
@ -626,9 +626,9 @@ to identify the registers that will be used by your assembly code:
Clobber => "ebx");
The Clobber parameter is a static string expression specifying the
register(s) you are using. Note that register names are *not* prefixed
by a percent sign. Also, if more than one register is used then their names
are separated by commas; e.g., ``"eax, ebx"``
register(s) you are using. Note that register names are *not*
prefixed by a percent sign. Also, if more than one register is used,
you separate their names by commas; e.g., ``"eax, ebx"``
The ``Clobber`` parameter has several additional uses:
@ -648,7 +648,7 @@ unwanted effects. For example, when an ``Asm`` invocation with an input
variable is inside a loop, the compiler might move the loading of the input
variable outside the loop, regarding it as a one-time initialization.
If this effect is not desired, you can disable such optimizations by setting
If you don't want this to happen, you can disable such optimizations by setting
the ``Volatile`` parameter to ``True``; for example:
.. code-block:: ada
@ -664,7 +664,7 @@ By default, ``Volatile`` is set to ``False`` unless there is no
``Outputs`` parameter.
Although setting ``Volatile`` to ``True`` prevents unwanted
optimizations, it will also disable other optimizations that might be
optimizations, it also disables other optimizations that might be
important for efficiency. In general, you should set ``Volatile``
to ``True`` only if the compiler's optimizations have created
problems.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff