# Technical Documentation: gcc-mirror/gcc

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/gcc-mirror/gcc)

### Gcc Ada Doc Gnat Style (`gcc/ada/doc/gnat-style.rst`)

GNAT Coding Style: A Guide for GNAT Developers
==============================================

General
-------

Most of GNAT is written in Ada using a consistent style to ensure
readability of the code.  This document has been written to help
maintain this consistent style, while having a large group of developers
work on the compiler.

For the coding style in the C parts of the compiler and run time,
see the GNU Coding Guidelines.

This document is structured after the Ada Reference Manual.
Those familiar with that document should be able to quickly
lookup style rules for particular constructs.

Lexical Elements
----------------

Character Set and Separators
****************************

.. index:: Character set
.. index:: ASCII
.. index:: Separators
.. index:: End-of-line
.. index:: Line length
.. index:: Indentation

* The character set used should be plain 7-bit ASCII.
  The only separators allowed are space and the end-of-line sequence.
  No other control character or format effector (such as ``HT``,
  ``VT``, ``FF`` )
  should be used.
  The normal end-of-line sequence is used, which may be
  ``LF``, ``CR/LF`` or ``CR``,
  depending on the host system.  An optional ``SUB``
  ( ``16#1A#`` ) may be present as the
  last character in the file on hosts using that character as file terminator.

* Files that are checked in or distributed should be in host format.

* A line should never be longer than 79 characters, not counting the line
  separator.

* Lines must not have trailing blanks.

* Indentation is 3 characters per level for ``if`` statements, loops, and
  ``case`` statements.
  For exact information on required spacing between lexical
  elements, see file style.adb.

  .. index:: style.adb file

Identifiers
***********

* Identifiers will start with an upper case letter, and each letter following
  an underscore will be upper case.

  .. index:: Casing (for identifiers)

  Short acronyms may be all upper case.
  All other letters are lower case.
  An exception is for identifiers matching a foreign language.  In particular,
  we use all lower case where appropriate for C.

* Use underscores to separate words in an identifier.

  .. index:: Underscores

* Try to limit your use of abbreviations in identifiers.
  It is ok to make a few abbreviations, explain what they mean, and then
  use them frequently, but don't use lots of obscure abbreviations.  An
  example is the ``ALI`` word which stands for Ada Library
  Information and is by convention always written in upper-case when
  used in entity names.

  .. code-block:: ada

           procedure Find_ALI_Files;

* Don't use the variable name ``I``, use ``J`` instead; ``I`` is too
  easily confused with ``1`` in some fonts.  Similarly don't use the
  variable ``O``, which is too easily mistaken for the number ``0``.

Numeric Literals
****************

* Numeric literals should include underscores where helpful for
  readability.

  .. index:: Underscores

  .. code-block:: ada

          1_000_000
          16#8000_0000#
          3.14159_26535_89793_23846

Reserved Words
**************

* Reserved words use all lower case.

  .. index:: Casing (for reserved words)

  .. code-block:: ada

           return else

* The words ``Access``, ``Delta`` and ``Digits`` are
  capitalized when used as attribute_designator.

Comments
********

* A comment starts with ``--`` followed by two spaces.
  The only exception to this rule (i.e. one space is tolerated) is when the
  comment ends with a single space followed by ``--``.
  It is also acceptable to have only one space between ``--`` and the start
  of the comment when the comment is at the end of a line,
  after some Ada code.

* Every sentence in a comment should start with an upper-case letter (including
  the first letter of the comment).

  .. index:: Casing (in comments)

* When declarations are commented with 'hanging' comments, i.e.
  comments after the declaration, there is no blank line before the
  comment, and if it is absolutely necessary to have blank lines within
  the comments, e.g. to make paragraph separations within a single comment,
  these blank lines *do* have a ``--`` (unlike the
  normal rule, which is to use entirely blank lines for separating
  comment paragraphs).  The comment starts at same level of indentation
  as code it is commenting.

  .. index:: Blank lines (in comments)
  .. index:: Indentation

  .. code-block:: ada

           z : Integer;
           --  Integer value for storing value of z
           --
           --  The previous line was a blank line.

* Comments that are dubious or incomplete, or that comment on possibly
  wrong or incomplete code, should be preceded or followed by ``???``.

* Comments in a subprogram body must generally be surrounded by blank lines.
  An exception is a comment that follows a line containing a single keyword
  ( ``begin``, ``else``, ``loop`` ):

  .. code-block:: ada

           begin
              --  Comment for the next statement

              A := 5;

              --  Comment for the B statement

              B := 6;
           end;

* In sequences of statements, comments at the end of the lines should be
  aligned.

  .. index:: Alignment (in comments)

  .. code-block:: ada

            My_Identifier := 5;      --  First comment
            Other_Id := 6;           --  Second comment

* Short comments that fit on a single line are *not* ended with a
  period.  Comments taking more than a line are punctuated in the normal
  manner.

* Comments should focus on *why* instead of *what*.
  Descriptions of what subprograms do go with the specification.

* Comments describing a subprogram spec should specifically mention the
  formal argument names.  General rule: write a comment that does not
  depend on the names of things.  The names are supplementary, not
  sufficient, as comments.

* *Do not* put two spaces after periods in comments.

Declarations and Types
----------------------

* In entity declarations, colons must be surrounded by spaces.  Colons
  should be aligned.

  .. index:: Alignment (in declarations)

  .. code-block:: ada

            Entity1   : Integer;
            My_Entity : Integer;

* Declarations should be grouped in a logical order.
  Related groups of declarations may be preceded by a header comment.

* All local subprograms in a subprogram or package body should be declared
  before the first local subprogram body.

* Do not declare local entities that hide global entities.

  .. index:: Hiding of outer entities

* Do not declare multiple variables in one declaration that spans lines.
  Start a new declaration on each line, instead.

* The defining_identifiers of global declarations serve as
  comments of a sort.  So don't choose terse names, but look for names
  that give useful information instead.

* Local names can be shorter, because they are used only within
  one context, where comments explain their purpose.

* When starting an initialization or default expression on the line that follows
  the declaration line, use 2 characters for indentation.

  .. code-block:: ada

            Entity1 : Integer :=
              Function_Name (Parameters, For_Call);

* If an initialization or default expression needs to be continued on subsequent
  lines, the continuations should be indented from the start of the expression.

  .. code-block:: ada

            Entity1 : Integer := Long_Function_Name
                                   (parameters for call);

Expressions and Names
---------------------

* Every operator must be surrounded by spaces. An exception is that
  this rule does not apply to the exponentiation operator, for which
  there are no specific layout rules. The reason for this exception
  is that sometimes it makes clearer reading to leave out the spaces
  around exponentiation.

  .. index:: Operators

  .. code-block:: ada

           E := A * B**2 + 3 * (C - D);

* Use parentheses where they clarify the intended association of operands
  with operators:

  .. index:: Parenthesization of expressions

  .. code-block:: ada

           (A / B) * C

Statements
----------

Simple and Compound Statements
******************************

* Use only one statement or label per line.

* A longer sequence_of_statements may be divided in logical
  groups or separated from surrounding code using a blank line.


If Statements
*************

* When the ``if``, ``elsif`` or ``else`` keywords fit on the
  same line with the condition and the ``then`` keyword, then the
  statement is formatted as follows:

  .. index:: Alignment (in an if statement)

  .. code-block:: ada

            if condition then
               ...
            elsif condition then
               ...
            else
               ...
            end if;

  When the above layout is not possible, ``then`` should be aligned
  with ``if``, and conditions should preferably be split before an
  ``and`` or ``or`` keyword a follows:

  .. code-block:: ada

            if long_condition_that_has_to_be_split
              and then continued_on_the_next_line
            then
               ...
            end if;

  The ``elsif``, ``else`` and ``end if`` always line up with
  the ``if`` keyword.  The preferred location for splitting the line
  is before ``and`` or ``or``.  The continuation of a condition is
  indented with two spaces or as many as needed to make nesting clear.
  As an exception, if conditions are closely related either of the
  following is allowed:

  .. code-block:: ada

         if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf
              or else
            x = asldkjhalkdsjfhhfd
              or else
            x = asdfadsfadsf
         then
           ...
         end if;

         if x = lakdsjfhlkashfdlkflkdsalkhfsalkdhflkjdsahf or else
            x = asldkjhalkdsjfhhfd                         or else
            x = asdfadsfadsf
         then
           ...
         end if;

* Conditions should use short-circuit forms ( ``and then``,
  ``or else`` ), except when the operands are boolean variables
  or boolean constants.

  .. index:: Short-circuit forms

* Complex conditions in ``if`` statements are indented two characters:

  .. index:: Indentation (in if statements)

  .. code-block:: ada

          if this_complex_condition
            and then that_other_one
            and then one_last_one
          then
             ...
          end if;

  There are some cases where complex conditionals can be laid out
  in manners that do not follow these rules to preserve better
  parallelism between branches, e.g.

  .. code-block:: ada

          if xyz.abc (gef) = 'c'
               or else
             xyz.abc (gef) = 'x'
          then
             ...
          end if;

* Every ``if`` block is preceded and followed by a blank line, except
  where it begins or ends a sequence_of_statements.

  .. index:: Blank lines (in an if statement)

  .. code-block:: ada

            A := 5;

            if A = 5 then
               null;
            end if;

            A := 6;

Case Statements
***************

* Layout is as below.  For long ``case`` statements, the extra indentation
  can be saved by aligning the ``when`` clauses with the opening ``case``.

  .. code-block:: ada

           case expression is
              when condition =>
                 ...
              when condition =>
                 ...
           end case;

Loop Statements
***************

* When possible, have ``for`` or ``while`` on one line with the
  condition and the ``loop`` keyword.

  .. code-block:: ada

           for J in S'Range loop
              ...
           end loop;

  If the condition is too long, split the condition (see 'If
  statements' above) and align ``loop`` with the ``for`` or
  ``while`` keyword.

  .. index:: Alignment (in a loop statement)

  .. code-block:: ada

          while long_condition_that_has_to_be_split
            and then continued_on_the_next_line
          loop
             ...
          end loop;

  If the loop_statement has an identifier, it is laid out as follows:

  .. code-block:: ada

          Outer : while not condition loop
             ...
          end Outer;

Block Statements
****************

* The ``declare`` (optional), ``begin`` and ``end`` words
  are aligned, except when the block_statement is named.  There
  is a blank line before the ``begin`` keyword:

  .. index:: Alignment (in a block statement)

  .. code-block:: ada

          Some_Block : declare
             ...

          begin
             ...
          end Some_Block;

Subprograms
-----------

Subprogram Declarations
***********************

* Do not write the ``in`` for parameters.

  .. code-block:: ada

          function Length (S : String) return Integer;

* When the declaration line for a procedure or a function is too long to fit
  the entire declaration (including the keyword procedure or function) on a
  single line, then fold it, putting a single parameter on a line, aligning
  the colons, as in:

  .. code-block:: ada

         procedure Set_Heading
           (Source : String;
            Count  : Natural;
            Pad    : Character := Space;
            Fill   : Boolean   := True);

  In the case of a function, if the entire spec does not fit on one line, then
  the return may appear after the last parameter, as in:

  .. code-block:: ada

          function Head
            (Source : String;
             Count  : Natural;
             Pad    : Character := Space) return String;

  Or it may appear on its own as a separate line. This form is preferred when
  putting the return on the same line as the last parameter would result in
  an overlong line. The return type may optionally be aligned with the types
  of the parameters (usually we do this aligning if it results only in a small
  number of extra spaces, and otherwise we don't attempt to align). So two
  alternative forms for the above spec are:

  .. code-block:: ada

          function Head
            (Source : String;
             Count  : Natural;
             Pad    : Character := Space)
             return   String;

          function Head
            (Source : String;
             Count  : Natural;
             Pad    : Character := Space)
             return String;

Subprogram Bodies
*****************

* Function and procedure bodies should usually be sorted alphabetically. Do
  not attempt to sort them in some logical order by functionality. For a
  sequence of subprogram specs, a general alphabetical sorting is also
  usually appropriate, but occasionally it makes sense to group by major
  function, with appropriate headers.

* All subprograms have a header giving the function name, with the following
  format:

  .. code-block:: ada

          -----------------
          -- My_Function --
          -----------------

          procedure My_Function is
          begin
            ...
          end My_Function;

  Note that the name in the header is preceded by a single space,
  not two spaces as for other comments. These headers are used on
  nested subprograms as well as outer level subprograms. They may
  also be used as headers for sections of comments, or collections
  of declarations that are related.

* Every subprogram body must have a preceding subprogram_declaration,
  which includes proper client documentation so that you do not need to
  read the subprogram body in order to understand what the subprogram does and
  how to call it. All subprograms should be documented, without exceptions.

  .. index:: Blank lines (in subprogram bodies)

* A sequence of declarations may optionally be separated from the following
  begin by a blank line.  Just as we optionally allow blank lines in general
  between declarations, this blank line should be present only if it improves
  readability. Generally we avoid this blank line if the declarative part is
  small (one or two lines) and the body has no blank lines, and we include it
  if the declarative part is long or if the body has blank lines.

* If the declarations in a subprogram contain at least one nested
  subprogram body, then just before the ``begin`` of the enclosing
  subprogram, there is a comment line and a blank line:

  .. code-block:: ada

        --  Start of processing for Enclosing_Subprogram

        begin
          ...
        end Enclosing_Subprogram;

* When nested subprograms are present, variables that are referenced by any
  nested subprogram should precede the nested subprogram specs. For variables
  that are not referenced by nested procedures, the declarations can either also
  be before any of the nested subprogram specs (this is the old style, more
  generally used). Or then can come just before the begin, with a header. The
  following example shows the two possible styles:

  .. code-block:: ada

        procedure Style1 is
           Var_Referenced_In_Nested      : Integer;
           Var_Referenced_Only_In_Style1 : Integer;

           proc Nested;
           --  Comments ...

           ------------
           -- Nested --
           ------------

           procedure Nested is
           begin
              ...
           end Nested;

        --  Start of processing for Style1

        begin
           ...
        end Style1;

        procedure Style2 is
           Var_Referenced_In_Nested : Integer;

           proc Nested;
           --  Comments ...

           ------------
           -- Nested --
           ------------

           procedure Nested is
           begin
              ...
           end Nested;

           --  Local variables

           Var_Referenced_Only_In_Style2 : Integer;

        --  Start of processing for Style2

        begin
           ...
        end Style2;

  For new code, we generally prefer Style2, but we do not insist on
  modifying all legacy occurrences of Style1, which is still much
  more common in the sources.

Packages and Visibility Rules
-----------------------------

* All program units and subprograms have their name at the end:

  .. code-block:: ada

          package P is
             ...
          end P;

* We will use the style of ``use`` -ing ``with`` -ed packages, with
  the context clauses looking like:

  .. index:: use clauses

  .. code-block:: ada

          with A; use A;
          with B; use B;

* Names declared in the visible part of packages should be
  unique, to prevent name clashes when the packages are ``use`` d.

  .. index:: Name clash avoidance

  .. code-block:: ada

          package Entity is
             type Entity_Kind is ...;
             ...
          end Entity;

* After the file header comment, the context clause and unit specification
  should be the first thing in a program_unit.

* Preelaborate, Pure and Elaborate_Body pragmas should be added right after the
  package name, indented an extra level and using the parameterless form:

  .. code-block:: ada

          package Preelaborate_Package is
             pragma Preelaborate;
             ...
          end Preelaborate_Package;

Program Structure and Compilation Issues
----------------------------------------

* Every GNAT source file must be compiled with the ``-gnatg``
  switch to check the coding style.
  (Note that you should look at
  style.adb to see the lexical rules enforced by ``-gnatg`` ).

  .. index:: -gnatg option (to gcc)
  .. index:: style.adb file

* Each source file should contain only one compilation unit.

* Filenames should be 8 or fewer characters, followed by the ``.adb``
  extension for a body or ``.ads`` for a spec.

  .. index:: File name length

* Unit names should be distinct when 'krunch'ed to 8 characters
  (see krunch.ads) and the filenames should match the unit name,
  except that they are all lower case.

  .. index:: krunch.ads file

.. toctree::
   share/gnu_free_documentation_license

---

### Gcc Ada Doc Gnat Rm (`gcc/ada/doc/gnat_rm.rst`)

GNAT Reference Manual
=====================

.. only:: not latex

    *GNAT, The GNU Ada Development Environment*

    .. only:: PRO

       *GNAT Pro Edition*

       | Version |version|
       | Date: |today|

    .. only:: GPL

       *GNAT Community Edition*

       | Version |version|
       | Date: |today|

    .. only:: FSF

       .. raw:: texinfo

          @include gcc-common.texi
          GCC version @value{version-GCC}@*

    AdaCore

    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.3 or
    any later version published by the Free Software Foundation; with no
    Invariant Sections, with the Front-Cover Texts being "GNAT Reference
    Manual", and with no Back-Cover Texts.  A copy of the license is
    included in the section entitled :ref:`gnu_fdl`.

.. toctree::
   :numbered:
   :maxdepth: 3

   gnat_rm/about_this_guide
   gnat_rm/implementation_defined_pragmas
   gnat_rm/implementation_defined_aspects
   gnat_rm/implementation_defined_attributes
   gnat_rm/standard_and_implementation_defined_restrictions
   gnat_rm/implementation_advice
   gnat_rm/gnat_implementation_mode
   gnat_rm/implementation_defined_characteristics
   gnat_rm/intrinsic_subprograms
   gnat_rm/representation_clauses_and_pragmas
   gnat_rm/standard_library_routines
   gnat_rm/the_implementation_of_standard_i_o
   gnat_rm/the_gnat_library
   gnat_rm/interfacing_to_other_languages
   gnat_rm/specialized_needs_annexes
   gnat_rm/implementation_of_specific_ada_features
   gnat_rm/implementation_of_ada_2022_features
   gnat_rm/gnat_language_extensions
   gnat_rm/security_hardening_features
   gnat_rm/obsolescent_features
   gnat_rm/compatibility_and_porting_guide

.. raw:: latex

   \appendix

.. toctree::
   :maxdepth: 3

   share/gnu_free_documentation_license

---

### Gcc Ada Doc Gnat Ugn (`gcc/ada/doc/gnat_ugn.rst`)

GNAT User's Guide for Native Platforms
======================================

.. only:: not latex

    *GNAT, The GNU Ada Development Environment*

    .. only:: PRO

       *GNAT Pro Edition*

       | Version |version|
       | Date: |today|

    .. only:: GPL

       *GNAT Community Edition*

       | Version |version|
       | Date: |today|

    .. only:: FSF

       .. raw:: texinfo

          @include gcc-common.texi
          GCC version @value{version-GCC}@*

    AdaCore

    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.3 or
    any later version published by the Free Software Foundation; with no
    Invariant Sections, with the Front-Cover Texts being
    "GNAT User's Guide for Native Platforms",
    and with no Back-Cover Texts.  A copy of the license is
    included in the section entitled :ref:`gnu_fdl`.

.. toctree::
   :maxdepth: 3
   :numbered:

   gnat_ugn/about_this_guide
   gnat_ugn/getting_started_with_gnat
   gnat_ugn/the_gnat_compilation_model
   gnat_ugn/building_executable_programs_with_gnat
   gnat_ugn/gnat_utility_programs
   gnat_ugn/gnat_and_program_execution

.. raw:: latex

   \appendix

.. toctree::
   :maxdepth: 3

   A. Platform-Specific Information <gnat_ugn/platform_specific_information>
   B. Example of Binder Output <gnat_ugn/example_of_binder_output>
   C. Elaboration Order Handling in GNAT <gnat_ugn/elaboration_order_handling_in_gnat>
   D. Inline Assembler <gnat_ugn/inline_assembler>
   E. GNU Free Documentation License <share/gnu_free_documentation_license>

---

### Gcc Doc Libgdiagnostics Index (`gcc/doc/libgdiagnostics/index.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

libgdiagnostics
===============

This document describes `libgdiagnostics <https://gcc.gnu.org/wiki/libgdiagnostics>`_,
an API for programs to use to emit diagnostics (such as for "lint"-style checker
tools), supporting:

* text output similar to GCC's errors and warnings::

    test-typo.c:19:13: error: unknown field 'colour'
       19 |   return p->colour;
          |             ^~~~~~

  quoting pertinent source code (with a cache), and underlining
  :doc:`points and ranges in the files being tested <tutorial/02-physical-locations>`,
  possibly with labels::

   test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *'
      19 |   42 + "foo"
         |   ~~ ^ ~~~~~
         |   |    |
         |   int  const char *

* emitting :doc:`fix-it hints <tutorial/06-fix-it-hints>`::

   test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color'
      19 |   return p->colour;
         |             ^~~~~~
         |             color

  and generating patches from them::

   @@ -16,7 +16,7 @@
    struct rgb
    get_color (struct object *p)
    {
   -  return p->colour;
   +  return p->color;
    }

* capturing :doc:`execution paths<tutorial/07-execution-paths>` through code::

   In function 'make_a_list_of_random_ints_badly':
   test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter"
      30 |     PyList_Append(list, item);
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   make_a_list_of_random_ints_badly': events 1-3
      26 |   list = PyList_New(0);
         |          ^~~~~~~~~~~~~
         |          |
         |          (1) when 'PyList_New' fails, returning NULL
      27 |
      28 |   for (i = 0; i < count; i++) {
         |               ~~~~~~~~~
         |               |
         |               (2) when 'i < count'
      29 |     item = PyLong_FromLong(random());
      30 |     PyList_Append(list, item);
         |     ~~~~~~~~~~~~~~~~~~~~~~~~~
         |     |
         |     (3) when calling 'PyList_Append', passing NULL from (1) as argument 1

* support for emitting machine-readable representations of the above
  using the :doc:`SARIF file format <topics/sarif>`

There are actually two APIs for the library:

* a pure C API: ``libgdiagnostics.h``

* a C++ wrapper API: ``libgdiagnostics+.h``.  This is a header-only
  collection of wrapper classes around the C API to give a less
  verbose API.

This documentation covers the C API.

Contents
********

.. toctree::
   :maxdepth: 2

   tutorial/index.rst
   topics/index.rst

libgdiagnostics is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.


Indices and tables
******************

* :ref:`genindex`
* :ref:`search`

---

### Gcc Jit Docs Index (`gcc/jit/docs/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

libgccjit
=========

This document describes `libgccjit <https://gcc.gnu.org/wiki/JIT>`_, an API
for embedding GCC inside programs and libraries.

There are actually two APIs for the library:

* a pure C API: ``libgccjit.h``

* a C++ wrapper API: ``libgccjit++.h``.  This is a collection of "thin"
  wrapper classes around the C API, to save typing.

Contents:

.. toctree::
   :maxdepth: 2

   intro/index.rst
   topics/index.rst
   cp/index.rst
   internals/index.rst


Indices and tables
==================

* :ref:`genindex`
* :ref:`search`

---

### Gcc Ada Doc Gnat Rm About This Guide (`gcc/ada/doc/gnat_rm/about_this_guide.rst`)

.. _About_This_Guide:

****************
About This Guide
****************

.. only:: PRO

   For ease of exposition, 'GNAT Pro' will be referred to simply as
   'GNAT' in the remainder of this document.

This manual contains useful information in writing programs using the
GNAT compiler.  It includes information on implementation dependent
characteristics of GNAT, including all the information required by
Annex M of the Ada language standard.

GNAT implements Ada 95, Ada 2005, Ada 2012 and Ada 2022, 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
to explicitly specify the language version.
(Please refer to the *GNAT User's Guide* for details on these switches.)
Throughout this manual, references to 'Ada' without a year suffix
apply to all the Ada versions of the language.

Ada is designed to be highly portable.
In general, a program will have the same effect even when compiled by
different compilers on different platforms.
However, since Ada is designed to be used in a
wide variety of applications, it also contains a number of system
dependent features to be used in interfacing to the external world.

.. index:: Implementation-dependent features

.. index:: Portability

Note: Any program that makes use of implementation-dependent features
may be non-portable.  You should follow good programming practice and
isolate and clearly document any sections of your program that make use
of these features in a non-portable manner.

What This Reference Manual Contains
===================================

This reference manual contains the following chapters:

* :ref:`Implementation_Defined_Pragmas`, lists GNAT implementation-dependent
  pragmas, which can be used to extend and enhance the functionality of the
  compiler.

* :ref:`Implementation_Defined_Attributes`, lists GNAT
  implementation-dependent attributes, which can be used to extend and
  enhance the functionality of the compiler.

* :ref:`Standard_and_Implementation_Defined_Restrictions`, lists GNAT
  implementation-dependent restrictions, which can be used to extend and
  enhance the functionality of the compiler.

* :ref:`Implementation_Advice`, provides information on generally
  desirable behavior which are not requirements that all compilers must
  follow since it cannot be provided on all systems, or which may be
  undesirable on some systems.

* :ref:`GNAT_Implementation_Mode` details the features and restrictions that
  are enabled while building the compiler and its runtime libraries.

* :ref:`Implementation_Defined_Characteristics`, provides a guide to
  minimizing implementation dependent features.

* :ref:`Intrinsic_Subprograms`, describes the intrinsic subprograms
  implemented by GNAT, and how they can be imported into user
  application programs.

* :ref:`Representation_Clauses_and_Pragmas`, describes in detail the
  way that GNAT represents data, and in particular the exact set
  of representation clauses and pragmas that is accepted.

* :ref:`Standard_Library_Routines`, provides a listing of packages and a
  brief description of the functionality that is provided by Ada's
  extensive set of standard library routines as implemented by GNAT.

* :ref:`The_Implementation_of_Standard_I/O`, details how the GNAT
  implementation of the input-output facilities.

* :ref:`The_GNAT_Library`, is a catalog of packages that complement
  the Ada predefined library.

* :ref:`Interfacing_to_Other_Languages`, describes how programs
  written in Ada using GNAT can be interfaced to other programming
  languages.

* :ref:`Specialized_Needs_Annexes`, describes the GNAT implementation of all
  of the specialized needs annexes.

* :ref:`Implementation_of_Specific_Ada_Features`, discusses issues related
  to GNAT's implementation of machine code insertions, tasking, and several
  other features.

* :ref:`Implementation_of_Ada_2022_Features`, describes the status of the
  GNAT implementation of the Ada 2022 language standard.

* :ref:`Security_Hardening_Features` documents GNAT extensions aimed
  at security hardening.

* :ref:`Obsolescent_Features` documents implementation dependent features,
  including pragmas and attributes, which are considered obsolescent, since
  there are other preferred ways of achieving the same results. These
  obsolescent forms are retained for backwards compatibility.

* :ref:`Compatibility_and_Porting_Guide` presents some guidelines for
  developing portable Ada code, describes the compatibility issues that
  may arise between GNAT and other Ada compilation systems (including those
  for Ada 83), and shows how GNAT can expedite porting applications
  developed in other Ada environments.

* :ref:`gnu_fdl` contains the license for this document.

.. index:: Ada 95 Language Reference Manual

.. index:: Ada 2005 Language Reference Manual

This reference manual assumes a basic familiarity with the Ada 95 language, as
described in the
:title:`International Standard ANSI/ISO/IEC-8652:1995`.
It does not require knowledge of the new features introduced by Ada 2005 or
Ada 2012.
All three reference manuals are included in the GNAT documentation
package.

Conventions
===========
.. index:: Conventions, typographical

.. index:: Typographical conventions

Following are examples of the typographical and graphic conventions used
in this guide:

* ``Functions``, ``utility program names``, ``standard names``,
  and ``classes``.

* ``Option flags``

* :file:`File names`

* ``Variables``

* *Emphasis*

* [optional information or parameters]

* Examples are described by text

  ::

    and then shown this way.

* Commands that are entered by the user are shown as preceded by a prompt string
  comprising the ``$`` character followed by a space.

Related Information
===================

See the following documents for further information on GNAT:

* :title:`GNAT User's Guide for Native Platforms`,
  which provides information on how to use the
  GNAT development environment.

* :title:`Ada 95 Reference Manual`, the Ada 95 programming language standard.

* :title:`Ada 95 Annotated Reference Manual`, which is an annotated version
  of the Ada 95 standard.  The annotations describe
  detailed aspects of the design decision, and in particular contain useful
  sections on Ada 83 compatibility.

* :title:`Ada 2005 Reference Manual`, the Ada 2005 programming language standard.

* :title:`Ada 2005 Annotated Reference Manual`, which is an annotated version
  of the Ada 2005 standard.  The annotations describe
  detailed aspects of the design decision.

* :title:`Ada 2012 Reference Manual`, the Ada 2012 programming language standard.

* :title:`DEC Ada, Technical Overview and Comparison on DIGITAL Platforms`,
  which contains specific information on compatibility between GNAT and
  DEC Ada 83 systems.

* :title:`DEC Ada, Language Reference Manual`, part number AA-PYZAB-TK, which
  describes in detail the pragmas and attributes provided by the DEC Ada 83
  compiler system.

---

### Gcc Ada Doc Gnat Rm Compatibility And Porting Guide (`gcc/ada/doc/gnat_rm/compatibility_and_porting_guide.rst`)

.. _Compatibility_and_Porting_Guide:

*******************************
Compatibility and Porting Guide
*******************************

This chapter presents some guidelines for developing portable Ada code,
describes the compatibility issues that may arise between
GNAT and other Ada compilation systems (including those for Ada 83),
and shows how GNAT can expedite porting
applications developed in other Ada environments.

.. _Writing_Portable_Fixed-Point_Declarations:

Writing Portable Fixed-Point Declarations
=========================================

The Ada Reference Manual gives an implementation freedom to choose bounds
that are narrower by ``Small`` from the given bounds.
For example, if we write

.. code-block:: ada

     type F1 is delta 1.0 range -128.0 .. +128.0;

then the implementation is allowed to choose -128.0 .. +127.0 if it
likes, but is not required to do so.

This leads to possible portability problems, so let's have a closer
look at this, and figure out how to avoid these problems.

First, why does this freedom exist, and why would an implementation
take advantage of it? To answer this, take a closer look at the type
declaration for ``F1`` above. If the compiler uses the given bounds,
it would need 9 bits to hold the largest positive value (and typically
that means 16 bits on all machines). But if the implementation chooses
the +127.0 bound then it can fit values of the type in 8 bits.

Why not make the user write +127.0 if that's what is wanted?
The rationale is that if you are thinking of fixed point
as a kind of 'poor man's floating-point', then you don't want
to be thinking about the scaled integers that are used in its
representation. Let's take another example:

.. code-block:: ada

      type F2 is delta 2.0**(-15) range -1.0 .. +1.0;

Looking at this declaration, it seems casually as though
it should fit in 16 bits, but again that extra positive value
+1.0 has the scaled integer equivalent of 2**15 which is one too
big for signed 16 bits. The implementation can treat this as:

.. code-block:: ada

     type F2 is delta 2.0**(-15) range -1.0 .. +1.0-(2.0**(-15));

and the Ada language design team felt that this was too annoying
to require. We don't need to debate this decision at this point,
since it is well established (the rule about narrowing the ranges
dates to Ada 83).

But the important point is that an implementation is not required
to do this narrowing, so we have a potential portability problem.
We could imagine three types of implementation:

(a) those that narrow the range automatically if they can figure
    out that the narrower range will allow storage in a smaller machine unit,

(b) those that will narrow only if forced to by a ``'Size`` clause, and

(c) those that will never narrow.

Now if we are language theoreticians, we can imagine a fourth
approach: to narrow all the time, e.g. to treat

.. code-block:: ada

     type F3 is delta 1.0 range -10.0 .. +23.0;

as though it had been written:


.. code-block:: ada

      type F3 is delta 1.0 range -9.0 .. +22.0;

But although technically allowed, such a behavior would be hostile and silly,
and no real compiler would do this. All real compilers will fall into one of
the categories (a), (b) or (c) above.

So, how do you get the compiler to do what you want? The answer is give the
actual bounds you want, and then use a ``'Small`` clause and a
``'Size`` clause to absolutely pin down what the compiler does.
E.g., for ``F2`` above, we will write:

.. code-block:: ada

     My_Small : constant := 2.0**(-15);
     My_First : constant := -1.0;
     My_Last  : constant := +1.0 - My_Small;

     type F2 is delta My_Small range My_First .. My_Last;

and then add

.. code-block:: ada

     for F2'Small use my_Small;
     for F2'Size  use 16;

In practice all compilers will do the same thing here and will give you
what you want, so the above declarations are fully portable. If you really
want to play language lawyer and guard against ludicrous behavior by the
compiler you could add

.. code-block:: ada

     Test1 : constant := 1 / Boolean'Pos (F2'First = My_First);
     Test2 : constant := 1 / Boolean'Pos (F2'Last  = My_Last);

One or other or both are allowed to be illegal if the compiler is
behaving in a silly manner, but at least the silly compiler will not
get away with silently messing with your (very clear) intentions.

If you follow this scheme you will be guaranteed that your fixed-point
types will be portable.




.. _Compatibility_with_Ada_83:

Compatibility with Ada 83
=========================

.. index:: Compatibility (between Ada 83 and Ada 95 / Ada 2005 / Ada 2012 / Ada 2022)

Ada 95 and the subsequent revisions Ada 2005, Ada 2012, Ada 2022
are highly upwards compatible with Ada 83.  In
particular, the design intention was that the difficulties associated
with moving from Ada 83 to later versions of the standard should be no greater
than those that occur when moving from one Ada 83 system to another.

However, there are a number of points at which there are minor
incompatibilities.  The :title:`Ada 95 Annotated Reference Manual` contains
full details of these issues as they relate to Ada 95,
and should be consulted for a complete treatment.
In practice the
following subsections treat the most likely issues to be encountered.

.. _Legal_Ada_83_programs_that_are_illegal_in_Ada_95:

Legal Ada 83 programs that are illegal in Ada 95
------------------------------------------------

Some legal Ada 83 programs are illegal (i.e., they will fail to compile) in
Ada 95 and later versions of the standard:


* *Character literals*

  Some uses of character literals are ambiguous.  Since Ada 95 has introduced
  ``Wide_Character`` as a new predefined character type, some uses of
  character literals that were legal in Ada 83 are illegal in Ada 95.
  For example:

  .. code-block:: ada

       for Char in 'A' .. 'Z' loop ... end loop;

  The problem is that 'A' and 'Z' could be from either
  ``Character`` or ``Wide_Character``.  The simplest correction
  is to make the type explicit; e.g.:

  .. code-block:: ada

       for Char in Character range 'A' .. 'Z' loop ... end loop;

* *New reserved words*

  The identifiers ``abstract``, ``aliased``, ``protected``,
  ``requeue``, ``tagged``, and ``until`` are reserved in Ada 95.
  Existing Ada 83 code using any of these identifiers must be edited to
  use some alternative name.

* *Freezing rules*

  The rules in Ada 95 are slightly different with regard to the point at
  which entities are frozen, and representation pragmas and clauses are
  not permitted past the freeze point.  This shows up most typically in
  the form of an error message complaining that a representation item
  appears too late, and the appropriate corrective action is to move
  the item nearer to the declaration of the entity to which it refers.

  A particular case is that representation pragmas
  cannot be applied to a subprogram body.  If necessary, a separate subprogram
  declaration must be introduced to which the pragma can be applied.

* *Optional bodies for library packages*

  In Ada 83, a package that did not require a package body was nevertheless
  allowed to have one.  This lead to certain surprises in compiling large
  systems (situations in which the body could be unexpectedly ignored by the
  binder).  In Ada 95, if a package does not require a body then it is not
  permitted to have a body.  To fix this problem, simply remove a redundant
  body if it is empty, or, if it is non-empty, introduce a dummy declaration
  into the spec that makes the body required.  One approach is to add a private
  part to the package declaration (if necessary), and define a parameterless
  procedure called ``Requires_Body``, which must then be given a dummy
  procedure body in the package body, which then becomes required.
  Another approach (assuming that this does not introduce elaboration
  circularities) is to add an ``Elaborate_Body`` pragma to the package spec,
  since one effect of this pragma is to require the presence of a package body.

* *Numeric_Error is the same exception as Constraint_Error*

  In Ada 95, the exception ``Numeric_Error`` is a renaming of ``Constraint_Error``.
  This means that it is illegal to have separate exception handlers for
  the two exceptions.  The fix is simply to remove the handler for the
  ``Numeric_Error`` case (since even in Ada 83, a compiler was free to raise
  ``Constraint_Error`` in place of ``Numeric_Error`` in all cases).

* *Indefinite subtypes in generics*

  In Ada 83, it was permissible to pass an indefinite type (e.g, ``String``)
  as the actual for a generic formal private type, but then the instantiation
  would be illegal if there were any instances of declarations of variables
  of this type in the generic body.  In Ada 95, to avoid this clear violation
  of the methodological principle known as the 'contract model',
  the generic declaration explicitly indicates whether
  or not such instantiations are permitted.  If a generic formal parameter
  has explicit unknown discriminants, indicated by using ``(<>)`` after the
  subtype name, then it can be instantiated with indefinite types, but no
  stand-alone variables can be declared of this type.  Any attempt to declare
  such a variable will result in an illegality at the time the generic is
  declared.  If the ``(<>)`` notation is not used, then it is illegal
  to instantiate the generic with an indefinite type.
  This is the potential incompatibility issue when porting Ada 83 code to Ada 95.
  It will show up as a compile time error, and
  the fix is usually simply to add the ``(<>)`` to the generic declaration.


.. _More_deterministic_semantics:

More deterministic semantics
----------------------------

* *Conversions*

  Conversions from real types to integer types round away from 0.  In Ada 83
  the conversion Integer(2.5) could deliver either 2 or 3 as its value.  This
  implementation freedom was intended to support unbiased rounding in
  statistical applications, but in practice it interfered with portability.
  In Ada 95 the conversion semantics are unambiguous, and rounding away from 0
  is required.  Numeric code may be affected by this change in semantics.
  Note, though, that this issue is no worse than already existed in Ada 83
  when porting code from one vendor to another.

* *Tasking*

  The Real-Time Annex introduces a set of policies that define the behavior of
  features that were implementation dependent in Ada 83, such as the order in
  which open select branches are executed.


.. _Changed_semantics:

Changed semantics
-----------------

The worst kind of incompatibility is one where a program that is legal in
Ada 83 is also legal in Ada 95 but can have an effect in Ada 95 that was not
possible in Ada 83.  Fortunately this is extremely rare, but the one
situation that you should be alert to is the change in the predefined type
``Character`` from 7-bit ASCII to 8-bit Latin-1.

    .. index:: Latin-1

* *Range of type ``Character``*

  The range of ``Standard.Character`` is now the full 256 characters
  of Latin-1, whereas in most Ada 83 implementations it was restricted
  to 128 characters. Although some of the effects of
  this change will be manifest in compile-time rejection of legal
  Ada 83 programs it is possible for a working Ada 83 program to have
  a different effect in Ada 95, one that was not permitted in Ada 83.
  As an example, the expression
  ``Character'Pos(Character'Last)`` returned ``127`` in Ada 83 and now
  delivers ``255`` as its value.
  In general, you should look at the logic of any
  character-processing Ada 83 program and see whether it needs to be adapted
  to work correctly with Latin-1.  Note that the predefined Ada 95 API has a
  character handling package that may be relevant if code needs to be adapted
  to account for the additional Latin-1 elements.
  The desirable fix is to
  modify the program to accommodate the full character set, but in some cases
  it may be convenient to define a subtype or derived type of Character that
  covers only the restricted range.


.. _Other_language_compatibility_issues:

Other language compatibility issues
-----------------------------------

* *-gnat83* switch

  All implementations of GNAT provide a switch that causes GNAT to operate
  in Ada 83 mode.  In this mode, some but not all compatibility problems
  of the type described above are handled automatically.  For example, the
  new reserved words introduced in Ada 95 and Ada 2005 are treated simply
  as identifiers as in Ada 83.  However,
  in practice, it is usually advisable to make the necessary modifications
  to the program to remove the need for using this switch.
  See the ``Compiling Different Versions of Ada`` section in
  the :title:`GNAT User's Guide`.


* Support for removed Ada 83 pragmas and attributes

  A number of pragmas and attributes from Ada 83 were removed from Ada 95,
  generally because they were replaced by other mechanisms.  Ada 95 and Ada 2005
  compilers are allowed, but not required, to implement these missing
  elements.  In contrast with some other compilers, GNAT implements all
  such pragmas and attributes, eliminating this compatibility concern.  These
  include ``pragma Interface`` and the floating point type attributes
  (``Emax``, ``Mantissa``, etc.), among other items.


.. _Compatibility_between_Ada_95_and_Ada_2005:

Compatibility between Ada 95 and Ada 2005
=========================================

.. index:: Compatibility between Ada 95 and Ada 2005

Although Ada 2005 was designed to be upwards compatible with Ada 95, there are
a number of incompatibilities. Several are enumerated below;
for a complete description please see the
:title:`Annotated Ada 2005 Reference Manual`, or section 9.1.1 in
:title:`Rationale for Ada 2005`.

* *New reserved words.*

  The words ``interface``, ``overriding`` and ``synchronized`` are
  reserved in Ada 2005.
  A pre-Ada 2005 program that uses any of these as an identifier will be
  illegal.

* *New declarations in predefined packages.*

  A number of packages in the predefined environment contain new declarations:
  ``Ada.Exceptions``, ``Ada.Real_Time``, ``Ada.Strings``,
  ``Ada.Strings.Fixed``, ``Ada.Strings.Bounded``,
  ``Ada.Strings.Unbounded``, ``Ada.Strings.Wide_Fixed``,
  ``Ada.Strings.Wide_Bounded``, ``Ada.Strings.Wide_Unbounded``,
  ``Ada.Tags``, ``Ada.Text_IO``, and ``Interfaces.C``.
  If an Ada 95 program does a ``with`` and ``use`` of any of these
  packages, the new declarations may cause name clashes.

* *Access parameters.*

  A nondispatching subprogram with an access parameter cannot be renamed
  as a dispatching operation.  This was permitted in Ada 95.

* *Access types, discriminants, and constraints.*

  Rule changes in this area have led to some incompatibilities; for example,
  constrained subtypes of some access types are not permitted in Ada 2005.

* *Aggregates for limited types.*

  The allowance of aggregates for limited types in Ada 2005 raises the
  possibility of ambiguities in legal Ada 95 programs, since additional types
  now need to be considered in expression resolution.

* *Fixed-point multiplication and division.*

  Certain expressions involving '*' or '/' for a fixed-point type, which
  were legal in Ada 95 and invoked the predefined versions of these operations,
  are now ambiguous.
  The ambiguity may be resolved either by applying a type conversion to the
  expression, or by explicitly invoking the operation from package
  ``Standard``.

* *Return-by-reference types.*

  The Ada 95 return-by-reference mechanism has been removed.  Instead, the user
  can declare a function returning a value from an anonymous access type.


.. _Implementation-dependent_characteristics:

Implementation-dependent characteristics
========================================

Although the Ada language defines the semantics of each construct as
precisely as practical, in some situations (for example for reasons of
efficiency, or where the effect is heavily dependent on the host or target
platform) the implementation is allowed some freedom.  In porting Ada 83
code to GNAT, you need to be aware of whether / how the existing code
exercised such implementation dependencies.  Such characteristics fall into
several categories, and GNAT offers specific support in assisting the
transition from certain Ada 83 compilers.

.. _Implementation-defined_pragmas:

Implementation-defined pragmas
------------------------------

Ada compilers are allowed to supplement the language-defined pragmas, and
these are a potential source of non-portability.  All GNAT-defined pragmas
are described in :ref:`Implementation_Defined_Pragmas`,
and these include several that are specifically
intended to correspond to other vendors' Ada 83 pragmas.
For migrating from VADS, the pragma ``Use_VADS_Size`` may be useful.
For compatibility with HP Ada 83, GNAT supplies the pragmas
``Extend_System``, ``Ident``, ``Inline_Generic``,
``Interface_Name``, ``Passive``, ``Suppress_All``,
and ``Volatile``.
Other relevant pragmas include ``External`` and ``Link_With``.
Some vendor-specific
Ada 83 pragmas (``Share_Generic``, ``Subtitle``, and ``Title``) are
recognized, thus
avoiding compiler rejection of units that contain such pragmas; they are not
relevant in a GNAT context and hence are not otherwise implemented.


.. _Implementation-defined_attributes:

Implementation-defined attributes
---------------------------------

Analogous to pragmas, the set of attributes may be extended by an
implementation.  All GNAT-defined attributes are described in
:ref:`Implementation_Defined_Attributes`,
and these include several that are specifically intended
to correspond to other vendors' Ada 83 attributes.  For migrating from VADS,
the attribute ``VADS_Size`` may be useful.  For compatibility with HP
Ada 83, GNAT supplies the attributes ``Bit``, ``Machine_Size`` and
``Type_Class``.

.. _Libraries:

Libraries
---------

Vendors may supply libraries to supplement the standard Ada API.  If Ada 83
code uses vendor-specific libraries then there are several ways to manage
this in Ada 95 and later versions of the standard:

* If the source code for the libraries (specs and bodies) are
  available, then the libraries can be migrated in the same way as the
  application.

* If the source code for the specs but not the bodies are
  available, then you can reimplement the bodies.

* Some features introduced by Ada 95 obviate the need for library support.  For
  example most Ada 83 vendors supplied a package for unsigned integers.  The
  Ada 95 modular type feature is the preferred way to handle this need, so
  instead of migrating or reimplementing the unsigned integer package it may
  be preferable to retrofit the application using modular types.


.. _Elaboration_order:

Elaboration order
-----------------
The implementation can choose any elaboration order consistent with the unit
dependency relationship.  This freedom means that some orders can result in
Program_Error being raised due to an 'Access Before Elaboration': an attempt
to invoke a subprogram before its body has been elaborated, or to instantiate
a generic before the generic body has been elaborated.  By default GNAT
attempts to choose a safe order (one that will not encounter access before
elaboration problems) by implicitly inserting ``Elaborate`` or
``Elaborate_All`` pragmas where
needed.  However, this can lead to the creation of elaboration circularities
and a resulting rejection of the program by gnatbind.  This issue is
thoroughly described in the *Elaboration Order Handling in GNAT* appendix
in the :title:`GNAT User's Guide`.
In brief, there are several
ways to deal with this situation:

* Modify the program to eliminate the circularities, e.g., by moving
  elaboration-time code into explicitly-invoked procedures

* Constrain the elaboration order by including explicit ``Elaborate_Body`` or
  ``Elaborate`` pragmas, and then inhibit the generation of implicit
  ``Elaborate_All``
  pragmas either globally (as an effect of the *-gnatE* switch) or locally
  (by selectively suppressing elaboration checks via pragma
  ``Suppress(Elaboration_Check)`` when it is safe to do so).


.. _Target-specific_aspects:

Target-specific aspects
-----------------------

Low-level applications need to deal with machine addresses, data
representations, interfacing with assembler code, and similar issues.  If
such an Ada 83 application is being ported to different target hardware (for
example where the byte endianness has changed) then you will need to
carefully examine the program logic; the porting effort will heavily depend
on the robustness of the original design.  Moreover, Ada 95 (and thus
Ada 2005, Ada 2012, and Ada 2022) are sometimes
incompatible with typical Ada 83 compiler practices regarding implicit
packing, the meaning of the Size attribute, and the size of access values.
GNAT's approach to these issues is described in :ref:`Representation_Clauses`.


.. _Compatibility_with_Other_Ada_Systems:

Compatibility with Other Ada Systems
====================================

If programs avoid the use of implementation dependent and
implementation defined features, as documented in the
:title:`Ada Reference Manual`, there should be a high degree of portability between
GNAT and other Ada systems.  The following are specific items which
have proved troublesome in moving Ada 95 programs from GNAT to other Ada 95
compilers, but do not affect porting code to GNAT.
(As of January 2007, GNAT is the only compiler available for Ada 2005;
the following issues may or may not arise for Ada 2005 programs
when other compilers appear.)

* *Ada 83 Pragmas and Attributes*

  Ada 95 compilers are allowed, but not required, to implement the missing
  Ada 83 pragmas and attributes that are no longer defined in Ada 95.
  GNAT implements all such pragmas and attributes, eliminating this as
  a compatibility concern, but some other Ada 95 compilers reject these
  pragmas and attributes.

* *Specialized Needs Annexes*

  GNAT implements the full set of special needs annexes.  At the
  current time, it is the only Ada 95 compiler to do so.  This means that
  programs making use of these features may not be portable to other Ada
  95 compilation systems.

* *Representation Clauses*

  Some other Ada 95 compilers implement only the minimal set of
  representation clauses required by the Ada 95 reference manual.  GNAT goes
  far beyond this minimal set, as described in the next section.


.. _Representation_Clauses:

Representation Clauses
======================

The Ada 83 reference manual was quite vague in describing both the minimal
required implementation of representation clauses, and also their precise
effects.  Ada 95 (and thus also Ada 2005) are much more explicit, but the
minimal set of capabilities required is still quite limited.

GNAT implements the full required set of capabilities in
Ada 95 and Ada 2005, but also goes much further, and in particular
an effort has been made to be compatible with existing Ada 83 usage to the
greatest extent possible.

A few cases exist in which Ada 83 compiler behavior is incompatible with
the requirements in Ada 95 (and thus also Ada 2005).  These are instances of
intentional or accidental dependence on specific implementation dependent
characteristics of these Ada 83 compilers.  The following is a list of
the cases most likely to arise in existing Ada 83 code.

* *Implicit Packing*

  Some Ada 83 compilers allowed a Size specification to cause implicit
  packing of an array or record.  This could cause expensive implicit
  conversions for change of representation in the presence of derived
  types, and the Ada design intends to avoid this possibility.
  Subsequent AI's were issued to make it clear that such implicit
  change of representation in response to a Size clause is inadvisable,
  and this recommendation is represented explicitly in the Ada 95 (and Ada 2005)
  Reference Manuals as implementation advice that is followed by GNAT.
  The problem will show up as an error
  message rejecting the size clause.  The fix is simply to provide
  the explicit pragma ``Pack``, or for more fine tuned control, provide
  a Component_Size clause.

* *Meaning of Size Attribute*

  The Size attribute in Ada 95 (and Ada 2005) for discrete types is defined as
  the minimal number of bits required to hold values of the type.  For example,
  on a 32-bit machine, the size of ``Natural`` will typically be 31 and not
  32 (since no sign bit is required).  Some Ada 83 compilers gave 31, and
  some 32 in this situation.  This problem will usually show up as a compile
  time error, but not always.  It is a good idea to check all uses of the
  'Size attribute when porting Ada 83 code.  The GNAT specific attribute
  Object_Size can provide a useful way of duplicating the behavior of
  some Ada 83 compiler systems.

* *Size of Access Types*

  A common assumption in Ada 83 code is that an access type is in fact a pointer,
  and that therefore it will be the same size as a System.Address value.  This
  assumption is true for GNAT in most cases with one exception.  For the case of
  a pointer to an unconstrained array type (where the bounds may vary from one
  value of the access type to another), the default is to use a 'fat pointer',
  which is represented as two separate pointers, one to the bounds, and one to
  the array.  This representation has a number of advantages, including improved
  efficiency.  However, it may cause some difficulties in porting existing Ada 83
  code which makes the assumption that, for example, pointers fit in 32 bits on
  a machine with 32-bit addressing.

  To get around this problem, GNAT also permits the use of 'thin pointers' for
  access types in this case (where the designated type is an unconstrained array
  type).  These thin pointers are indeed the same size as a System.Address value.
  To specify a thin pointer, use a size clause for the type, for example:

  .. code-block:: ada

       type X is access all String;
       for X'Size use Standard'Address_Size;

  which will cause the type X to be represented using a single pointer.
  When using this representation, the bounds are right behind the array.
  This representation is slightly less efficient, and does not allow quite
  such flexibility in the use of foreign pointers or in using the
  Unrestricted_Access attribute to create pointers to non-aliased objects.
  But for any standard portable use of the access type it will work in
  a functionally correct manner and allow porting of existing code.
  Note that another way of forcing a thin pointer representation
  is to use a component size clause for the element size in an array,
  or a record representation clause for an access field in a record.

  See the documentation of Unrestricted_Access in the GNAT RM for a
  full discussion of possible problems using this attribute in conjunction
  with thin pointers.


.. _Compatibility_with_HP_Ada_83:

Compatibility with HP Ada 83
============================

All the HP Ada 83 pragmas and attributes are recognized, although only a subset
of them can sensibly be implemented.  The description of pragmas in
:ref:`Implementation_Defined_Pragmas` indicates whether or not they are
applicable to GNAT.

* *Default floating-point representation*

  In GNAT, the default floating-point format is IEEE, whereas in HP Ada 83,
  it is VMS format.

* *System*

  the package System in GNAT exactly corresponds to the definition in the
  Ada 95 reference manual, which means that it excludes many of the
  HP Ada 83 extensions.  However, a separate package Aux_DEC is provided
  that contains the additional definitions, and a special pragma,
  Extend_System allows this package to be treated transparently as an
  extension of package System.

---

### Gcc Ada Doc Gnat Rm Gnat Implementation Mode (`gcc/ada/doc/gnat_rm/gnat_implementation_mode.rst`)

.. _GNAT_Implementation_Mode:

**************************************************
GNAT Implementation Mode (the ``-gnatg`` switch)
**************************************************

``-gnatg`` enables **GNAT implementation mode**, the internal compilation mode
used when building GNAT itself and its runtime libraries. It is not intended
for user application programs.

It implies ``-gnatw.ge`` (extended warning set, treated as errors) and
``-gnatyg`` (GNAT style checks).

Language & Semantic Changes
===========================

Ada Version and Identifier Rules
---------------------------------

* **Ada version is fixed at Ada 2012**, regardless of other switches.
* **Identifier character set is restricted to 7-bit ASCII**;
  extended characters are disallowed.
* **Identifiers are allowed to start with underscore** to avoid conflicts
  between global symbols in the runtime and those defined in the user code.

Limited Types
-------------

* Copying limited objects is **permitted** (normally illegal).
* Initializing limited types emits a **warning** rather than an error.
* Returning objects of limited types is **permitted**.

Preelaboration and Categorization
----------------------------------

* Categorization errors (pure/preelaborated unit violations) are downgraded
  to **warnings**.
* Statements in preelaborated units emit a **warning** rather than an error.
* Private objects and non-static constants/calls in preelaborated units emit
  **warnings** rather than errors.
* Calls to non-preelaborable subprograms in preelaborated packages are
  demoted to **suppressible warnings** (RM 10.2.1), allowing the runtime to
  include elaboration code that would otherwise be forbidden.
* Assignment statements to library-level variables are **excluded** from
  access-before-elaboration (ABE) analysis, on the assumption that the
  predefined runtime manages its own elaboration order correctly.

Overflow
--------

Overflow checks are **suppressed** but the overflow checking mode is set to
**Strict** (for assertion purposes).

Miscellaneous
-------------

* ``Scalar_Storage_Order`` attribute applies to **generic types** (normally
  it does not).
* Only the ``--!`` special comment sequence is recognized; all others are
  disallowed.
* The ``Priority`` aspect/attribute on protected types accepts the
  unconstrained type ``Any_Priority`` rather than the subtype
  ``System.Priority`` (a subrange of ``Integer``), giving GNAT's own
  protected objects access to the full implementation-defined priority range.
* ``pragma Extend_System`` is **ignored** (prevents circularities in System).
  Exception: predefined renaming units (``Text_IO``, ``Direct_IO``, etc.) are
  compiled without GNAT implementation mode so that ``Extend_System`` still
  works for them.
* Importing a non-pure external function (``pragma Import``) into a ``Pure``
  unit does **not** produce a purity warning, on the assumption that the
  runtime knows the purity properties of the C functions it imports.
* ``pragma Style_Checks ("All_Checks")`` activates the stricter ``-gnatyg``
  rule set rather than the default ``-gnaty`` set.

ALI Files and Recompilation
----------------------------

* ALI files are always generated for predefined generic packages.
* Compiling a unit whose top-level name is ``Ada``, ``Interfaces``, or
  ``System`` as the main unit is permitted; the RM reserves these as
  hierarchical library-unit name prefixes, but the diagnostic is suppressed
  to let GNAT compile its own predefined library (``Ada.Text_IO``,
  ``System.Storage_Elements``, etc.) as main units.

---

### Gcc Ada Doc Gnat Rm Gnat Language Extensions (`gcc/ada/doc/gnat_rm/gnat_language_extensions.rst`)

.. role:: ada(code)
   :language: ada

.. _GNAT_Language_Extensions:

************************
GNAT language extensions
************************

The GNAT compiler implements a certain number of language extensions on top of
the latest Ada standard, implementing its own extended superset of Ada.

There are two sets of language extensions:

* The first is the curated set. The features in that set are features that we
  consider being worthy additions to the Ada language, and that we want to make
  available to users early on.

* The second is the experimental set. It includes the first, but also
  experimental features, which are considered experimental because
  they're still in an early prototyping phase.
  These features might be removed or heavily modified at any time.

How to activate the extended GNAT Ada superset
==============================================

There are two ways to activate the extended GNAT Ada superset:

* The :ref:`Pragma Extensions_Allowed<Pragma_Extensions_Allowed>`. To activate
  the curated set of extensions, you should use

.. code-block:: ada

   pragma Extensions_Allowed (On)

As a configuration pragma, you can either put it at the beginning of a source
file, or in a ``.adc`` file corresponding to your project.

* The ``-gnatX`` command-line option will
  activate the curated subset of extensions.

.. attention:: You can activate the experimental set of extensions
   in addition by using either
   the ``-gnatX0`` command-line option, or the pragma ``Extensions_Allowed`` with
   ``All_Extensions`` as an argument. However, it is not recommended you use
   this subset for serious projects; it is only meant as a technology preview
   for use in playground experiments.

.. _Curated_Language_Extensions:

Curated Extensions
==================

Features activated via ``-gnatX`` or
``pragma Extensions_Allowed (On)``.

Local Declarations Without Block
--------------------------------

A ``basic_declarative_item`` may appear at the place of any statement. This
avoids the heavy syntax of block_statements just to declare something locally.

The only valid kinds of declarations for now are ``object_declaration``,
``object_renaming_declaration``, ``use_package_clause``, and
``use_type_clause``.

For example:

.. code-block:: ada

   if X > 5 then
      X := X + 1;

      Squared : constant Integer := X**2;

      X := X + Squared;
   end if;

It is generally a good practice to declare local variables (or constants) with as
short a lifetime as possible. However, introducing a declare block to accomplish
this is a relatively heavy syntactic load along with a traditional extra level
of indentation. The alternative syntax supported here allows declarations
in any statement sequence.
The lifetime of such local declarations is until the end of
the enclosing construct. The same enclosing construct cannot contain several
declarations of the same defining name; however, overriding symbols from higher-level
scopes works similarly to the explicit ``declare`` block.

If the enclosing construct allows an exception handler (such as an accept
statement, begin-except-end block or a subprogram body), declarations that
appear at the place of a statement are *not* visible within the handler. Only
declarations that precede the beginning of the construct with an exception
handler would be visible in this handler.

.. attention::

  Here are a couple of examples illustrating the scoping rules described above.

   1. Those declarations are not visible from the potential exception handler:

      .. code-block:: ada

         begin
            A : Integer
            ...
         exception
            when others =>
                Put_Line (A'Image) --  ILLEGAL
         end;

   2. The following is legal

      .. code-block:: ada

         declare
            A : Integer := 10;
         begin
            A : Integer := 12;
         end;

      because it is roughly expanded into

      .. code-block:: ada

         declare
            A : Integer := 10;
         begin
            declare
               A : Integer := 12;
            begin
               ...
            end;
         end;

       And as such the second ``A`` declaration is hiding the first one.

Deep delta Aggregates
---------------------

Ada 2022's delta aggregates are extended to allow deep updates.

A delta aggregate may be used to specify new values for subcomponents of the
copied base value, instead of only new values for direct components of the
copied base value. This allows a more compact expression of updated values with
a single delta aggregate, instead of multiple nested delta aggregates.

The syntax of delta aggregates in the extended version is the following:

Syntax
^^^^^^

.. code::

   delta_aggregate ::= record_delta_aggregate | array_delta_aggregate

   record_delta_aggregate ::=
     ( base_expression with delta record_subcomponent_association_list )

   record_subcomponent_association_list ::=
     record_subcomponent_association {, record_subcomponent_association}

   record_subcomponent_association ::=
     record_subcomponent_choice_list => expression

   record_subcomponent_choice_list ::=
     record_subcomponent_choice {'|' record_subcomponent_choice}

   record_subcomponent_choice ::=
       component_selector_name
     | record_subcomponent_choice (expression)
     | record_subcomponent_choice . component_selector_name

   array_delta_aggregate ::=
       ( base_expression with delta array_component_association_list )
     | '[' base_expression with delta array_component_association_list ']'
     | ( base_expression with delta array_subcomponent_association_list )
     | '[' base_expression with delta array_subcomponent_association_list ']'

   array_subcomponent_association_list ::=
     array_subcomponent_association {, array_subcomponent_association}

   array_subcomponent_association ::=
     array_subcomponent_choice_list => expression

   array_subcomponent_choice_list ::=
     array_subcomponent_choice {'|' array_subcomponent_choice}

   array_subcomponent_choice ::=
       ( expression )
     | array_subcomponent_choice (expression)
     | array_subcomponent_choice . component_selector_name

Legality Rules
^^^^^^^^^^^^^^

1. For an ``array_delta_aggregate``, the discrete_choice shall not be **others**.

2. For an ``array_delta_aggregate``, the dimensionality of the type of the
   ``delta_aggregate`` shall be 1.

3. For an ``array_delta_aggregate``, the ``base_expression`` and each
   expression in every ``array_component_association`` or
   ``array_subcomponent_association`` shall be of a nonlimited type.

4. For a ``record_delta_aggregate``, no ``record_subcomponent_choices`` that
   consists of only ``component_selector_names`` shall be the same or a prefix
   of another record_subcomponent_choice.

5. For an ``array_subcomponent_choice`` or a ``record_subcomponent_choice`` the
   ``component_selector_name`` shall not be a subcomponent that depends on
   discriminants of an unconstrained record subtype with defaulted
   discriminants unless its prefix consists of only
   ``component_selector_names``.

   [Rationale: As a result of this rule, accessing the subcomponent can only
   lead to a discriminant check failure if the subcomponent was not present in
   the object denoted by the base_expression, prior to any update.]

Dynamic Semantics
^^^^^^^^^^^^^^^^^

The evaluation of a ``delta_aggregate`` begins with the evaluation of the
``base_expression`` of the delta_aggregate; then that value is used to create
and initialize the anonymous object of the aggregate. The bounds of the
anonymous object of an ``array_delta_aggregate`` and the discriminants (if any)
of the anonymous object of a ``record_delta_aggregate`` are those of the
``base_expression``.

If a ``record_delta_aggregate`` is of a specific tagged type, its tag is that
of the specific type; if it is of a class-wide type, its tag is that of the
base_expression.

For a ``delta_aggregate``, for each ``discrete_choice`` or each subcomponent
associated with a ``record_subcomponent_associated``,
``array_component_association`` or ``array_subcomponent_association`` (in the
order given in the enclosing ``discrete_choice_list`` or
``subcomponent_association_list``, respectively):

- if the associated subcomponent belongs to a variant, a check is made that the
  values of the governing discriminants are such that the anonymous object has
  this component. The exception ``Constraint_Error`` is raised if this check fails.

- if the associated subcomponent is a subcomponent of an array, then for each
  represented index value (in ascending order, if the ``discrete_choice``
  represents a range):

    * the index value is converted to the index type of the array type.

    * a check is made that the index value belongs to the index range of the
      corresponding array part of the anonymous object; ``Constraint_Error`` is
      raised if this check fails.

    * the expression of the ``record_subcomponent_association``,
      ``array_component_association`` or ``array_subcomponent_association`` is
      evaluated, converted to the nominal subtype of the associated subcomponent,
      and assigned to the corresponding subcomponent of the anonymous object.

Examples
^^^^^^^^

.. code-block:: ada
   :linenos:

   declare
      type Point is record
         X, Y : Integer;
      end record;

      type Segment is array (1 .. 2) of Point;
      type Triangle is array (1 .. 3) of Segment;

      S : Segment := (1 .. 2 => (0, 0));
      T : Triangle := (1 .. 3 => (1 .. 2 => (0, 0)));
   begin
      S := (S with delta (1).X => 11, (2).Y => 12, (1).Y => 15);

      pragma Assert (S (1).X = 11);
      pragma Assert (S (2).Y = 12);
      pragma Assert (S (1).Y = 15);

      T := (T with delta (2)(1).Y => 18);
      pragma Assert (T (2)(1).Y = 18);
   end;


Fixed lower bounds for array types and subtypes
-----------------------------------------------

Unconstrained array types and subtypes can be specified with a lower bound that
is fixed to a certain value, by writing an index range that uses the syntax
``<lower-bound-expression> .. <>``. This guarantees that all objects of the
type or subtype will have the specified lower bound.

For example, a matrix type with fixed lower bounds of zero for each dimension
can be declared by the following:

.. code-block:: ada

    type Matrix is
      array (Natural range 0 .. <>, Natural range 0 .. <>) of Integer;

Objects of type ``Matrix`` declared with an index constraint must have index
ranges starting at zero:

.. code-block:: ada

    M1 : Matrix (0 .. 9, 0 .. 19);
    M2 : Matrix (2 .. 11, 3 .. 22);  -- Warning about bounds; will raise CE

Similarly, a subtype of ``String`` can be declared that specifies the lower
bound of objects of that subtype to be ``1``:

 .. code-block:: ada

    subtype String_1 is String (1 .. <>);

If a string slice is passed to a formal of subtype ``String_1`` in a call to a
subprogram ``S``, the slice's bounds will "slide" so that the lower bound is
``1``.

Within ``S``, the lower bound of the formal is known to be ``1``, so, unlike a
normal unconstrained ``String`` formal, there is no need to worry about
accounting for other possible lower-bound values. Sliding of bounds also occurs
in other contexts, such as for object declarations with an unconstrained
subtype with fixed lower bound, as well as in subtype conversions.

Use of this feature increases safety by simplifying code, and can also improve
the efficiency of indexing operations, since the compiler statically knows the
lower bound of unconstrained array formals when the formal's subtype has index
ranges with static fixed lower bounds.

Prefixed-view notation for calls to primitive subprograms of untagged types
---------------------------------------------------------------------------

When operating on an untagged type, if it has any primitive operations, and the
first parameter of an operation is of the type (or is an access parameter with
an anonymous type that designates the type), you may invoke these operations
using an ``object.op(...)`` notation, where the parameter that would normally be
the first parameter is brought out front, and the remaining parameters (if any)
appear within parentheses after the name of the primitive operation.

This same notation is already available for tagged types. This extension allows
for untagged types. It is allowed for all primitive operations of the type
independent of whether they were originally declared in a package spec,
or were inherited and/or overridden as part of a derived type
declaration occurring anywhere, so long as the first parameter is of the type,
or an access parameter designating the type.

For example:

.. code-block:: ada

    generic
       type Elem_Type is private;
    package Vectors is
        type Vector is private;
        procedure Add_Element (V : in out Vector; Elem : Elem_Type);
        function Nth_Element (V : Vector; N : Positive) return Elem_Type;
        function Length (V : Vector) return Natural;
    private
        function Capacity (V : Vector) return Natural;
           --  Return number of elements that may be added without causing
           --  any new allocation of space

        type Vector is ...
          with Type_Invariant => Vector.Length <= Vector.Capacity;
        ...
    end Vectors;

    package Int_Vecs is new Vectors(Integer);

    V : Int_Vecs.Vector;
    ...
    V.Add_Element(42);
    V.Add_Element(-33);

    pragma Assert (V.Length = 2);
    pragma Assert (V.Nth_Element(1) = 42);

Expression defaults for generic formal functions
------------------------------------------------

The declaration of a generic formal function is allowed to specify
an expression as a default, using the syntax of an expression function.

Here is an example of this feature:

.. code-block:: ada

    generic
       type T is private;
       with function Copy (Item : T) return T is (Item); -- Defaults to Item
    package Stacks is

       type Stack is limited private;

       procedure Push (S : in out Stack; X : T); -- Calls Copy on X
       function Pop (S : in out Stack) return T; -- Calls Copy to return item

    private
       -- ...
    end Stacks;

If Stacks is instantiated with an explicit actual for Copy,
then that will be called when Copy is called in the generic body.
If the default is used (i.e. there is no actual corresponding to Copy),
then calls to Copy in the instance will simply return Item.

String interpolation
--------------------

The syntax for string literals is extended to support string interpolation.
An interpolated string literal starts with ``f``, immediately before
the first double-quote character.

Within an interpolated string literal, an arbitrary expression, when
enclosed in ``{ ... }``, is expanded at run time into the result of calling
``'Image`` on the result of evaluating the expression enclosed by the brace
characters, unless it is already a string or a single character.

Here is an example of this feature where the expressions ``Name`` and ``X + Y``
will be evaluated and included in the string.

.. code-block:: ada

   procedure Test_Interpolation is
      X    : Integer := 12;
      Y    : Integer := 15;
      Name : String := "Leo";
   begin
      Put_Line (f"The name is {Name} and the sum is {X + Y}.");
   end Test_Interpolation;

This will print:

.. code-block:: ada

    The name is Leo and the sum is 27.

In addition, an escape character (``\``) is provided for inserting certain
standard control characters (such as ``\t`` for tabulation or ``\n`` for
newline) or to escape characters with special significance to the
interpolated string syntax, namely ``"``, ``{``, ``}``,and ``\`` itself.

=================   =================
escaped_character   meaning
-----------------   -----------------
``\a``              ALERT
``\b``              BACKSPACE
``\f``              FORM FEED
``\n``              LINE FEED
``\r``              CARRIAGE RETURN
``\t``              CHARACTER TABULATION
``\v``              LINE TABULATION
``\0``              NUL
-----------------   -----------------
``\\``              ``\``
``\"``              ``"``
``\{``              ``{``
``\}``              ``}``
=================   =================

Note that, unlike normal string literals, doubled double-quote characters have no
special significance. So to include a double-quote or a brace character
in an interpolated string, they must be preceded by a ``\``.
Multiple interpolated strings are concatenated.
For example:

.. code-block:: ada

    Put_Line
      (f"X = {X} and Y = {Y} and X+Y = {X+Y};\n" &
       f" a double quote is \" and" &
       f" an open brace is \{");

This will print:

.. code-block:: ada

      X = 12 and Y = 15 and X+Y = 27
      a double quote is " and an open brace is {

Constrained attribute for generic objects
-----------------------------------------

The ``Constrained`` attribute is permitted for objects of generic types. The
result indicates whether the corresponding actual is constrained.

``Static`` aspect on intrinsic functions
----------------------------------------

The Ada 202x ``Static`` aspect can be specified on Intrinsic imported functions
and the compiler will evaluate some of these intrinsics statically, in
particular the ``Shift_Left`` and ``Shift_Right`` intrinsics.

First Controlling Parameter
---------------------------

A new pragma/aspect, ``First_Controlling_Parameter``, is introduced for tagged
types, altering the semantics of primitive/controlling parameters. When a
tagged type is marked with this aspect, only subprograms where the first
parameter is of that type will be considered dispatching primitives. This
pragma/aspect applies to the entire hierarchy, starting from the specified
type, without affecting inherited primitives.

Here is an example of this feature:

.. code-block:: ada

    package Example is
       type Root is tagged private;

       procedure P (V : Integer; V2 : Root);
       -- Primitive

       type Child is tagged private
         with First_Controlling_Parameter;

    private
       type Root is tagged null record;
       type Child is new Root with null record;

       overriding
       procedure P (V : Integer; V2 : Child);
       -- Primitive

       procedure P2 (V : Integer; V2 : Child);
       -- NOT Primitive

       function F return Child; -- NOT Primitive

       function F2 (V : Child) return Child;
       -- Primitive, but only controlling on the first parameter
    end Example;

Note that ``function F2 (V : Child) return Child;`` differs from ``F2 (V : Child)
return Child'Class;`` in that the return type is a specific, definite type. This
is also distinct from the legacy semantics, where further derivations with
added fields would require overriding the function.

The option ``-gnatw_j``, that you can pass to the compiler directly, enables
warnings related to this new language feature. For instance, compiling the
example above without this switch produces no warnings, but compiling it with
``-gnatw_j`` generates the following warning on the declaration of procedure P2:

.. code-block:: ada

    warning: not a dispatching primitive of tagged type "Child"
    warning: disallowed by First_Controlling_Parameter on "Child"

For generic formal tagged types, you can specify whether the type has the
First_Controlling_Parameter aspect enabled:

.. code-block:: ada

    generic
       type T is tagged private with First_Controlling_Parameter;
    package T is
        type U is new T with null record;
        function Foo return U; -- Not a primitive
    end T;

For tagged partial views, the value of the aspect must be consistent between
the partial and full views:

.. code-block:: ada

    package R is
       type T is tagged private;
    ...
    private
       type T is tagged null record with First_Controlling_Parameter; -- ILLEGAL
    end R;

Restricting the position of controlling parameter offers several advantages:

* Simplification of the dispatching rules improves readability of Ada programs.
  One doesn't need to analyze all subprogram parameters to understand if the given
  subprogram is a primitive of a certain tagged type.

* A programmer is free to use any type, including class-wide types, on other
  parameters of a subprogram, without the need to consider possible effects of
  overriding a primitive or creating new one.

* The result of a function is never a controlling result.

``Unsigned_Base_Range`` aspect
------------------------------

A new pragma/aspect, ``Unsigned_Base_Range``, is introduced to explicitly
enforce the use of an unsigned base type for signed integer types.
RM-3.5.4(9) mandates a symmetric base range for signed integer types. This
requirement often requires the use of larger data types for arithmetic
operations, potentially introducing undesirable run-time overhead and
performance penalties, particularly in embedded systems. For instance,
on a 64-bit architecture, a 64-bit multiplication can be performed with
a single hardware instruction, whereas a 128-bit multiplication requires
multiple instructions and intermediate steps.

Here is an example of this feature:

.. code-block:: ada

  type Uns_64 is range 0 .. 2 ** 64 - 1
    with Size => 64,
         Unsigned_Base_Range => True;

It ensures that arithmetic operations of type ``Uns_64`` are carried
out using 64 bits.

Generalized Finalization
------------------------

The ``Finalizable`` aspect can be applied to any record type, tagged or not,
to specify that it provides the same level of control on the operations of
initialization, finalization, and assignment of objects as the controlled
types (see RM 7.6(2) for a high-level overview). The only restriction is
that the record type must be a root type, in other words not a derived type.

The aspect additionally makes it possible to specify relaxed semantics for
the finalization operations by means of the ``Relaxed_Finalization`` setting.
Here is the archetypal example:

.. code-block:: ada

    type T is record
      ...
    end record
      with Finalizable => (Initialize           => Initialize,
                           Adjust               => Adjust,
                           Finalize             => Finalize,
                           Relaxed_Finalization => True);

    procedure Adjust     (Obj : in out T);
    procedure Finalize   (Obj : in out T);
    procedure Initialize (Obj : in out T);

The three procedures must be primitive operations of ``T`` and have a single
``in out`` parameter. They need not be all specified by the aspect. If they
are specified, they have the same dynamic semantics as for controlled types:

 - ``Initialize`` is called when an object of type ``T`` is declared without
   initialization expression.

 - ``Adjust`` is called after an object of type ``T`` is assigned a new value.

 - ``Finalize`` is called when an object of type ``T`` goes out of scope (for
   stack-allocated objects) or is deallocated (for heap-allocated objects).
   It is also called when the value is replaced by an assignment.

However, when ``Relaxed_Finalization`` is either ``True`` or not explicitly
specified, the following differences are implemented relative to the semantics
of controlled types:

* The compiler has permission to perform no automatic finalization of
  heap-allocated objects: ``Finalize`` is only called when such an object
  is explicitly deallocated, or when the designated object is assigned a new
  value. As a consequence, no runtime support is needed for performing
  implicit deallocation. In particular, no per-object header data is needed
  for heap-allocated objects.

  Heap-allocated objects allocated through a nested access type will therefore
  **not** be deallocated either. The result is simply that memory will be leaked
  in this case.

* The ``Adjust`` and ``Finalize`` procedures are automatically considered as
  having the :ref:`No_Raise_Aspect` specified for them. In particular, the
  compiler has permission to enforce none of the guarantees specified by the
  RM 7.6.1 (14/1) and subsequent subclauses.

Simple example of ref-counted type:

.. code-block:: ada

   type T is record
      Value     : Integer;
      Ref_Count : Natural := 0;
   end record;

   procedure Inc_Ref (X : in out T);
   procedure Dec_Ref (X : in out T);

   type T_Access is access all T;

   type T_Ref is record
      Value : T_Access;
   end record
      with Finalizable => (Adjust   => Adjust,
                           Finalize => Finalize);

   procedure Adjust (Ref : in out T_Ref) is
   begin
      Inc_Ref (Ref.Value);
   end Adjust;

   procedure Finalize (Ref : in out T_Ref) is
   begin
      Def_Ref (Ref.Value);
   end Finalize;

Simple file handle that ensures resources are properly released:

.. code-block:: ada

   package P is
      type File (<>) is limited private;

      function Open (Path : String) return File;

      procedure Close (F : in out File);

   private
      type File is limited record
         Handle : ...;
      end record
         with Finalizable (Finalize => Close);
   end P;

Finalizable tagged types
^^^^^^^^^^^^^^^^^^^^^^^^

The aspect is inherited by derived types and the primitives may be overridden
by the derivation. The compiler-generated calls to these operations are then
dispatching whenever it makes sense, i.e. when the object in question is of a
class-wide type and the class includes at least one finalizable tagged type.

Composite types
^^^^^^^^^^^^^^^

When a finalizable type is used as a component of a composite type, the latter
becomes finalizable as well. The three primitives are derived automatically
in order to call the primitives of their components. The dynamic semantics is
the same as for controlled components of composite types.

Interoperability with controlled types
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Finalizable types are fully interoperable with controlled types, in particular
it is possible for a finalizable type to have a controlled component and vice
versa, but the stricter dynamic semantics, in other words that of controlled
types, is applied in this case.

.. _Experimental_Language_Extensions:

Experimental Language Extensions
================================

Features activated via ``-gnatX0`` or
``pragma Extensions_Allowed (All_Extensions)``.

Conditional when constructs
---------------------------

This feature extends the use of ``when`` as a way to condition a control-flow
related statement, to all control-flow related statements.

To do a conditional return in a procedure the following syntax should be used:

.. code-block:: ada

   procedure P (Condition : Boolean) is
   begin
      return when Condition;
   end P;

This will return from the procedure if ``Condition`` is true.

When being used in a function the conditional part comes after the return value:

.. code-block:: ada

   function Is_Null (I : Integer) return Boolean is
   begin
      return True when I = 0;
      return False;
   end;

In a similar way to the ``exit when`` a ``goto ... when`` can be employed:

.. code-block:: ada

   procedure Low_Level_Optimized is
      Flags : Bitmapping;
   begin
      Do_1 (Flags);
      goto Cleanup when Flags (1);

      Do_2 (Flags);
      goto Cleanup when Flags (32);

      --  ...

   <<Cleanup>>
      --  ...
   end;

.. code-block

To use a conditional raise construct:

.. code-block:: ada

   procedure Foo is
   begin
      raise Error when Imported_C_Func /= 0;
   end;

An exception message can also be added:

.. code-block:: ada

   procedure Foo is
   begin
      raise Error with "Unix Error"
        when Imported_C_Func /= 0;
   end;

Implicit With
-------------

This feature allows a standalone ``use`` clause in the context clause of a
compilation unit to imply an implicit ``with`` of the same library unit where
an equivalent ``with`` clause would be allowed.

.. code-block:: ada

   use Ada.Text_IO;
   procedure Main is
   begin
      Put_Line ("Hello");
   end;


Storage Model
-------------

This extends Storage Pools into a more efficient model allowing higher performance,
easier integration with low footprint embedded run-times and copying data between
different pools of memory. The latter is especially useful when working with distributed
memory models, in particular to support interactions with GPU.

Aspect Storage_Model_Type
^^^^^^^^^^^^^^^^^^^^^^^^^^

A Storage model is a type with a specified ``Storage_Model_Type``
aspect, e.g.:

.. code-block:: Ada

   type A_Model is null record
      with Storage_Model_Type (...);

Storage_Model_Type itself accepts six parameters:

- Address_Type, the type of the address managed by this model. This has to be
  a scalar type or derived from System.Address.
- Allocate, a procedure used for allocating memory in this model
- Deallocate, a procedure used for deallocating memory in this model
- Copy_To, a procedure used to copy memory from native memory to this model
- Copy_From, a procedure used to copy memory from this model to native memory
- Storage_Size, a function returning the amount of memory left
- Null_Address, a value for the null address value

By default, Address_Type is System.Address, and the five subprograms
perform native operations (e.g. the allocator is the native ``new`` allocator).
Users can decide to specify one or more of these. When an Address_Type is
specified to be other than System.Address, all of the subprograms have
to be specified.

The prototypes of these procedures are as follows:

.. code-block:: Ada

   procedure Allocate
     (Model           : in out A_Model;
      Storage_Address : out Address_Type;
      Size            : Storage_Count;
      Alignment       : Storage_Count);

   procedure Deallocate
     (Model           : in out A_Model;
      Storage_Address : out Address_Type;
      Size            : Storage_Count;
      Alignment       : Storage_Count);

   procedure Copy_To
     (Model   : in out A_Model;
      Target  : Address_Type;
      Source  : System.Address;
      Size    : Storage_Count);

   procedure Copy_From
     (Model  : in out A_Model;
      Target : System.Address;
      Source : Address_Type;
      Size   : Storage_Count);

   function Storage_Size
     (Pool : A_Model)
      return Storage_Count;

Here's an example of how this could be instantiated in the context of CUDA:

.. code-block:: Ada

   package CUDA_Memory is

      type CUDA_Storage_Model is null record
         with Storage_Model_Type => (
            Address_Type => CUDA_Address,
            Allocate     => CUDA_Allocate,
            Deallocate   => CUDA_Deallocate,
            Copy_To      => CUDA_Copy_To,
            Copy_From    => CUDA_Copy_From,
            Storage_Size => CUDA_Storage_Size,
            Null_Address => CUDA_Null_Address
         );

      type CUDA_Address is new System.Address;
      --  We're assuming for now same address size on host and device

      procedure CUDA_Allocate
        (Model           : in out CUDA_Storage_Model;
         Storage_Address : out CUDA_Address;
         Size            : Storage_Count;
         Alignment       : Storage_Count);

      procedure CUDA_Deallocate
        (Model           : in out CUDA_Storage_Model;
         Storage_Address : out CUDA_Address;
         Size            : Storage_Count;
         Alignment       : Storage_Count);

      procedure CUDA_Copy_To
        (Model  : in out CUDA_Storage_Model;
         Target : CUDA_Address;
         Source : System.Address;
         Size   : Storage_Count);

      procedure CUDA_Copy_From
        (Model   : in out CUDA_Storage_Model;
         Target  : System.Address;
         Source  : CUDA_Address;
         Size    : Storage_Count);

      function CUDA_Storage_Size
        (Pool : CUDA_Storage_Model)
         return Storage_Count return Storage_Count'Last;

      CUDA_Null_Address : constant CUDA_Address :=
         CUDA_Address (System.Null_Address);

      CUDA_Memory : CUDA_Storage_Model;

   end CUDA_Memory;

Aspect Designated_Storage_Model
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A new aspect, Designated_Storage_Model, allows to specify the memory model
for the objects pointed by an access type. Under this aspect, allocations
and deallocations will come from the specified memory model instead
of the standard ones. In addition, if write operations are needed for
initialization, or if there is a copy of the target object from and to a
standard memory area, the Copy_To and Copy_From functions will be called.
It allows to encompass the capabilities of storage pools, e.g.:

.. code-block:: Ada

   procedure Main is
      type Integer_Array is array (Integer range <>) of Integer;

      type Host_Array_Access is access all Integer_Array;
      type Device_Array_Access is access Integer_Array
         with Designated_Storage_Model => CUDA_Memory;

      procedure Free is new Unchecked_Deallocation
         (Host_Array_Type, Host_Array_Access);
      procedure Free is new Unchecked_Deallocation
         (Device_Array_Type, Device_Array_Access);

      Host_Array : Host_Array_Access := new Integer_Array (1 .. 10);

      Device_Array : Device_Array_Access := new Host_Array (1 .. 10);
      --  Calls CUDA_Storage_Model.Allocate to allocate the fat pointers and
      --  the bounds, then CUDA_Storage_Model.Copy_In to copy the values of the
      --  boundaries.
   begin
      Host_Array.all := (others => 0);

      Device_Array.all := Host_Array.all;
      --  Calls CUDA_Storage_Model.Copy_To to write to the device array from the
      --  native memory.

      Host_Array.all := Device_Array.all;
      --  Calls CUDA_Storage_Model.Copy_From to read from the device array and
      --  write to native memory.

      Free (Host_Array);

      Free (Device_Array);
      --  Calls CUDA_Storage_Model.Deallocate;
   end;

Taking ``'Address`` of an object with a specific memory model returns an object of
the type of the address for that memory category, which may be different from
System.Address.

When copying is performed between two specific memory models, the native memory
is used as a temporary between the two. E.g.:

.. code-block:: Ada

  type Foo_I is access Integer with Designated_Storage_Model => Foo;
  type Bar_I is access Integer with Designated_Storage_Model => Bar;

    X : Foo_I := new Integer;
    Y : Bar_I := new Integer;
  begin
    X.all := Y.all;

conceptually becomes:

.. code-block:: Ada

    X : Foo_I := new Integer;
    T : Integer;
    Y : Bar_I := new Integer;
  begin
    T := Y.all;
    X.all := T;

Legacy Storage Pools
^^^^^^^^^^^^^^^^^^^^^

Legacy Storage Pools are now replaced by a Storage_Model_Type.
They are implemented as follows:

.. code-block:: Ada

   type Root_Storage_Pool is abstract
     new Ada.Finalization.Limited_Controlled with private
   with Storage_Model_Type => (
      Allocate     => Allocate,
      Deallocate   => Deallocate,
      Storage_Size => Storage_Size
   );
   pragma Preelaborable_Initialization (Root_Storage_Pool);

   procedure Allocate
     (Pool                     : in out Root_Storage_Pool;
      Storage_Address          : out System.Address;
      Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
      Alignment                : System.Storage_Elements.Storage_Count)
   is abstract;

   procedure Deallocate
     (Pool                     : in out Root_Storage_Pool;
      Storage_Address          : System.Address;
      Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
      Alignment                : System.Storage_Elements.Storage_Count)
   is abstract;

   function Storage_Size
     (Pool : Root_Storage_Pool)
      return System.Storage_Elements.Storage_Count
   is abstract;

The legacy notation:

.. code-block:: Ada

   type My_Pools is new Root_Storage_Pool with record [...]

   My_Pool_Instance : Storage_Model_Pool.Storage_Model :=
      My_Pools'(others => <>);

   type Acc is access Integer_Array with Storage_Pool => My_Pool;

can still be accepted as a shortcut for the new syntax.

Attribute Super
---------------
.. index:: Super

The ``Super`` attribute can be applied to objects of tagged types in order
to obtain a view conversion to the most immediate specific parent type.

It cannot be applied to objects of types without any ancestors.

.. code-block:: ada

  type T1 is tagged null record;
  procedure P (V : T1);

  type T2 is new T1 with null record;

  type T3 is new T2 with null record;
  procedure P (V : T3);

  procedure Call (
    V1 : T1'Class;
    V2 : T2'Class;
    V3 : T3'Class) is
  begin
    V1'Super.P; --  Illegal call as T1 doesn't have any ancestors
    V2'Super.P; --  Equivalent to "T1 (V).P;", a non-dispatching call
                --  to T1's primitive procedure P.
    V3'Super.P; --  Equivalent to "T2 (V).P;"; Since T2 doesn't
                --  override P, a non-dispatching call to T1.P is
                --  executed.
  end;

Simpler Accessibility Model
---------------------------

The goal of this feature is to simplify the accessibility rules by removing
dynamic accessibility checks that are often difficult to understand and debug.
The new rules eliminate the need for runtime accessibility checks by imposing
more conservative legality rules when enabled via a new restriction (see RM 13.12),
No_Dynamic_Accessibility_Checks, which prevents dangling reference problems
at compile time.

This restriction has no effect on the user-visible behavior of a program when executed;
the only effect of this restriction is to enable additional compile-time checks
(described below) which ensure statically that Ada's dynamic accessibility checks
will not fail.

The feature can be activated with ``pragma Restrictions (No_Dynamic_Accessibility_Checks);``.
As a result, additional compile-time checks are performed; these checks pertain to
stand-alone objects, subprogram parameters, and function results as described below.

All of the refined rules are compatible with the [use of anonymous access types in SPARK]
(http://docs.adacore.com/spark2014-docs/html/lrm/declarations-and-types.html#access-types).


Stand-alone objects
^^^^^^^^^^^^^^^^^^^^

.. code-block:: ada

   Var        : access T := ...
   Var_To_Cst : access constant T := ...
   Cst        : constant access T := ...
   Cst_To_Cst : constant access constant T := ...

In this section, we will refer to a stand-alone object of an anonymous access
type as an SO.

When the restriction is in effect, the "statically deeper" relationship
(see RM 3.10.2(4)) does apply to the type of a SO (contrary to RM 3.10.2(19.2))
and, for the purposes of compile-time checks, the accessibility level of the
type of a SO is the accessibility level of that SO.
This supports many common use-cases without the employment of ``Unchecked_Access``
while still removing the need for dynamic checks.

This statically disallows cases that would otherwise require a dynamic accessibility
check, such as

.. code-block:: ada

   type Ref is access all Integer;
   Ptr : Ref;
   Good : aliased Integer;

   procedure Proc is
      Bad : aliased Integer;
      Stand_Alone : access Integer;
   begin
      if <some condition> then
         Stand_Alone := Good'Access;
      else
         Stand_Alone := Bad'Access;
      end if;
      Ptr := Ref (Stand_Alone);
   end Proc;

If a No_Dynamic_Accessibility_Checks restriction is in effect, then the otherwise-legal
type conversion (the right-hand side of the assignment to Ptr) becomes a violation
of the RM 4.6 rule "The accessibility level of the operand type shall not be
statically deeper than that of the target type ...".

Subprogram parameters
^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: ada

   procedure P (V : access T; X : access constant T);


In most cases (the exceptions are described below), a No_Dynamic_Accessibility_Checks
restriction means that the "statically deeper" relationship does apply to the anonymous
type of an access parameter specifying an access-to-object type (contrary to RM 3.10.2(19.1))
and, for purposes of compile-time "statically deeper" checks, the accessibility level
of the type of such a parameter is the accessibility level of the parameter.

This change (at least as described so far) doesn't affect the caller's side, but on the
callee's side it means that object designated by a non-null parameter of an anonymous
access type is treated as having the same accessibility level as a local object declared
immediately within the called subprogram.

With the restriction in effect, the otherwise-legal type conversion in the following example
becomes illegal:

.. code-block:: ada

   type Ref is access all Integer;
   Ptr : Ref;

   procedure Proc (Param : access Integer) is
   begin
      Ptr := Ref (Param);
   end Proc;

The aforementioned exceptions have to do with return statements from functions that either
return the given parameter (in the case of a function whose result type is an anonymous
access type) or return the given parameter value as an access discriminant of the function
result (or of some discriminated part thereof). More specifically, the "statically deeper"
changes described above do not apply for purposes of checking the "shall not be statically
deeper" rule for access discriminant parts of function results (RM 6.5(5.9)) or in determining
the legality of an (implicit) type conversion from the anonymous access type of a parameter
of a function to an anonymous access result type of that function. In order to prevent these
rule relaxations from introducing the possibility of dynamic accessibility check failures,
compensating compile-time checks are performed at the call site to prevent cases where
including the value of an access parameter as part of a function result could make such
check failures possible (specifically, the discriminant checks of RM 6.5(21) or, in the
case of an anonymous access result type, the RM 4.6(48) check performed when converting
to that result type). These compile-time checks are described in the next section.

From the callee's perspective, the level of anonymous access formal parameters would be
between the level of the subprogram and the level of the subprogram's locals. This has the effect
of formal parameters being treated as local to the callee except in:

* Use as a function result
* Use as a value for an access discriminant in result object
* Use as an assignments between formal parameters

Note that with these more restricted rules we lose track of accessibility levels when assigned to
local objects thus making (in the example below) the assignment to Node2.Link from Temp below
compile-time illegal.

.. code-block:: ada

   type Node is record
      Data : Integer;
      Link : access Node;
   end record;

   procedure Swap_Links (Node1, Node2 : in out Node) is
      Temp : constant access Node := Node1.Link; -- We lose the "association" to Node1
   begin
      Node1.Link := Node2.Link; -- Allowed
      Node2.Link := Temp;       -- Not allowed
   end;

   function Identity (N : access Node) return access Node is
      Local : constant access Node := N;
   begin
      if True then
         return N;              -- Allowed
      else
         return Local;          -- Not allowed
      end if;
   end;

Function results
^^^^^^^^^^^^^^^^

.. code-block:: ada

   function Get (X : Rec) return access T;

If the result subtype of a function is either an anonymous access (sub)type, a
class-wide (sub)type, an unconstrained subtype with an access discriminant, or
a type with an unconstrained subcomponent subtype that has at least one access
discriminant (this last case is only possible if the access discriminant has a
default value), then we say that the function result type "might require an
anonymous-access-part accessibility check". If a function has an access parameter,
or a parameter whose subtype "might require an anonymous-access-part accessibility
check", then we say that the each such parameter "might be used to pass in an
anonymous-access value". If the first of these conditions holds for the result
subtype of a function and the second condition holds for at least one parameter
that function, then it is possible that a call to that function could return a
result that contains anonymous-access values that were passed in via the parameter.

Given a function call where the result type "might require an anonymous-access-part
accessibility check" and a formal parameter of that function that "might be used to
pass in an anonymous-access value", either the type of that formal parameter is an
anonymous access type or it is not. If it is, and if a No_Dynamic_Access_Checks
restriction is in effect, then the accessibility level of the type of the actual
parameter shall be statically known to not be deeper than that of the master of
the call. If it isn't, then the accessibility level of the actual parameter shall
be statically known to not be deeper than that of the master of the call.

Function result example:

.. code-block:: ada

   declare
      type T is record
         Comp : aliased Integer;
      end record;

      function Identity (Param : access Integer) return access Integer is
      begin
         return Param;        -- Legal
      end;

      function Identity_2 (Param : aliased Integer) return access Integer is
      begin
         return Param'Access; -- Legal
      end;

      X : access Integer;
   begin
      X := Identity (X);      -- Legal
      declare
         Y : access Integer;
         Z : aliased Integer;
      begin
         X := Identity (Y);   -- Illegal since Y is too deep
         X := Identity_2 (Z); -- Illegal since Z is too deep
      end;
   end;

In order to avoid having to expand the definition of "might be used to pass in an
anonymous-access value" to include any parameter of a tagged type, the
No_Dynamic_Access_Checks restriction also imposes a requirement that a type extension
cannot include the explicit definition of an access discriminant.

Here is an example of one such case of an upward conversion which would lead to a memory leak:

.. code-block:: ada

   declare
      type T is tagged null record;
      type T2 (Disc : access Integer) is new T with null record; -- Must be illegal

      function Identity (Param : aliased T'Class) return access Integer is
      begin
         return T2 (T'Class (Param)).Disc; -- Here P gets effectively returned and set to X
      end;

      X : access Integer;
   begin
      declare
         P : aliased Integer;
         Y : T2 (P'Access);
      begin
         X := Identity (T'Class (Y)); -- Pass local variable P (via Y's discriminant),
                                    -- leading to a memory leak.
      end;
   end;
   ```

   Thus we need to make the following illegal to avoid such situations:

   ```ada
   package Pkg1 is
      type T1 is tagged null record;
      function Func (X1 : T1) return access Integer is (null);
   end;

   package Pkg2 is
      type T2 (Ptr1, Ptr2 : access Integer) is new Pkg1.T1 with null record; -- Illegal
      ...
   end;

In order to prevent upward conversions of anonymous function results (like below), we
also would need to assure that the level of such a result (from the callee's perspective)
is statically deeper:

.. code-block:: ada

   declare
      type Ref is access all Integer;
      Ptr : Ref;
      function Foo (Param : access Integer) return access Integer is
      begin
         return Result : access Integer := Param; do
            Ptr := Ref (Result); -- Not allowed
         end return;
      end;
   begin
      declare
         Local : aliased Integer;
      begin
         Foo (Local'Access).all := 123;
      end;
   end;

Case pattern matching
---------------------

The selector for a case statement (but not for a case expression) may
be of a composite type, subject to some restrictions (described below).
Aggregate syntax is used for choices of such a case statement; however,
in cases where a "normal" aggregate would require a discrete value, a
discrete subtype may be used instead; box notation can also be used to
match all values.

Consider this example:

.. code-block:: ada

  type Rec is record
     F1, F2 : Integer;
  end record;

  procedure Caser_1 (X : Rec) is
  begin
     case X is
        when (F1 => Positive, F2 => Positive) =>
           Do_This;
        when (F1 => Natural, F2 => <>) | (F1 => <>, F2 => Natural) =>
           Do_That;
        when others =>
            Do_The_Other_Thing;
     end case;
  end Caser_1;

If ``Caser_1`` is called and both components of X are positive, then
``Do_This`` will be called; otherwise, if either component is nonnegative
then ``Do_That`` will be called; otherwise, ``Do_The_Other_Thing`` will be
called.

In addition, pattern bindings are supported. This is a mechanism
for binding a name to a component of a matching value for use within
an alternative of a case statement. For a component association
that occurs within a case choice, the expression may be followed by
``is <identifier>``. In the special case of a "box" component association,
the identifier may instead be provided within the box. Either of these
indicates that the given identifier denotes (a constant view of) the matching
subcomponent of the case selector.

.. attention:: Binding is not yet supported for arrays or subcomponents
   thereof.

Consider this example (which uses type ``Rec`` from the previous example):

.. code-block:: ada

  procedure Caser_2 (X : Rec) is
  begin
     case X is
        when (F1 => Positive is Abc, F2 => Positive) =>
           Do_This (Abc)
        when (F1 => Natural is N1, F2 => <N2>) |
             (F1 => <N2>, F2 => Natural is N1) =>
           Do_That (Param_1 => N1, Param_2 => N2);
        when others =>
           Do_The_Other_Thing;
     end case;
  end Caser_2;

This example is the same as the previous one with respect to determining
whether ``Do_This``, ``Do_That``, or ``Do_The_Other_Thing`` will be called. But
for this version, ``Do_This`` takes a parameter and ``Do_That`` takes two
parameters. If ``Do_This`` is called, the actual parameter in the call will be
``X.F1``.

If ``Do_That`` is called, the situation is more complex because there are two
choices for that alternative. If ``Do_That`` is called because the first choice
matched (i.e., because ``X.F1`` is nonnegative and either ``X.F1`` or ``X.F2``
is zero or negative), then the actual parameters of the call will be (in order)
``X.F1`` and ``X.F2``. If ``Do_That`` is called because the second choice
matched (and the first one did not), then the actual parameters will be
reversed.

Within the choice list for single alternative, each choice must define the same
set of bindings and the component subtypes for for a given identifier must all
statically match. Currently, the case of a binding for a nondiscrete component
is not implemented.

If the set of values that match the choice(s) of an earlier alternative
overlaps the corresponding set of a later alternative, then the first set shall
be a proper subset of the second (and the later alternative will not be
executed if the earlier alternative "matches"). All possible values of the
composite type shall be covered. The composite type of the selector shall be an
array or record type that is neither limited nor class-wide. Currently, a "when
others =>" case choice is required; it is intended that this requirement will
be relaxed at some point.

If a subcomponent's subtype does not meet certain restrictions, then the only
value that can be specified for that subcomponent in a case choice expression
is a "box" component association (which matches all possible values for the
subcomponent). This restriction applies if:

- the component subtype is not a record, array, or discrete type; or

- the component subtype is subject to a non-static constraint or has a
  predicate; or:

- the component type is an enumeration type that is subject to an enumeration
  representation clause; or

- the component type is a multidimensional array type or an array type with a
  nonstatic index subtype.

Support for casing on arrays (and on records that contain arrays) is
currently subject to some restrictions. Non-positional
array aggregates are not supported as (or within) case choices. Likewise
for array type and subtype names. The current implementation exceeds
compile-time capacity limits in some annoyingly common scenarios; the
message generated in such cases is usually "Capacity exceeded in compiling
case statement with composite selector type".

Mutably Tagged Types with Size'Class Aspect
-------------------------------------------

For a specific tagged nonformal type T that satisfies some conditions
described later in this section, the universal-integer-valued type-related
representation aspect ``Size'Class`` may be specified; any such specified
aspect value shall be static.

Specifying this aspect imposes an upper bound on the sizes of all specific
descendants of T (including T itself). T'Class (but not T) is then said to be
a "mutably tagged" type - meaning that T'Class is a definite subtype and that
the tag of a variable of type T'Class may be modified by assignment in some
cases described later in this section. An inherited ``Size'Class`` aspect
value may be overridden, but not with a larger value.

If the ``Size'Class`` aspect is specified for a type T, then every specific
descendant of T (including T itself)

* shall have a Size that does not exceed the specified value; and

* shall have a (possibly inherited) ``Size'Class`` aspect that does not exceed
  the specified value; and

* shall be undiscriminated; and

* shall have no composite subcomponent whose subtype is subject to a nonstatic
  constraint; and

* shall not have a tagged partial view other than a private extension; and

* shall not be a descendant of an interface type; and

* shall not have a statically deeper accessibility level than that of T.

If the ``Size'Class`` aspect is not specified for a type T (either explicitly
or by inheritance), then it shall not be specified for any descendant of T.

Example:

.. code-block:: ada

    type Root_Type is tagged null record with Size'Class => 16 * 8;

    type Derived_Type is new Root_Type with record
       Stuff : Some_Type;
    end record;  -- ERROR if Derived_Type exceeds 16 bytes

Because any subtype of a mutably tagged type is definite, it can be used as a
component subtype for enclosing array or record types, as the subtype of a
default-initialized stand-alone object, or as the subtype of an uninitialized
allocator, as in this example:

.. code-block:: ada

    Obj : Root_Type'Class;
    type Array_of_Roots is array (Positive range <>) of Root_Type'Class;

Default initialization of an object of such a definite subtype proceeds as
for the corresponding specific type, except that Program_Error is raised if
the specific type is abstract. In particular, the initial tag of the object
is that of the corresponding specific type.

There is a general design principle that if a type has a tagged partial view,
then the type's ``Size'Class`` aspect (or lack thereof) should be determinable
by looking only at the partial view. That provides the motivation for the
rules of the next two paragraphs.

If a type has a tagged partial view, then a ``Size'Class`` aspect specification
may be provided only at the point of the partial view declaration (in other
words, no such aspect specification may be provided when the full view of
the type is declared). All of the above rules (in particular, the rule that
an overriding ``Size'Class`` aspect value shall not be larger than the
overridden inherited value) are also enforced when the full view (which may
have a different ancestor type than that of the partial view) is declared.
If a partial view for a type inherits a ``Size'Class`` aspect value and does
not override that value with an explicit aspect specification, then the
(static) aspect values inherited by the partial view and by the full view
shall be equal.

An actual parameter of an instantiation whose corresponding formal parameter
is a formal tagged private type shall not be either mutably tagged or the
corresponding specific type of a mutably tagged type.

For the legality rules in this section, the RM 12.3(11) rule about legality
checking in the visible part and formal part of an instance is extended (in
the same way that it is extended in many other places in the RM) to include
the private part of an instance.

An object (or a view thereof) of a tagged type is defined to be
"tag-constrained" if it is

* an object whose type is not mutably tagged; or

* a constant object; or

* a view conversion of a tag-constrained object; or

* a view conversion to a type that is not a descendant of the operand's
  type; or

* a formal in out or out parameter whose corresponding actual parameter is
  tag-constrained; or

* a dereference of an access value.

In the case of an assignment to a tagged variable that is not
tag-constrained, no check is performed that the tag of the value
of the expression is the same as that of the target (RM 5.2 notwithstanding).
Instead, the tag of the target object becomes that of the source object of
the assignment. Note that the tag of an object of a mutably tagged type MT
will always be the tag of some specific type that is a descendant of MT.
An assignment to a composite object similarly copies the tags of any
subcomponents of the source object that have a mutably tagged type.

The Constrained attribute is defined for any name denoting an object of a
mutably tagged type (RM 3.7.2 notwithstanding). In this case, the
Constrained attribute yields the value True if the object is
tag-constrained and False otherwise.

Renaming is not allowed (see RM 8.5.1) for a type conversion having an operand
of a mutably tagged type MT and a target type TT such that TT (or its
corresponding specific type if TT is class-wide) is not an ancestor of MT
(this is sometimes called a "downward" conversion), nor for any part of
such an object, nor for any slice of any part of such an object. This
rule also applies in any context where a name is required to be one for
which "renaming is allowed" (for example, see RM 12.4).
[This is analogous to the way that renaming is not allowed for a
discriminant-dependent component of an unconstrained variable.]

A name denoting a view of a variable of a mutably tagged type shall not occur
as an operative constituent of the prefix of a name denoting a prefixed
view of a callable entity, except as the callee name in a call to the
callable entity. This disallows, for example, renaming such a prefixed view,
passing the prefixed view name as a generic actual parameter, or using the
prefixed view name as the prefix of an attribute.

The execution of a construct is erroneous if the construct has a constituent
that is a name denoting a subcomponent of a tagged object and the object's
tag is changed by this execution between evaluating the name and the last
use (within this execution) of the subcomponent denoted by the name.
This is analogous to the RM 3.7.2(4) rule about discriminant-dependent
subcomponents.

If the type of a formal parameter is a specific tagged type, then the execution
of the call is erroneous if the tag of the actual is changed while the formal
parameter exists (that is, before leaving the corresponding callable construct).
This is analogous to the RM 6.4.1(18) rule about discriminated parameters.

.. _No_Raise_Aspect:

No_Raise aspect
----------------

The ``No_Raise`` aspect can be applied to a subprogram to declare that this
subprogram is not expected to raise an exception. Should an exception still
be raised during the execution of the subprogram, it is caught at the end of
this execution and ``Program_Error`` is propagated to the caller.

Inference of Dependent Types in Generic Instantiations
------------------------------------------------------

If a generic formal type T2 depends on another formal type T1,
the actual for T1 can be inferred from the actual for T2.
That is, you can give the actual for T2, and leave out the one
for T1.

For example, ``Ada.Unchecked_Deallocation`` has two generic formals:

.. code-block:: ada

   generic
      type Object (<>) is limited private;
      type Name is access Object;
   procedure Ada.Unchecked_Deallocation (X : in out Name);

where ``Name`` depends on ``Object``. With this language extension,
you can leave out the actual for ``Object``, as in:

.. code-block:: ada

   type Integer_Access is access all Integer;

   procedure Free is new Unchecked_Deallocation (Name => Integer_Access);

The compiler will infer that the actual type for ``Object`` is ``Integer``.
Note that named notation is always required when using inference.

The following inferences are allowed:

- For a formal access type, the designated type can be inferred.

- For a formal array type, the index type(s) and the component
  type can be inferred.

- For a formal type with discriminants, the type(s) of the discriminants
  can be inferred.

Example for arrays:

.. code-block:: ada

   generic
      type Element_Type is private;
      type Index_Type is (<>);
      type Array_Type is array (Index_Type range <>) of Element_Type;
   package Array_Operations is
      ...
   end Array_Operations;

   ...

   type Int_Array is array (Positive range <>) of Integer;

   package Int_Array_Operations is new Array_Operations (Array_Type => Int_Array);

The index and component types of ``Array_Type`` are inferred from
``Int_Array``, so that the above instantiation is equivalent to
the following standard-Ada instantiation:

.. code-block:: ada

   package Int_Array_Operations is new Array_Operations
      (Element_Type => Integer,
         Index_Type   => Positive,
         Array_Type   => Int_Array);


External_Initialization Aspect
------------------------------

The ``External_Initialization`` aspect provides a feature similar to Rust's ``include_bytes!``
and to C23's ``#embed``. It has the effect of initializing an object with the contents of
a file specified by a file path.

Only string objects and objects of type ``Ada.Streams.Stream_Element_Array`` can be subject
to the ``External_Initialization`` aspect.

Example:

.. code-block:: ada

   with Ada.Streams;

   package P is
      S : constant String with External_Initialization => "foo.txt";

      X : constant Ada.Streams.Stream_Element_Array with External_Initialization => "bar.bin";
   end P;

``External_Initialization`` aspect accepts the following parameters:

- mandatory ``Path``: the path the compiler uses to access the binary resource.

If ``Path`` is a relative path, it is interpreted relatively to the directory of the file that contains the aspect specification.

.. attention:: The maximum size of loaded files is limited to 2\ :sup:`31` bytes.


Finally construct
-----------------

The ``finally`` keyword makes it possible to have a sequence of statements be executed when
another sequence of statements is completed, whether normally or abnormally.

This feature is similar to the one with the same name in other languages such as Java.

Note that ``finally`` is a keyword but it is not a reserved word. This is a
configuration that does not exist in standard Ada.

Syntax
^^^^^^

.. code-block:: text

   handled_sequence_of_statements ::=
        sequence_of_statements
     [exception
        exception_handler
       {exception_handler}]
     [finally
       sequence_of_statements]

Legality Rules
^^^^^^^^^^^^^^

Return statements in the ``sequence_of_statements`` attached to the finally that would cause control
to be transferred outside the finally part are forbidden.

Goto & exit where the target is outside of the finally's ``sequence_of_statements`` are forbidden

Dynamic Semantics
^^^^^^^^^^^^^^^^^

Statements in the optional ``sequence_of_statements`` contained in the ``finally`` branch will be
executed unconditionally, after the main ``sequence_of_statements`` is executed, and after any
potential ``exception_handler`` is executed.

If an exception is raised in the finally part, it cannot be caught by the ``exception_handler``.

Abort/ATC (asynchronous transfer of control) cannot interrupt a finally block, nor prevent its
execution, that is the finally block must be executed in full even if the containing task is
aborted, or if the control is transferred out of the block.

Continue statement
------------------

The ``continue`` keyword makes it possible to stop execution of a loop iteration
and continue with the next one. A continue statement has the same syntax
(except "exit" is replaced with "continue"), static semantics, and legality
rules as an exit statement. The difference is in the dynamic semantics: where an
exit statement would cause a transfer of control that completes the (implicitly
or explicitly) specified loop_statement, a continue statement would instead
cause a transfer of control that completes only the current iteration of that
loop_statement, like a goto statement targeting a label following the last
statement in the sequence of statements of the specified loop_statement.

Note that ``continue`` is a keyword but it is not a reserved word. This is a
configuration that does not exist in standard Ada.

Destructors
-----------

The :ada:`Destructor` extension adds a new finalization mechanism that
significantly differs from standard Ada in how it interacts with type
derivation.

New syntax is introduced to make it possible to define "destructors" for record
types, tagged or untagged. Here's a simple example:

.. code-block:: ada

   package P is
      type T is record
         ...
      end record;

      procedure T'Destructor (X : in out T);
   end P;

.. code-block:: ada

   package body P is
      procedure T'Destructor (X : in out T) is
      begin
         ...
      end T'Destructor;
   end P;

Like :ada:`Finalize` procedures, destructors are called on objects just before they
are destroyed. But destructors are more flexible in how they can used with derived
types. With standard Ada finalization, when you derive from a finalizable type,
you must either inherit the :ada:`Finalize` procedure or override it completely.

Destructors work differently. You can define a destructor for a type derived from
a parent type that also has a destructor, and then when objects of the derived type
are finalized, both destructors will be called. For example:

.. code-block:: ada

   type T1 is record
      ...
   end record;

   procedure T1'Destructor (X : in out T1);

   type T2 is new T1;

   procedure T2'Destructor (X : in out T2);

When an object of type :ada:`T2` is finalized, there will be first a call to
:ada:`T2'Destructor`, and then a call to :ada:`T1'Destructor` on the object.

Structural Generic Instantiation
--------------------------------

The compiler implements a second kind of generic instantiation, called
"structural", alongside the traditional instantiation specified by the
language, which is defined as follows: the structural instantiation of
a generic unit on given actual parameters is the anonymous instantiation
of the generic unit on the actual parameters done in the outermost scope
where it would be legal to do an identical traditional instantiation.

There is at most one structural instantiation of a generic unit on given
actual parameters done in a partition.

Structural generic instances (the product of structural instantiation)
are implicitly created whenever a reference to them is made in a place
where a name is accepted by the language.

Syntax
^^^^^^

.. code-block:: text

   name ::= { set of productions specified in the RM }
            | structural_generic_instance_name

   structural_generic_instance_name ::= name generic_actual_part

Legality Rules
^^^^^^^^^^^^^^

The ``name`` in a ``structural_generic_instance_name`` shall denote a generic
unit that is preelaborated. Note that, unlike in a traditional instantiation,
there are no square brackets around the ``generic_actual_part`` in the second
production, which means that it is mandatory and, therefore, that the generic
unit shall have at least one generic formal parameter.

The generic unit shall not take a generic formal object of mode ``in out``.
If the generic unit takes a generic formal object of mode ``in``, then the
corresponding generic actual parameter shall be a static expression.

A ``structural_generic_instance_name`` for a generic package shall not be
present in a library unit if the structural instance is also a library unit
and has a semantic dependence on the former.

For a generic subprogram, if a local entity of the enclosing library-level
package is used as an actual and the structural instance would have a semantic
dependence on the package, the structural instantiation is automatically
demoted to a local instantiation. In this case, several instances of the
generic subprogram may be present in a single partition, unless
whole-partition optimization is performed (e.g., via LTO).

Static Semantics
^^^^^^^^^^^^^^^^

A ``structural_generic_instance_name`` denotes the instance that is the
product of the structural instantiation of a generic unit on the specified
actual parameters. This instance is unique to a partition, except when a
generic subprogram instantiation is automatically demoted to a local
instantiation as described under Legality Rules.

Example:

.. code-block:: ada

   with Ada.Containers.Vectors;

   procedure P is
      V : Ada.Containers.Vectors(Positive,Integer).Vector;

   begin
      V.Append (1);
      V.Append (0);
      Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<").Sort (V);
   end;

This procedure references two structural instantiations of two different generic
units: ``Ada.Containers.Vectors(Positive,Integer)`` is the structural instance
of the generic unit ``Ada.Containers.Vectors`` on ``Positive`` and ``Integer``
and ``Ada.Containers.Vectors(Positive,Integer).Generic_Sorting("<")`` is the
structural instance of the nested generic unit
``Ada.Containers.Vectors(Positive,Integer).Generic_Sorting`` on ``"<"``.

Note that the following example is illegal:

.. code-block:: ada

   with Ada.Containers.Vectors;

   package Q is
      type T is record
         I : Integer;
      end record;

      V : Ada.Containers.Vectors(Positive,T).Vector;
   end Q;

The reason is that ``Ada.Containers.Vectors``, ``Positive`` and ``Q.T`` being
library-level entities, the structural instance ``Ada.Containers.Vectors(Positive,T)`` is a library unit with a dependence
on ``Q`` and, therefore, cannot be referenced from within ``Q``. This
restriction applies to structural instantiations of generic packages. The
simple way out is to declare a traditional instantiation in this case:

.. code-block:: ada

   with Ada.Containers.Vectors;

   package Q is
      type T is record
         I : Integer;
      end record;

      package Vectors_Of_T is new Ada.Containers.Vectors(Positive,T);

      V : Vectors_Of_T.Vector;
   end Q;

But the following example is legal:

.. code-block:: ada

   with Ada.Containers.Vectors;

   procedure P is
      type T is record
         I : Integer;
      end record;

      V : Ada.Containers.Vectors(Positive,T).Vector;
   end;

because the structural instance ``Ada.Containers.Vectors(Positive,T)`` is
not a library unit.

For generic subprograms, the restriction does not apply: if a local entity of
a library-level package is used as an actual, the structural instantiation is
automatically demoted to a local instantiation. For example:

.. code-block:: ada

   with Ada.Unchecked_Deallocation;

   package Q is
      type T is record
         I : Integer;
      end record;

      type T_Access is access T;
   end Q;

   package body Q is
      procedure Free_T (X : in out T_Access) is
      begin
         Ada.Unchecked_Deallocation(T, T_Access)(X);
      end Free_T;
   end Q;

is legal: since ``T`` and ``T_Access`` are local entities of ``Q``, the
structural instantiation of ``Ada.Unchecked_Deallocation`` is demoted to a
local instantiation rather than producing an error. Note that the uniqueness
guarantee no longer holds in this case and several instances of the generic
subprogram may be present in a single partition.

The first example can be rewritten in a less verbose manner:

.. code-block:: ada

   with Ada.Containers.Vectors; use Ada.Containers.Vectors(Positive,Integer);

   procedure P is
      V : Vector;

   begin
      V.Append (1);
      V.Append (0);
      Generic_Sorting("<").Sort (V);
   end;

Another example, which additionally uses the inference of dependent types:

.. code-block:: ada

   with Ada.Unchecked_Deallocation;

   procedure P is

      type Integer_Access is access all Integer;

      A : Integer_Access := new Integer'(1);

   begin
      Ada.Unchecked_Deallocation(Name => Integer_Access) (A);
   end;

Attribute Subprograms
---------------------

This feature allows declaring subprograms that are associated with a named
aspect or attribute of a given type, as an alternative to explicitly
specifying the aspect or attribute for the type (using an aspect_specification
or attribute_definition_clause), by defining the name of the subprogram
using attribute syntax. In effect, this implicitly specifies the aspect
or attribute for the type, and is intended to be semantically equivalent to
using an explicit aspect specification, but without needing to give a specific
name in the aspect and subprogram. This is allowed for the various aspects that
denote subprograms (see below for the exact list of supported aspects).

Here is an example of the use of this feature for defining indexing functions
for a container type and an integer-literal function for the container's
element type:

.. code-block:: ada

   package My_Container is

      type Container is tagged ...;  -- Implicit indexing aspects

      type Element_Type is ...;      -- Implicit Integer_Literal aspect

      type Cursor_Type is ...;

      type Reference_Type is ...;

      function Container'Constant_Indexing (C : Container; Index : Positive)
        return Element_Type;

      function Container'Constant_Indexing (C : Container; Index : Cursor_Type)
        return Element_Type;

      function Container'Variable_Indexing
        (C : in out Container; Index : Positive)
         return Reference_Type;

      function Element_Type'Integer_Literal (S : String) return Element_Type;

   end My_Container;

Syntax
^^^^^^

.. code-block:: text

   defining_program_unit_name ::=
     [parent_unit_name . ]defining_identifier
   | defining_attribute_subprogram_name

   defining_attribute_subprogram_name ::=
     prefix'attribute_designator

Legality Rules
^^^^^^^^^^^^^^

The prefix of a ``defining_attribute_subprogram_name`` shall be either
a ``direct_name`` denoting a type (more properly, a first subtype)
declared immediately within the scope where the associated subprogram
is declared, or else an attribute name itself whose ``attribute_designator``
is ``Class`` and whose prefix denotes a type subject to the same
declaration condition. A ``defining_program_unit_name`` that is
a ``defining_attribute_subprogram_name`` may only be used to define
the name of a subprogram that is neither a library subprogram nor
a subprogram whose body is given by a ``body_stub`` (nor can it be
used to define the name of a generic subprogram).

The ``attribute_designator`` given in a ``defining_attribute_subprogram_name``
shall name an aspect that is allowed to designate a subprogram. Specifically,
it shall be one of the predefined aspects ``Constant_Indexing``,
``Variable_Indexing``, ``Default_Iterator``, ``Integer_Literal``,
``Real_Literal``, ``String_Literal``, ``Put_Image``, ``Read``, ``Write``,
``Input``, or ``Output``, or else one of the implementation-defined aspects
``Constructor`` or ``Destructor``. (Note that this feature is not supported
for aspects that have elements that may designate a subprogram, such as the
``Aggregate`` aspect.)

If the prefix of a ``defining_attribute_subprogram_name`` is an attribute name
whose ``attribute_designator`` is ``Class``, then the ``attribute_designator``
of the ``defining_attribute_subprogram_name`` shall be the name of a stream
attribute.

An attribute subprogram for a given type and aspect is subject to
the same restrictions as would be imposed on a subprogram denoted by
an explicit ``aspect_specification`` or ``attribute_definition_clause``
for that type and aspect. In particular, the profile of the subprogram
must satisfy any expected profile defined for the aspect.

If a subprogram is declared using a ``defining_attribute_subprogram_name``,
then the type named in the attribute subprogram's name shall not have
an explicit ``aspect_specification`` that specifies the same aspect as
that named by the subprogram, nor shall the type derive from an ancestor
type that explicitly specifies that aspect. Similarly, an explicit
``aspect_specification`` shall not specify an aspect for a type that
is derived from a type for which any attribute subprograms have been
declared for the same aspect.

---

### Gcc Ada Doc Gnat Rm Implementation Advice (`gcc/ada/doc/gnat_rm/implementation_advice.rst`)

.. _Implementation_Advice:

*********************
Implementation Advice
*********************

The main text of the Ada Reference Manual describes the required
behavior of all Ada compilers, and the GNAT compiler conforms to
these requirements.

In addition, there are sections throughout the Ada Reference Manual headed
by the phrase 'Implementation advice'.  These sections are not normative,
i.e., they do not specify requirements that all compilers must
follow.  Rather they provide advice on generally desirable behavior.
They are not requirements, because they describe behavior that cannot
be provided on all systems, or may be undesirable on some systems.

As far as practical, GNAT follows the implementation advice in
the Ada Reference Manual.  Each such RM section corresponds to a section
in this chapter whose title specifies the
RM section number and paragraph number and the subject of
the advice.  The contents of each section consists of the RM text within
quotation marks,
followed by the GNAT interpretation of the advice.  Most often, this simply says
'followed', which means that GNAT follows the advice.  However, in a
number of cases, GNAT deliberately deviates from this advice, in which
case the text describes what GNAT does and why.

.. index:: Error detection

RM 1.1.3(20): Error Detection
=============================

  "If an implementation detects the use of an unsupported Specialized Needs
  Annex feature at run time, it should raise ``Program_Error`` if
  feasible."

Not relevant.  All specialized needs annex features are either supported,
or diagnosed at compile time.

.. index:: Child Units

RM 1.1.3(31): Child Units
=========================


  "If an implementation wishes to provide implementation-defined
  extensions to the functionality of a language-defined library unit, it
  should normally do so by adding children to the library unit."

Followed.

.. index:: Bounded errors

RM 1.1.5(12): Bounded Errors
============================

  "If an implementation detects a bounded error or erroneous
  execution, it should raise ``Program_Error``."

Followed in all cases in which the implementation detects a bounded
error or erroneous execution.  Not all such situations are detected at
runtime.

.. index:: Pragmas

.. _RM_2_8_16_Pragmas:

RM 2.8(16): Pragmas
===================

  "Normally, implementation-defined pragmas should have no semantic effect
  for error-free programs; that is, if the implementation-defined pragmas
  are removed from a working program, the program should still be legal,
  and should still have the same semantics."

The following implementation defined pragmas are exceptions to this
rule:

+--------------------+-------------------+
| Pragma             | Explanation       |
+====================+===================+
| *Abort_Defer*      | Affects semantics |
+--------------------+-------------------+
|*Ada_83*            | Affects legality  |
+--------------------+-------------------+
|*Assert*            | Affects semantics |
+--------------------+-------------------+
|*CPP_Class*         | Affects semantics |
+--------------------+-------------------+
|*CPP_Constructor*   | Affects semantics |
+--------------------+-------------------+
|*Debug*             | Affects semantics |
+--------------------+-------------------+
|*Interface_Name*    | Affects semantics |
+--------------------+-------------------+
|*Machine_Attribute* | Affects semantics |
+--------------------+-------------------+
|*Unimplemented_Unit*| Affects legality  |
+--------------------+-------------------+
|*Unchecked_Union*   | Affects semantics |
+--------------------+-------------------+

In each of the above cases, it is essential to the purpose of the pragma
that this advice not be followed.  For details see
:ref:`Implementation_Defined_Pragmas`.

RM 2.8(17-19): Pragmas
======================

  "Normally, an implementation should not define pragmas that can
  make an illegal program legal, except as follows:

  * A pragma used to complete a declaration, such as a pragma ``Import``;

  * A pragma used to configure the environment by adding, removing, or
    replacing ``library_items``."

See :ref:`RM_2_8_16_Pragmas`.

.. index:: Character Sets

.. index:: Alternative Character Sets

RM 3.5.2(5): Alternative Character Sets
=======================================

  "If an implementation supports a mode with alternative interpretations
  for ``Character`` and ``Wide_Character``, the set of graphic
  characters of ``Character`` should nevertheless remain a proper
  subset of the set of graphic characters of ``Wide_Character``.  Any
  character set 'localizations' should be reflected in the results of
  the subprograms defined in the language-defined package
  ``Characters.Handling`` (see A.3) available in such a mode.  In a mode with
  an alternative interpretation of ``Character``, the implementation should
  also support a corresponding change in what is a legal
  ``identifier_letter``."

Not all wide character modes follow this advice, in particular the JIS
and IEC modes reflect standard usage in Japan, and in these encoding,
the upper half of the Latin-1 set is not part of the wide-character
subset, since the most significant bit is used for wide character
encoding.  However, this only applies to the external forms.  Internally
there is no such restriction.

.. index:: Integer types

RM 3.5.4(28): Integer Types
===========================

  "An implementation should support ``Long_Integer`` in addition to
  ``Integer`` if the target machine supports 32-bit (or longer)
  arithmetic.  No other named integer subtypes are recommended for package
  ``Standard``.  Instead, appropriate named integer subtypes should be
  provided in the library package ``Interfaces`` (see B.2)."

``Long_Integer`` is supported.  Other standard integer types are supported
so this advice is not fully followed.  These types
are supported for convenient interface to C, and so that all hardware
types of the machine are easily available.

RM 3.5.4(29): Integer Types
===========================

  "An implementation for a two's complement machine should support
  modular types with a binary modulus up to ``System.Max_Int*2+2``.  An
  implementation should support a non-binary modules up to ``Integer'Last``."

Followed.

.. index:: Enumeration values

RM 3.5.5(8): Enumeration Values
===============================

  "For the evaluation of a call on ``S'Pos`` for an enumeration
  subtype, if the value of the operand does not correspond to the internal
  code for any enumeration literal of its type (perhaps due to an
  un-initialized variable), then the implementation should raise
  ``Program_Error``.  This is particularly important for enumeration
  types with noncontiguous internal codes specified by an
  enumeration_representation_clause."

Followed.

.. index:: Float types

RM 3.5.7(17): Float Types
=========================

  "An implementation should support ``Long_Float`` in addition to
  ``Float`` if the target machine supports 11 or more digits of
  precision.  No other named floating point subtypes are recommended for
  package ``Standard``.  Instead, appropriate named floating point subtypes
  should be provided in the library package ``Interfaces`` (see B.2)."

``Short_Float`` and ``Long_Long_Float`` are also provided.  The
former provides improved compatibility with other implementations
supporting this type.  The latter corresponds to the highest precision
floating-point type supported by the hardware.  On most machines, this
will be the same as ``Long_Float``, but on some machines, it will
correspond to the IEEE extended form.  The notable case is all x86
implementations, where ``Long_Long_Float`` corresponds to the 80-bit
extended precision format supported in hardware on this processor.
Note that the 128-bit format on SPARC is not supported, since this
is a software rather than a hardware format.

.. index:: Multidimensional arrays

.. index:: Arrays, multidimensional

RM 3.6.2(11): Multidimensional Arrays
=====================================

  "An implementation should normally represent multidimensional arrays in
  row-major order, consistent with the notation used for multidimensional
  array aggregates (see 4.3.3).  However, if a pragma ``Convention``
  (``Fortran``, ...) applies to a multidimensional array type, then
  column-major order should be used instead (see B.5, *Interfacing with Fortran*)."

Followed.

.. index:: Duration'Small

RM 9.6(30-31): Duration'Small
=============================

  "Whenever possible in an implementation, the value of ``Duration'Small``
  should be no greater than 100 microseconds."

Followed.  (``Duration'Small`` = 10**(-9)).

  "The time base for ``delay_relative_statements`` should be monotonic;
  it need not be the same time base as used for ``Calendar.Clock``."

Followed.

RM 10.2.1(12): Consistent Representation
========================================

  "In an implementation, a type declared in a pre-elaborated package should
  have the same representation in every elaboration of a given version of
  the package, whether the elaborations occur in distinct executions of
  the same program, or in executions of distinct programs or partitions
  that include the given version."

Followed, except in the case of tagged types.  Tagged types involve
implicit pointers to a local copy of a dispatch table, and these pointers
have representations which thus depend on a particular elaboration of the
package.  It is not easy to see how it would be possible to follow this
advice without severely impacting efficiency of execution.

.. index:: Exception information

RM 11.4.1(19): Exception Information
====================================

  "``Exception_Message`` by default and ``Exception_Information``
  should produce information useful for
  debugging.  ``Exception_Message`` should be short, about one
  line.  ``Exception_Information`` can be long.  ``Exception_Message``
  should not include the
  ``Exception_Name``.  ``Exception_Information`` should include both
  the ``Exception_Name`` and the ``Exception_Message``."

Followed.  For each exception that doesn't have a specified
``Exception_Message``, the compiler generates one containing the location
of the raise statement.  This location has the form 'file_name:line', where
file_name is the short file name (without path information) and line is the line
number in the file.  Note that in the case of the Zero Cost Exception
mechanism, these messages become redundant with the Exception_Information that
contains a full backtrace of the calling sequence, so they are disabled.
To disable explicitly the generation of the source location message, use the
Pragma ``Discard_Names``.

.. index:: Suppression of checks

.. index:: Checks, suppression of

RM 11.5(28): Suppression of Checks
==================================

  "The implementation should minimize the code executed for checks that
  have been suppressed."

Followed.

.. index:: Representation clauses

RM 13.1 (21-24): Representation Clauses
=======================================

  "The recommended level of support for all representation items is
  qualified as follows:

  An implementation need not support representation items containing
  nonstatic expressions, except that an implementation should support a
  representation item for a given entity if each nonstatic expression in
  the representation item is a name that statically denotes a constant
  declared before the entity."

Followed.  In fact, GNAT goes beyond the recommended level of support
by allowing nonstatic expressions in some representation clauses even
without the need to declare constants initialized with the values of
such expressions. For example:

.. code-block:: ada

    X : Integer;
    Y : Float;
    for Y'Address use X'Address;

is accepted directly by GNAT.


  "An implementation need not support a specification for the ``Size``
  for a given composite subtype, nor the size or storage place for an
  object (including a component) of a given composite subtype, unless the
  constraints on the subtype and its composite subcomponents (if any) are
  all static constraints."

Followed.  Size Clauses are not permitted on nonstatic components, as
described above.


  "An aliased component, or a component whose type is by-reference, should
  always be allocated at an addressable location."

Followed.

.. index:: Packed types

RM 13.2(6-8): Packed Types
==========================

  "If a type is packed, then the implementation should try to minimize
  storage allocated to objects of the type, possibly at the expense of
  speed of accessing components, subject to reasonable complexity in
  addressing calculations.

  The recommended level of support pragma ``Pack`` is:

  For a packed record type, the components should be packed as tightly as
  possible subject to the Sizes of the component subtypes, and subject to
  any *record_representation_clause* that applies to the type; the
  implementation may, but need not, reorder components or cross aligned
  word boundaries to improve the packing.  A component whose ``Size`` is
  greater than the word size may be allocated an integral number of words."

Followed.  Tight packing of arrays is supported for all component sizes
up to 64-bits. If the array component size is 1 (that is to say, if
the component is a boolean type or an enumeration type with two values)
then values of the type are implicitly initialized to zero. This
happens both for objects of the packed type, and for objects that have a
subcomponent of the packed type.

.. index:: Address clauses

RM 13.3(14-19): Address Clauses
===============================

  "For an array ``X``, ``X'Address`` should point at the first
  component of the array, and not at the array bounds."

Followed.

  "The recommended level of support for the ``Address`` attribute is:

  ``X'Address`` should produce a useful result if ``X`` is an
  object that is aliased or of a by-reference type, or is an entity whose
  ``Address`` has been specified."

Followed.  A valid address will be produced even if none of those
conditions have been met.  If necessary, the object is forced into
memory to ensure the address is valid.

  "An implementation should support ``Address`` clauses for imported
  subprograms."

Followed.

  "Objects (including subcomponents) that are aliased or of a by-reference
  type should be allocated on storage element boundaries."

Followed.

  "If the ``Address`` of an object is specified, or it is imported or exported,
  then the implementation should not perform optimizations based on
  assumptions of no aliases."

Followed.

.. index:: Alignment clauses

RM 13.3(29-35): Alignment Clauses
=================================

  "The recommended level of support for the ``Alignment`` attribute for
  subtypes is:

  An implementation should support specified Alignments that are factors
  and multiples of the number of storage elements per word, subject to the
  following:"

Followed.

  "An implementation need not support specified Alignments for
  combinations of Sizes and Alignments that cannot be easily
  loaded and stored by available machine instructions."

Followed.

  "An implementation need not support specified Alignments that are
  greater than the maximum ``Alignment`` the implementation ever returns by
  default."

Followed.

  "The recommended level of support for the ``Alignment`` attribute for
  objects is:

  Same as above, for subtypes, but in addition:"

Followed.

  "For stand-alone library-level objects of statically constrained
  subtypes, the implementation should support all alignments
  supported by the target linker.  For example, page alignment is likely to
  be supported for such objects, but not for subtypes."

Followed.

.. index:: Size clauses

RM 13.3(42-43): Size Clauses
============================

  "The recommended level of support for the ``Size`` attribute of
  objects is:

  A ``Size`` clause should be supported for an object if the specified
  ``Size`` is at least as large as its subtype's ``Size``, and
  corresponds to a size in storage elements that is a multiple of the
  object's ``Alignment`` (if the ``Alignment`` is nonzero)."

Followed.

RM 13.3(50-56): Size Clauses
============================

  "If the ``Size`` of a subtype is specified, and allows for efficient
  independent addressability (see 9.10) on the target architecture, then
  the ``Size`` of the following objects of the subtype should equal the
  ``Size`` of the subtype:

  Aliased objects (including components)."

Followed.

  "`Size` clause on a composite subtype should not affect the
  internal layout of components."

Followed. But note that this can be overridden by use of the implementation
pragma Implicit_Packing in the case of packed arrays.

  "The recommended level of support for the ``Size`` attribute of subtypes is:

  The ``Size`` (if not specified) of a static discrete or fixed point
  subtype should be the number of bits needed to represent each value
  belonging to the subtype using an unbiased representation, leaving space
  for a sign bit only if the subtype contains negative values.  If such a
  subtype is a first subtype, then an implementation should support a
  specified ``Size`` for it that reflects this representation."

Followed.

  "For a subtype implemented with levels of indirection, the ``Size``
  should include the size of the pointers, but not the size of what they
  point at."

Followed.

.. index:: Component_Size clauses

RM 13.3(71-73): Component Size Clauses
======================================

  "The recommended level of support for the ``Component_Size``
  attribute is:

  An implementation need not support specified ``Component_Sizes`` that are
  less than the ``Size`` of the component subtype."

Followed.

  "An implementation should support specified Component_Sizes that
  are factors and multiples of the word size.  For such
  Component_Sizes, the array should contain no gaps between
  components.  For other Component_Sizes (if supported), the array
  should contain no gaps between components when packing is also
  specified; the implementation should forbid this combination in cases
  where it cannot support a no-gaps representation."

Followed.

.. index:: Enumeration representation clauses

.. index:: Representation clauses, enumeration

RM 13.4(9-10): Enumeration Representation Clauses
=================================================

  "The recommended level of support for enumeration representation clauses
  is:

  An implementation need not support enumeration representation clauses
  for boolean types, but should at minimum support the internal codes in
  the range ``System.Min_Int .. System.Max_Int``."

Followed.

.. index:: Record representation clauses

.. index:: Representation clauses, records

RM 13.5.1(17-22): Record Representation Clauses
===============================================

  "The recommended level of support for
  *record_representation_clause*\ s is:

  An implementation should support storage places that can be extracted
  with a load, mask, shift sequence of machine code, and set with a load,
  shift, mask, store sequence, given the available machine instructions
  and run-time model."

Followed.

  "A storage place should be supported if its size is equal to the
  ``Size`` of the component subtype, and it starts and ends on a
  boundary that obeys the ``Alignment`` of the component subtype."

Followed.

  "If the default bit ordering applies to the declaration of a given type,
  then for a component whose subtype's ``Size`` is less than the word
  size, any storage place that does not cross an aligned word boundary
  should be supported."

Followed.

  "An implementation may reserve a storage place for the tag field of a
  tagged type, and disallow other components from overlapping that place."

Followed.  The storage place for the tag field is the beginning of the tagged
record, and its size is Address'Size.  GNAT will reject an explicit component
clause for the tag field.

  "An implementation need not support a *component_clause* for a
  component of an extension part if the storage place is not after the
  storage places of all components of the parent type, whether or not
  those storage places had been specified."

Followed.  The above advice on record representation clauses is followed,
and all mentioned features are implemented.

.. index:: Storage place attributes

RM 13.5.2(5): Storage Place Attributes
======================================

  "If a component is represented using some form of pointer (such as an
  offset) to the actual data of the component, and this data is contiguous
  with the rest of the object, then the storage place attributes should
  reflect the place of the actual data, not the pointer.  If a component is
  allocated discontinuously from the rest of the object, then a warning
  should be generated upon reference to one of its storage place
  attributes."

Followed.  There are no such components in GNAT.

.. index:: Bit ordering

RM 13.5.3(7-8): Bit Ordering
============================

  "The recommended level of support for the non-default bit ordering is:

  The implementation should support the nondefault bit ordering in addition
  to the default bit ordering."

Followed.

.. index:: Address, as private type

RM 13.7(37): Address as Private
===============================

  "`Address` should be of a private type."

Followed.

.. index:: Operations, on ``Address``

.. index:: Address, operations of

RM 13.7.1(16): Address Operations
=================================

  "Operations in ``System`` and its children should reflect the target
  environment semantics as closely as is reasonable.  For example, on most
  machines, it makes sense for address arithmetic to 'wrap around'.
  Operations that do not make sense should raise ``Program_Error``."

Followed.  Address arithmetic is modular arithmetic that wraps around.  No
operation raises ``Program_Error``, since all operations make sense.

.. index:: Unchecked conversion

RM 13.9(14-17): Unchecked Conversion
====================================

  "The ``Size`` of an array object should not include its bounds; hence,
  the bounds should not be part of the converted data."

Followed.

  "The implementation should not generate unnecessary run-time checks to
  ensure that the representation of ``S`` is a representation of the
  target type.  It should take advantage of the permission to return by
  reference when possible.  Restrictions on unchecked conversions should be
  avoided unless required by the target environment."

Followed.  There are no restrictions on unchecked conversion.  A warning is
generated if the source and target types do not have the same size since
the semantics in this case may be target dependent.

  "The recommended level of support for unchecked conversions is:

  Unchecked conversions should be supported and should be reversible in
  the cases where this clause defines the result.  To enable meaningful use
  of unchecked conversion, a contiguous representation should be used for
  elementary subtypes, for statically constrained array subtypes whose
  component subtype is one of the subtypes described in this paragraph,
  and for record subtypes without discriminants whose component subtypes
  are described in this paragraph."

Followed.

.. index:: Heap usage, implicit

RM 13.11(23-25): Implicit Heap Usage
====================================

  "An implementation should document any cases in which it dynamically
  allocates heap storage for a purpose other than the evaluation of an
  allocator."

Followed, the only other points at which heap storage is dynamically
allocated are as follows:

*
  At initial elaboration time, to allocate dynamically sized global
  objects.

*
  To allocate space for a task when a task is created.

*
  To extend the secondary stack dynamically when needed.  The secondary
  stack is used for returning variable length results.

..

  "A default (implementation-provided) storage pool for an
  access-to-constant type should not have overhead to support deallocation of
  individual objects."

Followed.

  "A storage pool for an anonymous access type should be created at the
  point of an allocator for the type, and be reclaimed when the designated
  object becomes inaccessible."

Followed.

.. index:: Unchecked deallocation

RM 13.11.2(17): Unchecked Deallocation
======================================

  "For a standard storage pool, ``Free`` should actually reclaim the
  storage."

Followed.

.. index:: Stream oriented attributes

RM 13.13.2(1.6): Stream Oriented Attributes
===========================================

  "If not specified, the value of Stream_Size for an elementary type
  should be the number of bits that corresponds to the minimum number of
  stream elements required by the first subtype of the type, rounded up
  to the nearest factor or multiple of the word size that is also a
  multiple of the stream element size."

Followed, except that the number of stream elements is 1, 2, 3, 4 or 8.
The Stream_Size may be used to override the default choice.

The default implementation is based on direct binary representations and is
therefore target- and endianness-dependent.  To address this issue, GNAT also
supplies an alternate implementation of the stream attributes ``Read`` and
``Write``, which uses the target-independent XDR standard representation for
scalar types. This XDR alternative can be enabled via the binder switch -xdr.

.. index:: XDR representation
.. index:: Read attribute
.. index:: Write attribute
.. index:: Stream oriented attributes

RM A.1(52): Names of Predefined Numeric Types
=============================================

  "If an implementation provides additional named predefined integer types,
  then the names should end with ``Integer`` as in
  ``Long_Integer``.  If an implementation provides additional named
  predefined floating point types, then the names should end with
  ``Float`` as in ``Long_Float``."

Followed.

.. index:: Ada.Characters.Handling

RM A.3.2(49): ``Ada.Characters.Handling``
=========================================

  "If an implementation provides a localized definition of ``Character``
  or ``Wide_Character``, then the effects of the subprograms in
  ``Characters.Handling`` should reflect the localizations.
  See also 3.5.2."

Followed.  GNAT provides no such localized definitions.

.. index:: Bounded-length strings

RM A.4.4(106): Bounded-Length String Handling
=============================================

  "Bounded string objects should not be implemented by implicit pointers
  and dynamic allocation."

Followed.  No implicit pointers or dynamic allocation are used.

.. index:: Random number generation

RM A.5.2(46-47): Random Number Generation
=========================================

  "Any storage associated with an object of type ``Generator`` should be
  reclaimed on exit from the scope of the object."

Followed.

  "If the generator period is sufficiently long in relation to the number
  of distinct initiator values, then each possible value of
  ``Initiator`` passed to ``Reset`` should initiate a sequence of
  random numbers that does not, in a practical sense, overlap the sequence
  initiated by any other value.  If this is not possible, then the mapping
  between initiator values and generator states should be a rapidly
  varying function of the initiator value."

Followed.  The generator period is sufficiently long for the first
condition here to hold true.

.. index:: Get_Immediate

RM A.10.7(23): ``Get_Immediate``
================================

  "The ``Get_Immediate`` procedures should be implemented with
  unbuffered input.  For a device such as a keyboard, input should be
  available if a key has already been typed, whereas for a disk
  file, input should always be available except at end of file.  For a file
  associated with a keyboard-like device, any line-editing features of the
  underlying operating system should be disabled during the execution of
  ``Get_Immediate``."

Followed on all targets except VxWorks. For VxWorks, there is no way to
provide this functionality that does not result in the input buffer being
flushed before the ``Get_Immediate`` call. A special unit
``Interfaces.Vxworks.IO`` is provided that contains routines to enable
this functionality.

.. index:: Containers

RM A.18: ``Containers``
================================

All implementation advice pertaining to Ada.Containers and its
child units (that is, all implementation advice occurring within
section A.18 and its subsections) is followed except for A.18.24(17):

   "Bounded ordered set objects should be implemented without implicit pointers or dynamic allocation. "

The implementations of the two Reference_Preserving_Key functions of
the generic package Ada.Containers.Bounded_Ordered_Sets each currently make
use of dynamic allocation; other operations on bounded ordered set objects
follow the implementation advice.

.. index:: Export

RM B.1(39-41): Pragma ``Export``
================================

  "If an implementation supports pragma ``Export`` to a given language,
  then it should also allow the main subprogram to be written in that
  language.  It should support some mechanism for invoking the elaboration
  of the Ada library units included in the system, and for invoking the
  finalization of the environment task.  On typical systems, the
  recommended mechanism is to provide two subprograms whose link names are
  ``adainit`` and ``adafinal``.  ``adainit`` should contain the
  elaboration code for library units.  ``adafinal`` should contain the
  finalization code.  These subprograms should have no effect the second
  and subsequent time they are called."

Followed.

  "Automatic elaboration of pre-elaborated packages should be
  provided when pragma ``Export`` is supported."

Followed when the main program is in Ada.  If the main program is in a
foreign language, then
``adainit`` must be called to elaborate pre-elaborated
packages.

  "For each supported convention *L* other than ``Intrinsic``, an
  implementation should support ``Import`` and ``Export`` pragmas
  for objects of *L*\ -compatible types and for subprograms, and pragma
  `Convention` for *L*\ -eligible types and for subprograms,
  presuming the other language has corresponding features.  Pragma
  ``Convention`` need not be supported for scalar types."

Followed.

.. index:: Package Interfaces

.. index:: Interfaces

RM B.2(12-13): Package ``Interfaces``
=====================================

  "For each implementation-defined convention identifier, there should be a
  child package of package Interfaces with the corresponding name.  This
  package should contain any declarations that would be useful for
  interfacing to the language (implementation) represented by the
  convention.  Any declarations useful for interfacing to any language on
  the given hardware architecture should be provided directly in
  ``Interfaces``."

Followed.

  "An implementation supporting an interface to C, COBOL, or Fortran should
  provide the corresponding package or packages described in the following
  clauses."

Followed.  GNAT provides all the packages described in this section.

.. index:: C, interfacing with

RM B.3(63-71): Interfacing with C
=================================

  "An implementation should support the following interface correspondences
  between Ada and C."

Followed.

  "An Ada procedure corresponds to a void-returning C function."

Followed.

  "An Ada function corresponds to a non-void C function."

Followed.

  "An Ada ``in`` scalar parameter is passed as a scalar argument to a C
  function."

Followed.

  "An Ada ``in`` parameter of an access-to-object type with designated
  type ``T`` is passed as a ``t*`` argument to a C function,
  where ``t`` is the C type corresponding to the Ada type ``T``."

Followed.

  "An Ada access ``T`` parameter, or an Ada ``out`` or ``in out``
  parameter of an elementary type ``T``, is passed as a ``t*``
  argument to a C function, where ``t`` is the C type corresponding to
  the Ada type ``T``.  In the case of an elementary ``out`` or
  ``in out`` parameter, a pointer to a temporary copy is used to
  preserve by-copy semantics."

Followed.

  "An Ada parameter of a record type ``T``, of any mode, is passed as a
  ``t*`` argument to a C function, where ``t`` is the C
  structure corresponding to the Ada type ``T``."

Followed.  This convention may be overridden by the use of the C_Pass_By_Copy
pragma, or Convention, or by explicitly specifying the mechanism for a given
call using an extended import or export pragma.

  "An Ada parameter of an array type with component type ``T``, of any
  mode, is passed as a ``t*`` argument to a C function, where
  ``t`` is the C type corresponding to the Ada type ``T``."

Followed.

  "An Ada parameter of an access-to-subprogram type is passed as a pointer
  to a C function whose prototype corresponds to the designated
  subprogram's specification."

Followed.

.. index:: COBOL, interfacing with

RM B.4(95-98): Interfacing with COBOL
=====================================

  "An Ada implementation should support the following interface
  correspondences between Ada and COBOL."

Followed.

  "An Ada access ``T`` parameter is passed as a ``BY REFERENCE`` data item of
  the COBOL type corresponding to ``T``."

Followed.

  "An Ada in scalar parameter is passed as a ``BY CONTENT`` data item of
  the corresponding COBOL type."

Followed.

  "Any other Ada parameter is passed as a ``BY REFERENCE`` data item of the
  COBOL type corresponding to the Ada parameter type; for scalars, a local
  copy is used if necessary to ensure by-copy semantics."

Followed.

.. index:: Fortran, interfacing with

RM B.5(22-26): Interfacing with Fortran
=======================================

  "An Ada implementation should support the following interface
  correspondences between Ada and Fortran:"

Followed.

  "An Ada procedure corresponds to a Fortran subroutine."

Followed.

  "An Ada function corresponds to a Fortran function."

Followed.

  "An Ada parameter of an elementary, array, or record type ``T`` is
  passed as a ``T`` argument to a Fortran procedure, where ``T`` is
  the Fortran type corresponding to the Ada type ``T``, and where the
  INTENT attribute of the corresponding dummy argument matches the Ada
  formal parameter mode; the Fortran implementation's parameter passing
  conventions are used.  For elementary types, a local copy is used if
  necessary to ensure by-copy semantics."

Followed.

  "An Ada parameter of an access-to-subprogram type is passed as a
  reference to a Fortran procedure whose interface corresponds to the
  designated subprogram's specification."

Followed.

.. index:: Machine operations

RM C.1(3-5): Access to Machine Operations
=========================================

  "The machine code or intrinsic support should allow access to all
  operations normally available to assembly language programmers for the
  target environment, including privileged instructions, if any."

Followed.

  "The interfacing pragmas (see Annex B) should support interface to
  assembler; the default assembler should be associated with the
  convention identifier ``Assembler``."

Followed.

  "If an entity is exported to assembly language, then the implementation
  should allocate it at an addressable location, and should ensure that it
  is retained by the linking process, even if not otherwise referenced
  from the Ada code.  The implementation should assume that any call to a
  machine code or assembler subprogram is allowed to read or update every
  object that is specified as exported."

Followed.

RM C.1(10-16): Access to Machine Operations
===========================================

  "The implementation should ensure that little or no overhead is
  associated with calling intrinsic and machine-code subprograms."

Followed for both intrinsics and machine-code subprograms.

  "It is recommended that intrinsic subprograms be provided for convenient
  access to any machine operations that provide special capabilities or
  efficiency and that are not otherwise available through the language
  constructs."

Followed.  A full set of machine operation intrinsic subprograms is provided.

  "Atomic read-modify-write operations---e.g., test and set, compare and
  swap, decrement and test, enqueue/dequeue."

Followed on any target supporting such operations.

  "Standard numeric functions---e.g.:, sin, log."

Followed on any target supporting such operations.

  "String manipulation operations---e.g.:, translate and test."

Followed on any target supporting such operations.

  "Vector operations---e.g.:, compare vector against thresholds."

Followed on any target supporting such operations.

  "Direct operations on I/O ports."

Followed on any target supporting such operations.

.. index:: Interrupt support

RM C.3(28): Interrupt Support
=============================

  "If the ``Ceiling_Locking`` policy is not in effect, the
  implementation should provide means for the application to specify which
  interrupts are to be blocked during protected actions, if the underlying
  system allows for a finer-grain control of interrupt blocking."

Followed.  The underlying system does not allow for finer-grain control
of interrupt blocking.

.. index:: Protected procedure handlers

RM C.3.1(20-21): Protected Procedure Handlers
=============================================

  "Whenever possible, the implementation should allow interrupt handlers to
  be called directly by the hardware."

Followed on any target where the underlying operating system permits
such direct calls.

  "Whenever practical, violations of any
  implementation-defined restrictions should be detected before run time."

Followed.  Compile time warnings are given when possible.

.. index:: Package ``Interrupts``

.. index:: Interrupts

RM C.3.2(25): Package ``Interrupts``
====================================

  "If implementation-defined forms of interrupt handler procedures are
  supported, such as protected procedures with parameters, then for each
  such form of a handler, a type analogous to ``Parameterless_Handler``
  should be specified in a child package of ``Interrupts``, with the
  same operations as in the predefined package Interrupts."

Followed.

.. index:: Pre-elaboration requirements

RM C.4(14): Pre-elaboration Requirements
========================================

  "It is recommended that pre-elaborated packages be implemented in such a
  way that there should be little or no code executed at run time for the
  elaboration of entities not already covered by the Implementation
  Requirements."

Followed.  Executable code is generated in some cases, e.g., loops
to initialize large arrays.

RM C.5(8): Pragma ``Discard_Names``
===================================

  "If the pragma applies to an entity, then the implementation should
  reduce the amount of storage used for storing names associated with that
  entity."

Followed.

.. index:: Package Task_Attributes

.. index:: Task_Attributes

RM C.7.2(30): The Package Task_Attributes
=========================================

  "Some implementations are targeted to domains in which memory use at run
  time must be completely deterministic.  For such implementations, it is
  recommended that the storage for task attributes will be pre-allocated
  statically and not from the heap.  This can be accomplished by either
  placing restrictions on the number and the size of the task's
  attributes, or by using the pre-allocated storage for the first ``N``
  attribute objects, and the heap for the others.  In the latter case,
  ``N`` should be documented."

Not followed.  This implementation is not targeted to such a domain.

.. index:: Locking Policies

RM D.3(17): Locking Policies
============================

  "The implementation should use names that end with ``_Locking`` for
  locking policies defined by the implementation."

Followed.  Two implementation-defined locking policies are defined,
whose names (``Inheritance_Locking`` and
``Concurrent_Readers_Locking``) follow this suggestion.

.. index:: Entry queuing policies

RM D.4(16): Entry Queuing Policies
==================================

  "Names that end with ``_Queuing`` should be used
  for all implementation-defined queuing policies."

Followed.  No such implementation-defined queuing policies exist.

.. index:: Preemptive abort

RM D.6(9-10): Preemptive Abort
==============================

  "Even though the *abort_statement* is included in the list of
  potentially blocking operations (see 9.5.1), it is recommended that this
  statement be implemented in a way that never requires the task executing
  the *abort_statement* to block."

Followed.

  "On a multi-processor, the delay associated with aborting a task on
  another processor should be bounded; the implementation should use
  periodic polling, if necessary, to achieve this."

Followed.

.. index:: Tasking restrictions

RM D.7(21): Tasking Restrictions
================================

  "When feasible, the implementation should take advantage of the specified
  restrictions to produce a more efficient implementation."

GNAT currently takes advantage of these restrictions by providing an optimized
run time when the Ravenscar profile and the GNAT restricted run time set
of restrictions are specified.  See pragma ``Profile (Ravenscar)`` and
pragma ``Profile (Restricted)`` for more details.

.. index:: Time, monotonic

RM D.8(47-49): Monotonic Time
=============================

  "When appropriate, implementations should provide configuration
  mechanisms to change the value of ``Tick``."

Such configuration mechanisms are not appropriate to this implementation
and are thus not supported.

  "It is recommended that ``Calendar.Clock`` and ``Real_Time.Clock``
  be implemented as transformations of the same time base."

Followed.


  "It is recommended that the best time base which exists in
  the underlying system be available to the application through
  ``Clock``.  `Best` may mean highest accuracy or largest range."

Followed.

.. index:: Partition communication subsystem

.. index:: PCS

RM E.5(28-29): Partition Communication Subsystem
================================================

  "Whenever possible, the PCS on the called partition should allow for
  multiple tasks to call the RPC-receiver with different messages and
  should allow them to block until the corresponding subprogram body
  returns."

A separately supplied PCS that can be used with GNAT when combined with the PolyORB product (NB! See the note in :ref:`polyORB` regarding the lifetime
of this product).

  "The ``Write`` operation on a stream of type ``Params_Stream_Type``
  should raise ``Storage_Error`` if it runs out of space trying to
  write the ``Item`` into the stream."

.. index:: COBOL support

RM F(7): COBOL Support
======================

  "If COBOL (respectively, C) is widely supported in the target
  environment, implementations supporting the Information Systems Annex
  should provide the child package ``Interfaces.COBOL`` (respectively,
  ``Interfaces.C``) specified in Annex B and should support a
  ``convention_identifier`` of COBOL (respectively, C) in the interfacing
  pragmas (see Annex B), thus allowing Ada programs to interface with
  programs written in that language."

Followed.

.. index:: Decimal radix support

RM F.1(2): Decimal Radix Support
================================

  "Packed decimal should be used as the internal representation for objects
  of subtype ``S`` when ``S``'Machine_Radix = 10."

Not followed.  GNAT ignores ``S``'Machine_Radix and always uses binary
representations.

.. index:: Numerics

RM G: Numerics
==============

  "If Fortran (respectively, C) is widely supported in the target
  environment, implementations supporting the Numerics Annex
  should provide the child package ``Interfaces.Fortran`` (respectively,
  ``Interfaces.C``) specified in Annex B and should support a
  ``convention_identifier`` of Fortran (respectively, C) in the interfacing
  pragmas (see Annex B), thus allowing Ada programs to interface with
  programs written in that language."

Followed.

.. index:: Complex types

RM G.1.1(56-58): Complex Types
==============================

  "Because the usual mathematical meaning of multiplication of a complex
  operand and a real operand is that of the scaling of both components of
  the former by the latter, an implementation should not perform this
  operation by first promoting the real operand to complex type and then
  performing a full complex multiplication.  In systems that, in the
  future, support an Ada binding to IEC 559:1989, the latter technique
  will not generate the required result when one of the components of the
  complex operand is infinite.  (Explicit multiplication of the infinite
  component by the zero component obtained during promotion yields a NaN
  that propagates into the final result.) Analogous advice applies in the
  case of multiplication of a complex operand and a pure-imaginary
  operand, and in the case of division of a complex operand by a real or
  pure-imaginary operand."

Not followed.

  "Similarly, because the usual mathematical meaning of addition of a
  complex operand and a real operand is that the imaginary operand remains
  unchanged, an implementation should not perform this operation by first
  promoting the real operand to complex type and then performing a full
  complex addition.  In implementations in which the ``Signed_Zeros``
  attribute of the component type is ``True`` (and which therefore
  conform to IEC 559:1989 in regard to the handling of the sign of zero in
  predefined arithmetic operations), the latter technique will not
  generate the required result when the imaginary component of the complex
  operand is a negatively signed zero.  (Explicit addition of the negative
  zero to the zero obtained during promotion yields a positive zero.)
  Analogous advice applies in the case of addition of a complex operand
  and a pure-imaginary operand, and in the case of subtraction of a
  complex operand and a real or pure-imaginary operand."

Not followed.

  "Implementations in which ``Real'Signed_Zeros`` is ``True`` should
  attempt to provide a rational treatment of the signs of zero results and
  result components.  As one example, the result of the ``Argument``
  function should have the sign of the imaginary component of the
  parameter ``X`` when the point represented by that parameter lies on
  the positive real axis; as another, the sign of the imaginary component
  of the ``Compose_From_Polar`` function should be the same as
  (respectively, the opposite of) that of the ``Argument`` parameter when that
  parameter has a value of zero and the ``Modulus`` parameter has a
  nonnegative (respectively, negative) value."

Followed.

.. index:: Complex elementary functions

RM G.1.2(49): Complex Elementary Functions
==========================================

  "Implementations in which ``Complex_Types.Real'Signed_Zeros`` is
  ``True`` should attempt to provide a rational treatment of the signs
  of zero results and result components.  For example, many of the complex
  elementary functions have components that are odd functions of one of
  the parameter components; in these cases, the result component should
  have the sign of the parameter component at the origin.  Other complex
  elementary functions have zero components whose sign is opposite that of
  a parameter component at the origin, or is always positive or always
  negative."

Followed.

.. index:: Accuracy requirements

RM G.2.4(19): Accuracy Requirements
===================================

  "The versions of the forward trigonometric functions without a
  ``Cycle`` parameter should not be implemented by calling the
  corresponding version with a ``Cycle`` parameter of
  ``2.0*Numerics.Pi``, since this will not provide the required
  accuracy in some portions of the domain.  For the same reason, the
  version of ``Log`` without a ``Base`` parameter should not be
  implemented by calling the corresponding version with a ``Base``
  parameter of ``Numerics.e``."

Followed.

.. index:: Complex arithmetic accuracy

.. index:: Accuracy, complex arithmetic

RM G.2.6(15): Complex Arithmetic Accuracy
=========================================

  "The version of the ``Compose_From_Polar`` function without a
  ``Cycle`` parameter should not be implemented by calling the
  corresponding version with a ``Cycle`` parameter of
  ``2.0*Numerics.Pi``, since this will not provide the required
  accuracy in some portions of the domain."

Followed.

.. index:: Sequential elaboration policy

RM H.6(15/2): Pragma Partition_Elaboration_Policy
=================================================

  "If the partition elaboration policy is ``Sequential`` and the
  Environment task becomes permanently blocked during elaboration then the
  partition is deadlocked and it is recommended that the partition be
  immediately terminated."

Not followed.

---

### Gcc Ada Doc Gnat Rm Implementation Defined Aspects (`gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst`)

.. _Implementation_Defined_Aspects:

******************************
Implementation Defined Aspects
******************************

Ada defines (throughout the Ada 2012 reference manual, summarized
in Annex K) a set of aspects that can be specified for certain entities.
These language defined aspects are implemented in GNAT in Ada 2012 mode
and work as described in the Ada 2012 Reference Manual.

In addition, Ada 2012 allows implementations to define additional aspects
whose meaning is defined by the implementation.  GNAT provides
a number of these implementation-defined aspects which can be used
to extend and enhance the functionality of the compiler.  This section of
the GNAT reference manual describes these additional aspects.

Note that any program using these aspects may not be portable to
other compilers (although GNAT implements this set of aspects on all
platforms).  Therefore if portability to other compilers is an important
consideration, you should minimize the use of these aspects.

Note that for many of these aspects, the effect is essentially similar
to the use of a pragma or attribute specification with the same name
applied to the entity. For example, if we write:


.. code-block:: ada

  type R is range 1 .. 100
    with Value_Size => 10;


then the effect is the same as:

.. code-block:: ada

  type R is range 1 .. 100;
  for R'Value_Size use 10;


and if we write:

.. code-block:: ada

  type R is new Integer
    with Shared => True;


then the effect is the same as:

.. code-block:: ada

  type R is new Integer;
  pragma Shared (R);


In the documentation below, such cases are simply marked
as being boolean aspects equivalent to the corresponding pragma
or attribute definition clause.

Aspect Abstract_State
=====================

.. index:: Abstract_State

This aspect is equivalent to :ref:`pragma Abstract_State<Pragma-Abstract_State>`.

Aspect Always_Terminates
========================
.. index:: Always_Terminates

This boolean aspect is equivalent to :ref:`pragma Always_Terminates<Pragma-Always_Terminates>`.

Aspect Annotate
===============

.. index:: Annotate

There are three forms of this aspect (where ID is an identifier,
and ARG is a general expression),
corresponding to :ref:`pragma Annotate<Pragma-Annotate>`.



*Annotate => ID*
  Equivalent to ``pragma Annotate (ID, Entity => Name);``


*Annotate => (ID)*
  Equivalent to ``pragma Annotate (ID, Entity => Name);``


*Annotate => (ID ,ID {, ARG})*
  Equivalent to ``pragma Annotate (ID, ID {, ARG}, Entity => Name);``

Aspect Async_Readers
====================
.. index:: Async_Readers

This boolean aspect is equivalent to :ref:`pragma Async_Readers<Pragma-Async_Readers>`.

Aspect Async_Writers
====================
.. index:: Async_Writers

This boolean aspect is equivalent to :ref:`pragma Async_Writers<Pragma-Async_Writers>`.

Aspect Constant_After_Elaboration
=================================
.. index:: Constant_After_Elaboration

This aspect is equivalent to :ref:`pragma Constant_After_Elaboration<Pragma-Constant_After_Elaboration>`.

Aspect Contract_Cases
=====================
.. index:: Contract_Cases

This aspect is equivalent to :ref:`pragma Contract_Cases<Pragma-Contract_Cases>`, the sequence
of clauses being enclosed in parentheses so that syntactically it is an
aggregate.

Aspect Depends
==============
.. index:: Depends

This aspect is equivalent to :ref:`pragma Depends<Pragma-Depends>`.

Aspect Default_Initial_Condition
================================
.. index:: Default_Initial_Condition

This aspect is equivalent to :ref:`pragma Default_Initial_Condition<Pragma-Default_Initial_Condition>`.

Aspect Dimension
================
.. index:: Dimension

The ``Dimension`` aspect is used to specify the dimensions of a given
subtype of a dimensioned numeric type. The aspect also specifies a symbol
used when doing formatted output of dimensioned quantities. The syntax is::

  with Dimension =>
    ([Symbol =>] SYMBOL, DIMENSION_VALUE {, DIMENSION_Value})

  SYMBOL ::= STRING_LITERAL | CHARACTER_LITERAL

  DIMENSION_VALUE ::=
    RATIONAL
  | others               => RATIONAL
  | DISCRETE_CHOICE_LIST => RATIONAL

  RATIONAL ::= [-] NUMERIC_LITERAL [/ NUMERIC_LITERAL]


This aspect can only be applied to a subtype whose parent type has
a ``Dimension_System`` aspect. The aspect must specify values for
all dimensions of the system. The rational values are the powers of the
corresponding dimensions that are used by the compiler to verify that
physical (numeric) computations are dimensionally consistent. For example,
the computation of a force must result in dimensions (L => 1, M => 1, T => -2).
For further examples of the usage
of this aspect, see package ``System.Dim.Mks``.
Note that when the dimensioned type is an integer type, then any
dimension value must be an integer literal.

Aspect Dimension_System
=======================
.. index:: Dimension_System

The ``Dimension_System`` aspect is used to define a system of
dimensions that will be used in subsequent subtype declarations with
``Dimension`` aspects that reference this system. The syntax is::

  with Dimension_System => (DIMENSION {, DIMENSION});

  DIMENSION ::= ([Unit_Name   =>] IDENTIFIER,
                 [Unit_Symbol =>] SYMBOL,
                 [Dim_Symbol  =>] SYMBOL)

  SYMBOL ::= CHARACTER_LITERAL | STRING_LITERAL


This aspect is applied to a type, which must be a numeric derived type
(typically a floating-point type), that
will represent values within the dimension system. Each ``DIMENSION``
corresponds to one particular dimension. A maximum of 7 dimensions may
be specified. ``Unit_Name`` is the name of the dimension (for example
``Meter``). ``Unit_Symbol`` is the shorthand used for quantities
of this dimension (for example ``m`` for ``Meter``).
``Dim_Symbol`` gives
the identification within the dimension system (typically this is a
single letter, e.g. ``L`` standing for length for unit name ``Meter``).
The ``Unit_Symbol`` is used in formatted output of dimensioned quantities.
The ``Dim_Symbol`` is used in error messages when numeric operations have
inconsistent dimensions.

GNAT provides the standard definition of the International MKS system in
the run-time package ``System.Dim.Mks``. You can easily define
similar packages for cgs units or British units, and define conversion factors
between values in different systems. The MKS system is characterized by the
following aspect:

.. code-block:: ada

     type Mks_Type is new Long_Long_Float with
       Dimension_System => (
         (Unit_Name => Meter,    Unit_Symbol => 'm',   Dim_Symbol => 'L'),
         (Unit_Name => Kilogram, Unit_Symbol => "kg",  Dim_Symbol => 'M'),
         (Unit_Name => Second,   Unit_Symbol => 's',   Dim_Symbol => 'T'),
         (Unit_Name => Ampere,   Unit_Symbol => 'A',   Dim_Symbol => 'I'),
         (Unit_Name => Kelvin,   Unit_Symbol => 'K',   Dim_Symbol => '@'),
         (Unit_Name => Mole,     Unit_Symbol => "mol", Dim_Symbol => 'N'),
         (Unit_Name => Candela,  Unit_Symbol => "cd",  Dim_Symbol => 'J'));


Note that in the above type definition, we use the ``at`` symbol (``@``) to
represent a theta character (avoiding the use of extended Latin-1
characters in this context).

See section 'Performing Dimensionality Analysis in GNAT' in the GNAT Users
Guide for detailed examples of use of the dimension system.

Aspect Disable_Controlled
=========================
.. index:: Disable_Controlled

The aspect  ``Disable_Controlled`` is defined for controlled record types. If
active, this aspect causes suppression of all related calls to ``Initialize``,
``Adjust``, and ``Finalize``. The intended use is for conditional compilation,
where for example you might want a record to be controlled or not depending on
whether some run-time check is enabled or suppressed.

Aspect Effective_Reads
======================
.. index:: Effective_Reads

This aspect is equivalent to :ref:`pragma Effective_Reads<Pragma-Effective_Reads>`.

Aspect Effective_Writes
=======================
.. index:: Effective_Writes

This aspect is equivalent to :ref:`pragma Effective_Writes<Pragma-Effective_Writes>`.

Aspect Exceptional_Cases
========================
.. index:: Exceptional_Cases

This aspect may be specified for procedures and functions with side effects;
it can be used to list exceptions that might be propagated by the subprogram
with side effects in the context of its precondition, and associate them
with a specific postcondition.

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section 6.1.9.

Aspect Exit_Cases
=================
.. index:: Exit_Cases

This aspect may be specified for procedures and functions with side effects;
it can be used to partition the input state into a list of cases and specify,
for each case, how the subprogram is allowed to terminate (i.e. return normally
or propagate an exception).

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section 6.1.10.

Aspect Extended_Access
======================

This nonoverridable boolean-valued type-related representation aspect can be
specified as part of a full_type_declaration for a general access type
designating an unconstrained array subtype.

The absence of an Extended_Access aspect specification for such a
full_type_declaration is equivalent to an explicit
"Extended_Access => False" specification. This implies
that the aspect is never unspecified for an eligible access type.
An access type for which this aspect is True is said to be an extended access
type; this includes the case of a type derived from an extended access type.
Similarly, a value of such a type is said to be an extended access value.

The representation of an extended access value is different than that of
other access values. This representation makes it possible to designate
objects that cannot be designated using the usual "thin" or "fat" access
representations for an access type designating an unconstrained array
subtype (notably slices and array objects imported from other languages).

In particular, two rules are modified in determining the legality of an Access
or Unchecked_Access attribute reference if the expected access type is
an extended access type:

* A slice of an aliased array object of a non-bitpacked type (more precisely,
  of an array type having independently addressable components) is considered
  to be aliased (and the accessibility level of a slice of an array object is
  defined to be that of the array object); this also applies to renamings
  of such slices, slices of such renamings, etc.

* The requirement that the nominal subtype of the prefix shall statically
  match the designated subtype of the access type need not be met.

The Size aspect (and other aspects including Stream_Size, Object_Size,
and Alignment) of an extended access type may depend on the properties of the
designated type. Further details of this dependence are not documented.

An extended access value is not convertible to a non-extended access type,
although conversions in the opposite direction are allowed. We don't want
to allow

.. code-block:: ada

   type Big_Ref is access all String with Extended_Access;
   type Small_Ref is access all String;
   Obj : aliased String := "abcde";
   Big_Ptr : Big_Ref := Obj (2 .. 4)'Access; -- OK
   Small_Ptr : Small_Ref := Small_Ref (Big_Ptr); -- ERROR: illegal conversion

because there is no way to represent the result of such a conversion.

A dereference of an extended access value (or a reference to a renaming
thereof) shall not occur in any of the following contexts:

* as an operative constituent of the prefix of an Access or
  Unchecked_Access attribute reference whose expected type is not extended; or

* as an operative constituent of an actual parameter in a call where
  the corresponding formal parameter is explicitly aliased.

For the same reasons that explicit conversions from an extended access type to a
non-extended access type are forbidden, we also need to disallow getting the
same effect via a Extended_Ptr.all'Access reference; this includes the case
of passing Extended_Ptr.all as an actual parameter in a call where the
corresponding formal parameter is explicitly aliased (because the callee
could evaluate Formal_Parameter'Access). This goal is accomplished by
adjusting the definition of the term "aliased". A dereference of an extended
value occurring in one of these contexts is defined to denote
a nonaliased view. This has the desired effect because these contexts require
an aliased view. Continuing the preceding example, this rule disallows

.. code-block:: ada

   Sneaky_1 : Small_Ptr := Big_Ptr.all'Access; -- ERROR: illegal 'Access prefix

   function Make (Str : aliased in out String) return Small_Ptr
     is (Str'Access); -- OK

   Sneaky_2 : Small_Ptr := Make (Str => Big_Ptr.all); -- ERROR: bad parameter

for the same reason given above in the case of an explicit type conversion.

Aspect Extensions_Visible
=========================
.. index:: Extensions_Visible

This aspect is equivalent to :ref:`pragma Extensions_Visible<Pragma-Extensions_Visible>`.

Aspect Favor_Top_Level
======================
.. index:: Favor_Top_Level

This boolean aspect is equivalent to :ref:`pragma Favor_Top_Level<Pragma-Favor_Top_Level>`.

Aspect Ghost
=============
.. index:: Ghost

This aspect is equivalent to :ref:`pragma Ghost<Pragma-Ghost>`.

Aspect Ghost_Predicate
======================
.. index:: Ghost_Predicate

This aspect introduces a subtype predicate that can reference ghost
entities. The subtype cannot appear as a subtype_mark in a membership test.

For the detailed semantics of this aspect, see the entry for subtype predicates
in the SPARK Reference Manual, section 3.2.4.

Aspect Global
=============
.. index:: Global

This aspect is equivalent to :ref:`pragma Global<Pragma-Global>`.

Aspect Initial_Condition
========================
.. index:: Initial_Condition

This aspect is equivalent to :ref:`pragma Initial_Condition<Pragma-Initial_Condition>`.

Aspect Initializes
==================
.. index:: Initializes

This aspect is equivalent to :ref:`pragma Initializes<Pragma-Initializes>`.

Aspect Inline_Always
====================
.. index:: Inline_Always

This boolean aspect is equivalent to :ref:`pragma Inline_Always<Pragma-Inline_Always>`.

Aspect Invariant
================
.. index:: Invariant

This aspect is equivalent to :ref:`pragma Invariant<Pragma-Invariant>`. It is a
synonym for the language defined aspect ``Type_Invariant`` except
that it is separately controllable using pragma ``Assertion_Policy``.

Aspect Invariant'Class
======================
.. index:: Invariant'Class

This aspect is equivalent to :ref:`pragma Type_Invariant_Class<Pragma-Type_Invariant_Class>`. It is a
synonym for the language defined aspect ``Type_Invariant'Class`` except
that it is separately controllable using pragma ``Assertion_Policy``.

Aspect Iterable
===============
.. index:: Iterable

This aspect provides a light-weight mechanism for loops and quantified
expressions over container types, without the overhead imposed by the tampering
checks of standard Ada 2012 iterators. The value of the aspect is an aggregate
with six named components, of which the last four are optional: ``First``,
``Next``, ``Has_Element``, ``Element``, ``Constant_Reference``, ``Last``, and
``Previous``.
When only the first three components are specified, only the
``for .. in`` form of iteration over cursors is available. When either
``Element`` or ``Constant_Reference`` is specified, both this form and the
``for .. of`` form of iteration over elements are available. ``Element``
and ``Constant_Reference`` cannot be specified together.
If the last two components are specified, reverse
iterations over the container can be specified (analogous to what can be done
over predefined containers that support the ``Reverse_Iterator`` interface).
The following is a typical example of use:

.. code-block:: ada

  type List is private with
      Iterable => (First              => First_Cursor,
                   Next               => Advance,
                   Has_Element        => Cursor_Has_Element
                 [,Element            => Get_Element]
                 [,Constant_Reference => Element_Constant_Access]
                 [,Last               => Last_Cursor]
                 [,Previous           => Retreat]);

* The values of ``First`` and ``Last`` are primitive operations of the
  container type that return a ``Cursor``, which must be a type declared in
  the container package or visible from it. For example:

.. code-block:: ada

  function First_Cursor (Cont : Container) return Cursor;
  function Last_Cursor  (Cont : Container) return Cursor;

* The values of ``Next`` and ``Previous`` are primitive operations of the container type that take
  both a container and a cursor and yield a cursor. For example:

.. code-block:: ada

  function Advance (Cont : Container; Position : Cursor) return Cursor;
  function Retreat (Cont : Container; Position : Cursor) return Cursor;

* The value of ``Has_Element`` is a primitive operation of the container type
  that takes both a container and a cursor and yields a boolean. For example:

.. code-block:: ada

  function Cursor_Has_Element (Cont : Container; Position : Cursor) return Boolean;

* The value of ``Element`` is a primitive operation of the container type that
  takes both a container and a cursor and yields an ``Element_Type``, which must
  be a type declared in the container package or visible from it. For example:

.. code-block:: ada

  function Get_Element (Cont : Container; Position : Cursor) return Element_Type;

* The value of ``Constant_Reference`` is a primitive operation of the container
  type that
  takes both a container and a cursor and yields an anonymous access-to-constant
  type designating ``Element_Type`` with null exclusion, which must
  be a type declared in the container package or visible from it. For example:

.. code-block:: ada

  function Element_Constant_Access (Cont : Container; Position : Cursor) return not null access constant Element_Type;

This aspect is used in the GNAT-defined formal container packages.

Aspect Linker_Section
=====================
.. index:: Linker_Section

This aspect is equivalent to :ref:`pragma Linker_Section<Pragma-Linker_Section>`.

Aspect Local_Restrictions
=========================
.. index:: Local_Restrictions

This aspect may be specified for a subprogram (and for other declarations
as described below). It is used to specify that a particular subprogram does
not violate one or more local restrictions, nor can it call a subprogram
that is not subject to the same requirement. Positional aggregate syntax
(with parentheses, not square brackets) may be used to specify more than one
local restriction, as in

.. code-block:: ada

  procedure Do_Something
    with Local_Restrictions => (Some_Restriction, Another_Restriction);

Parentheses are currently required even in the case of specifying a single
local restriction (this requirement may be relaxed in the future).
Supported local restrictions currently include (only) No_Heap_Allocations and
No_Secondary_Stack.
No_Secondary_Stack corresponds to the GNAT-defined (global) restriction
of the same name. No_Heap_Allocations corresponds to the conjunction of the
Ada-defined restrictions No_Allocators and No_Implicit_Heap_Allocations.

Additional requirements are imposed in order to ensure that restriction
violations cannot be achieved via overriding dispatching operations,
calling through an access-to-subprogram value, calling a generic formal
subprogram, or calling through a subprogram renaming.
For a dispatching operation, an overrider must be subject to (at least) the
same restrictions as the overridden inherited subprogram; similarly, the
actual subprogram corresponding to a generic formal subprogram
in an instantiation must be subject to (at least) the same restrictions
as the formal subprogram. A call through an access-to-subprogram value
is conservatively assumed to violate all local restrictions; tasking-related
constructs (notably entry calls) are treated similarly. A renaming-as-body is
treated like a subprogram body containing a call to the renamed subprogram.

The Local_Restrictions aspect can be specified for a package specification,
in which case the aspect specification also applies to all eligible entities
declared with the package. This includes types. Default initialization of an
object of a given type is treated like a call to an implicitly-declared
initialization subprogram. Such a "call" is subject to the same local
restriction checks as any other call. If a type is subject to a local
restriction, then any violations of that restriction within the default
initialization expressions (if any) of the type are rejected. This may
include "calls" to the default initialization subprograms of other types.

Local_Restrictions aspect specifications are additive (for example, in the
case of a declaration that occurs within nested packages that each have
a Local_Restrictions specification).


Aspect Lock_Free
================
.. index:: Lock_Free

This boolean aspect is equivalent to :ref:`pragma Lock_Free<Pragma-Lock_Free>`.

Aspect Max_Queue_Length
=======================
.. index:: Max_Queue_Length

This aspect is equivalent to :ref:`pragma Max_Queue_Length<Pragma-Max_Queue_Length>`.

Aspect Modifies
===============
.. index:: Modifies

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section TBD.

Aspect No_Caching
=================
.. index:: No_Caching

This boolean aspect is equivalent to :ref:`pragma No_Caching<Pragma-No_Caching>`.

Aspect No_Elaboration_Code_All
==============================
.. index:: No_Elaboration_Code_All

This aspect is equivalent to :ref:`pragma No_Elaboration_Code_All<Pragma-No_Elaboration_Code_All>`
for a program unit.

Aspect No_Inline
================
.. index:: No_Inline

This boolean aspect is equivalent to :ref:`pragma No_Inline<Pragma-No_Inline>`.

Aspect No_Raise
===============
.. index:: No_Raise

This boolean aspect is equivalent to :ref:`pragma No_Raise<Pragma-No_Raise>`.

Aspect No_Tagged_Streams
========================
.. index:: No_Tagged_Streams

This aspect is equivalent to :ref:`pragma No_Tagged_Streams<Pragma-No_Tagged_Streams>` with an
argument specifying a root tagged type (thus this aspect can only be
applied to such a type).

Aspect No_Task_Parts
========================
.. index:: No_Task_Parts

Applies to a type. If True, requires that the type and any descendants
do not have any task parts. The rules for this aspect are the same as
for the language-defined No_Controlled_Parts aspect (see RM-H.4.1),
replacing "controlled" with "task".

If No_Task_Parts is True for a type T, then the compiler can optimize
away certain tasking-related code that would otherwise be needed
for T'Class, because descendants of T might contain tasks.

Aspect Object_Size
==================
.. index:: Object_Size

This aspect is equivalent to :ref:`attribute Object_Size<Attribute-Object_Size>`.

Aspect Obsolescent
==================
.. index:: Obsolescent

This aspect is equivalent to :ref:`pragma Obsolescent<Pragma_Obsolescent>`. Note that the
evaluation of this aspect happens at the point of occurrence, it is not
delayed until the freeze point.

Aspect Part_Of
==============
.. index:: Part_Of

This aspect is equivalent to :ref:`pragma Part_Of<Pragma-Part_Of>`.

Aspect Persistent_BSS
=====================
.. index:: Persistent_BSS

This boolean aspect is equivalent to :ref:`pragma Persistent_BSS<Pragma-Persistent_BSS>`.

Aspect Potentially_Invalid
==========================
.. index:: Potentially_Invalid

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section 13.9.1.


Aspect Predicate
================
.. index:: Predicate

This aspect is equivalent to :ref:`pragma Predicate<Pragma-Predicate>`. It is thus
similar to the language defined aspects ``Dynamic_Predicate``
and ``Static_Predicate`` except that whether the resulting
predicate is static or dynamic is controlled by the form of the
expression. It is also separately controllable using pragma
``Assertion_Policy``.

Aspect Program_Exit
===================
.. index:: Program_Exit

This boolean aspect is equivalent to :ref:`pragma Program_Exit<Pragma-Program_Exit>`.

Aspect Pure_Function
====================
.. index:: Pure_Function

This boolean aspect is equivalent to :ref:`pragma Pure_Function<Pragma-Pure_Function>`.

Aspect Refined_Depends
======================
.. index:: Refined_Depends

This aspect is equivalent to :ref:`pragma Refined_Depends<Pragma-Refined_Depends>`.

Aspect Refined_Global
=====================
.. index:: Refined_Global

This aspect is equivalent to :ref:`pragma Refined_Global<Pragma-Refined_Global>`.

Aspect Refined_Post
===================
.. index:: Refined_Post

This aspect is equivalent to :ref:`pragma Refined_Post<Pragma-Refined_Post>`.

Aspect Refined_State
====================
.. index:: Refined_State

This aspect is equivalent to :ref:`pragma Refined_State<Pragma-Refined_State>`.

Aspect Relaxed_Initialization
=============================
.. index:: Refined_Initialization

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section 6.10.

Aspect Remote_Access_Type
=========================
.. index:: Remote_Access_Type

This aspect is equivalent to :ref:`pragma Remote_Access_Type<Pragma-Remote_Access_Type>`.

Aspect Scalar_Storage_Order
===========================
.. index:: Scalar_Storage_Order

This aspect is equivalent to a :ref:`attribute Scalar_Storage_Order<Attribute-Scalar_Storage_Order>`.

Aspect Secondary_Stack_Size
===========================

.. index:: Secondary_Stack_Size

This aspect is equivalent to :ref:`pragma Secondary_Stack_Size<Pragma-Secondary_Stack_Size>`.

Aspect Shared
=============
.. index:: Shared

This boolean aspect is equivalent to :ref:`pragma Shared<Pragma-Shared>`
and is thus a synonym for aspect ``Atomic``.

Aspect Side_Effects
===================
.. index:: Side_Effects

This aspect is equivalent to :ref:`pragma Side_Effects<Pragma-Side_Effects>`.

Aspect Simple_Storage_Pool
==========================
.. index:: Simple_Storage_Pool

This aspect is equivalent to :ref:`attribute Simple_Storage_Pool<Attribute_Simple_Storage_Pool>`.

Aspect Simple_Storage_Pool_Type
===============================
.. index:: Simple_Storage_Pool_Type

This boolean aspect is equivalent to :ref:`pragma Simple_Storage_Pool_Type<Pragma-Simple_Storage_Pool_Type>`.

Aspect SPARK_Mode
=================
.. index:: SPARK_Mode

This aspect is equivalent to :ref:`pragma SPARK_Mode<Pragma-SPARK_Mode>` and
may be specified for either or both of the specification and body
of a subprogram or package.

Aspect Subprogram_Variant
=========================
.. index:: Subprogram_Variant

For the syntax and semantics of this aspect, see the SPARK 2014 Reference
Manual, section 6.1.8.

Aspect Suppress_Debug_Info
==========================
.. index:: Suppress_Debug_Info

This boolean aspect is equivalent to :ref:`pragma Suppress_Debug_Info<Pragma-Suppress_Debug_Info>`.

Aspect Suppress_Initialization
==============================
.. index:: Suppress_Initialization

This boolean aspect is equivalent to :ref:`pragma Suppress_Initialization<Pragma-Suppress_Initialization>`.

Aspect Test_Case
================
.. index:: Test_Case

This aspect is equivalent to :ref:`pragma Test_Case<Pragma-Test_Case>`.

Aspect Thread_Local_Storage
===========================
.. index:: Thread_Local_Storage

This boolean aspect is equivalent to :ref:`pragma Thread_Local_Storage<Pragma-Thread_Local_Storage>`.

Aspect Universal_Aliasing
=========================
.. index:: Universal_Aliasing

This boolean aspect is equivalent to :ref:`pragma Universal_Aliasing<Pragma-Universal_Aliasing>`.

Aspect Unmodified
=================
.. index:: Unmodified

This boolean aspect is equivalent to :ref:`pragma Unmodified<Pragma-Unmodified>`.

Aspect Unreferenced
===================
.. index:: Unreferenced

This boolean aspect is equivalent to :ref:`pragma Unreferenced<Pragma-Unreferenced>`.

When using the ``-gnat2022`` switch, this aspect is also supported on formal
parameters, which is in particular the only form possible for expression
functions.

Aspect Unreferenced_Objects
===========================
.. index:: Unreferenced_Objects

This boolean aspect is equivalent to :ref:`pragma Unreferenced_Objects<Pragma-Unreferenced_Objects>`.

Aspect User_Aspect
==================
.. index:: User_Aspect

This aspect takes an argument that is the name of an aspect defined by a
User_Aspect_Definition configuration pragma.
A User_Aspect aspect specification is semantically equivalent to
replicating the set of aspect specifications associated with the named
pragma-defined aspect.

Aspect Value_Size
=================
.. index:: Value_Size

This aspect is equivalent to :ref:`attribute Value_Size<Attribute-Value_Size>`.

Aspect Volatile_Full_Access
===========================
.. index:: Volatile_Full_Access

This boolean aspect is equivalent to :ref:`pragma Volatile_Full_Access<Pragma-Volatile_Full_Access>`.

Aspect Volatile_Function
===========================
.. index:: Volatile_Function

This boolean aspect is equivalent to :ref:`pragma Volatile_Function<Pragma-Volatile_Function>`.

Aspect Warnings
===============
.. index:: Warnings

This aspect is equivalent to the two argument form of :ref:`pragma Warnings<Pragma_Warnings>`,
where the first argument is ``ON`` or ``OFF`` and the second argument
is the entity.

---

### Gcc Ada Doc Gnat Rm Implementation Defined Attributes (`gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst`)

.. _Implementation_Defined_Attributes:

*********************************
Implementation Defined Attributes
*********************************

Ada defines (throughout the Ada reference manual,
summarized in Annex K),
a set of attributes that provide useful additional functionality in all
areas of the language.  These language defined attributes are implemented
in GNAT and work as described in the Ada Reference Manual.

In addition, Ada allows implementations to define additional
attributes whose meaning is defined by the implementation.  GNAT provides
a number of these implementation-dependent attributes which can be used
to extend and enhance the functionality of the compiler.  This section of
the GNAT reference manual describes these additional attributes.  It also
describes additional implementation-dependent features of standard
language-defined attributes.

Note that any program using these attributes may not be portable to
other compilers (although GNAT implements this set of attributes on all
platforms).  Therefore if portability to other compilers is an important
consideration, you should minimize the use of these attributes.

Attribute Abort_Signal
======================
.. index:: Abort_Signal

``Standard'Abort_Signal`` (``Standard`` is the only allowed
prefix) provides the entity for the special exception used to signal
task abort or asynchronous transfer of control.  Normally this attribute
should only be used in the tasking runtime (it is highly peculiar, and
completely outside the normal semantics of Ada, for a user program to
intercept the abort exception).

Attribute Address_Size
======================
.. index:: Size of ``Address``

.. index:: Address_Size

``Standard'Address_Size`` (``Standard`` is the only allowed
prefix) is a static constant giving the number of bits in an
``Address``. It is the same value as System.Address'Size,
but has the advantage of being static, while a direct
reference to System.Address'Size is nonstatic because Address
is a private type.

Attribute Asm_Input
===================
.. index:: Asm_Input

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
constant are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
:ref:`Machine_Code_Insertions`

Attribute Asm_Output
====================
.. index:: Asm_Output

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``.
:ref:`Machine_Code_Insertions`

Attribute Atomic_Always_Lock_Free
=================================
.. index:: Atomic_Always_Lock_Free

The prefix of the ``Atomic_Always_Lock_Free`` attribute is a type. The
result indicates whether atomic operations are supported by the target
for the given type.

Attribute Bit
=============
.. index:: Bit

``obj'Bit``, where ``obj`` is any object, yields the bit
offset within the storage unit (byte) that contains the first bit of
storage allocated for the object.  The value of this attribute is of the
type *universal_integer* and is always a nonnegative number smaller
than ``System.Storage_Unit``.

For an object that is a variable or a constant allocated in a register,
the value is zero.  (The use of this attribute does not force the
allocation of a variable to memory).

For an object that is a formal parameter, this attribute applies
to either the matching actual parameter or to a copy of the
matching actual parameter.

For an access object the value is zero.  Note that
``obj.all'Bit`` is subject to an ``Access_Check`` for the
designated object.  Similarly for a record component
``X.C'Bit`` is subject to a discriminant check and
``X(I).Bit`` and ``X(I1..I2)'Bit``
are subject to index checks.

This attribute is designed to be compatible with the DEC Ada 83 definition
and implementation of the ``Bit`` attribute.

Attribute Bit_Position
======================
.. index:: Bit_Position

``R.C'Bit_Position``, where ``R`` is a record object and ``C`` is one
of the fields of the record type, yields the bit
offset within the record contains the first bit of
storage allocated for the object.  The value of this attribute is of the
type *universal_integer*.  The value depends only on the field
``C`` and is independent of the alignment of
the containing record ``R``.

Attribute Code_Address
======================
.. index:: Code_Address
.. index:: Subprogram address

.. index:: Address of subprogram code

The ``'Address``
attribute may be applied to subprograms in Ada 95 and Ada 2005, but the
intended effect seems to be to provide
an address value which can be used to call the subprogram by means of
an address clause as in the following example:

.. code-block:: ada

  procedure K is ...

  procedure L;
  for L'Address use K'Address;
  pragma Import (Ada, L);


A call to ``L`` is then expected to result in a call to ``K``.
In Ada 83, where there were no access-to-subprogram values, this was
a common work-around for getting the effect of an indirect call.
GNAT implements the above use of ``Address`` and the technique
illustrated by the example code works correctly.

However, for some purposes, it is useful to have the address of the start
of the generated code for the subprogram.  On some architectures, this is
not necessarily the same as the ``Address`` value described above.
For example, the ``Address`` value may reference a subprogram
descriptor rather than the subprogram itself.

The ``'Code_Address`` attribute, which can only be applied to
subprogram entities, always returns the address of the start of the
generated code of the specified subprogram, which may or may not be
the same value as is returned by the corresponding ``'Address``
attribute.

Attribute Compiler_Version
==========================
.. index:: Compiler_Version

``Standard'Compiler_Version`` (``Standard`` is the only allowed
prefix) yields a static string identifying the version of the compiler
being used to compile the unit containing the attribute reference.

Attribute Constrained
=====================
.. index:: Constrained

In addition to the usage of this attribute in the Ada RM, GNAT
also permits the use of the ``'Constrained`` attribute
in a generic template
for any type, including types without discriminants. The value of this
attribute in the generic instance when applied to a scalar type or a
record type without discriminants is always ``True``. This usage is
compatible with older Ada compilers, including notably DEC Ada.


Attribute Default_Bit_Order
===========================
.. index:: Big endian

.. index:: Little endian

.. index:: Default_Bit_Order

``Standard'Default_Bit_Order`` (``Standard`` is the only
allowed prefix), provides the value ``System.Default_Bit_Order``
as a ``Pos`` value (0 for ``High_Order_First``, 1 for
``Low_Order_First``).  This is used to construct the definition of
``Default_Bit_Order`` in package ``System``.

Attribute Default_Scalar_Storage_Order
======================================
.. index:: Big endian

.. index:: Little endian

.. index:: Default_Scalar_Storage_Order

``Standard'Default_Scalar_Storage_Order`` (``Standard`` is the only
allowed prefix), provides the current value of the default scalar storage
order (as specified using pragma ``Default_Scalar_Storage_Order``, or
equal to ``Default_Bit_Order`` if unspecified) as a
``System.Bit_Order`` value. This is a static attribute.

Attribute Deref
===============
.. index:: Deref

The attribute ``typ'Deref(expr)`` where ``expr`` is of type ``System.Address`` yields
the variable of type ``typ`` that is located at the given address. It is similar
to ``(totyp (expr).all)``, where ``totyp`` is an unchecked conversion from address to
a named access-to-`typ` type, except that it yields a variable, so it can be
used on the left side of an assignment.

Attribute Descriptor_Size
=========================
.. index:: Descriptor

.. index:: Dope vector

.. index:: Descriptor_Size

Nonstatic attribute ``Descriptor_Size`` returns the size in bits of the
descriptor allocated for a type.  The result is non-zero only for unconstrained
array types and the returned value is of type universal integer.  In GNAT, an
array descriptor contains bounds information and is located immediately before
the first element of the array.

.. code-block:: ada

  type Unconstr_Array is array (Short_Short_Integer range <>) of Positive;
  Put_Line ("Descriptor size = " & Unconstr_Array'Descriptor_Size'Img);


The attribute takes into account any padding due to the alignment of the
component type. In the example above, the descriptor contains two values
of type ``Short_Short_Integer`` representing the low and high bound. But,
since ``Positive`` has an alignment of 4, the size of the descriptor is
``2 * Short_Short_Integer'Size`` rounded up to the next multiple of 32,
which yields a size of 32 bits, i.e. including 16 bits of padding.

Attribute Elaborated
====================
.. index:: Elaborated

The prefix of the ``'Elaborated`` attribute must be a unit name.  The
value is a Boolean which indicates whether or not the given unit has been
elaborated.  This attribute is primarily intended for internal use by the
generated code for dynamic elaboration checking, but it can also be used
in user programs.  The value will always be True once elaboration of all
units has been completed.  An exception is for units which need no
elaboration, the value is always False for such units.

Attribute Elab_Body
===================
.. index:: Elab_Body

This attribute can only be applied to a program unit name.  It returns
the entity for the corresponding elaboration procedure for elaborating
the body of the referenced unit.  This is used in the main generated
elaboration procedure by the binder and is not normally used in any
other context.  However, there may be specialized situations in which it
is useful to be able to call this elaboration procedure from Ada code,
e.g., if it is necessary to do selective re-elaboration to fix some
error.

Attribute Elab_Spec
===================
.. index:: Elab_Spec

This attribute can only be applied to a program unit name.  It returns
the entity for the corresponding elaboration procedure for elaborating
the spec of the referenced unit.  This is used in the main
generated elaboration procedure by the binder and is not normally used
in any other context.  However, there may be specialized situations in
which it is useful to be able to call this elaboration procedure from
Ada code, e.g., if it is necessary to do selective re-elaboration to fix
some error.

Attribute Elab_Subp_Body
========================
.. index:: Elab_Subp_Body

This attribute can only be applied to a library level subprogram
name and is only allowed in CodePeer mode. It returns the entity
for the corresponding elaboration procedure for elaborating the body
of the referenced subprogram unit. This is used in the main generated
elaboration procedure by the binder in CodePeer mode only and is unrecognized
otherwise.

Attribute Emax
==============
.. index:: Ada 83 attributes

.. index:: Emax

The ``Emax`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

Attribute Enabled
=================
.. index:: Enabled

The ``Enabled`` attribute allows an application program to check at compile
time to see if the designated check is currently enabled. The prefix is a
simple identifier, referencing any predefined check name (other than
``All_Checks``) or a check name introduced by pragma Check_Name. If
no argument is given for the attribute, the check is for the general state
of the check, if an argument is given, then it is an entity name, and the
check indicates whether an ``Suppress`` or ``Unsuppress`` has been
given naming the entity (if not, then the argument is ignored).

Note that instantiations inherit the check status at the point of the
instantiation, so a useful idiom is to have a library package that
introduces a check name with ``pragma Check_Name``, and then contains
generic packages or subprograms which use the ``Enabled`` attribute
to see if the check is enabled. A user of this package can then issue
a ``pragma Suppress`` or ``pragma Unsuppress`` before instantiating
the package or subprogram, controlling whether the check will be present.

Attribute Enum_Rep
==================
.. index:: Representation of enums

.. index:: Enum_Rep

Note that this attribute is now standard in Ada 202x and is available
as an implementation defined attribute for earlier Ada versions.

For every enumeration subtype ``S``, ``S'Enum_Rep`` denotes a
function with the following spec:

.. code-block:: ada

  function S'Enum_Rep (Arg : S'Base) return <Universal_Integer>;


It is also allowable to apply ``Enum_Rep`` directly to an object of an
enumeration type or to a non-overloaded enumeration
literal.  In this case ``S'Enum_Rep`` is equivalent to
``typ'Enum_Rep(S)`` where ``typ`` is the type of the
enumeration literal or object.

The function returns the representation value for the given enumeration
value.  This will be equal to value of the ``Pos`` attribute in the
absence of an enumeration representation clause.  This is a static
attribute (i.e., the result is static if the argument is static).

``S'Enum_Rep`` can also be used with integer types and objects,
in which case it simply returns the integer value.  The reason for this
is to allow it to be used for ``(<>)`` discrete formal arguments in
a generic unit that can be instantiated with either enumeration types
or integer types.  Note that if ``Enum_Rep`` is used on a modular
type whose upper bound exceeds the upper bound of the largest signed
integer type, and the argument is a variable, so that the universal
integer calculation is done at run time, then the call to ``Enum_Rep``
may raise ``Constraint_Error``.

Attribute Enum_Val
==================
.. index:: Representation of enums

.. index:: Enum_Val

Note that this attribute is now standard in Ada 202x and is available
as an implementation defined attribute for earlier Ada versions.

For every enumeration subtype ``S``, ``S'Enum_Val`` denotes a
function with the following spec:

.. code-block:: ada

  function S'Enum_Val (Arg : <Universal_Integer>) return S'Base;


The function returns the enumeration value whose representation matches the
argument, or raises Constraint_Error if no enumeration literal of the type
has the matching value.
This will be equal to value of the ``Val`` attribute in the
absence of an enumeration representation clause.  This is a static
attribute (i.e., the result is static if the argument is static).

Attribute Epsilon
=================
.. index:: Ada 83 attributes

.. index:: Epsilon

The ``Epsilon`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

Attribute Fast_Math
===================
.. index:: Fast_Math

``Standard'Fast_Math`` (``Standard`` is the only allowed
prefix) yields a static Boolean value that is True if pragma
``Fast_Math`` is active, and False otherwise.

Attribute Finalization_Size
===========================
.. index:: Finalization_Size

The prefix of attribute ``Finalization_Size`` must be an object or
a type. This attribute returns the size of any hidden data
reserved by the compiler to handle finalization-related actions. The type of
the attribute is *universal_integer*.

``Finalization_Size`` yields a value of zero for a type with no controlled
parts, an object whose type has no controlled parts, or an object of a
class-wide type whose tag denotes a type with no controlled parts.
For a class-wide type, ``Finalization_Size`` yields a non-zero value except
if a No_Finalization restriction is in effect, in which case it yields zero.

Note that only heap-allocated objects contain finalization data.

Attribute Fixed_Value
=====================
.. index:: Fixed_Value

For every fixed-point type ``S``, ``S'Fixed_Value`` denotes a
function with the following specification:

.. code-block:: ada

  function S'Fixed_Value (Arg : <Universal_Integer>) return S;

The value returned is the fixed-point value ``V`` such that::

  V = Arg * S'Small


The effect is thus similar to first converting the argument to the
integer type used to represent ``S``, and then doing an unchecked
conversion to the fixed-point type.  The difference is
that there are full range checks, to ensure that the result is in range.
This attribute is primarily intended for use in implementation of the
input-output functions for fixed-point values.

Attribute From_Address
======================
.. index:: From_Address

The prefix of this attribute must be a general access-to-array type (or
subtype); the attribute takes a System.Address argument and possibly some
additional arguments (described below) and yields a value of the given
access type that designates an array object located at the given address.
In the case of a non-null array this means that the given address is the
address of the first element of the array object (not the address of any sort
of bounds descriptor). This allows associating bounds with an address that is,
for example, passed in from C code.

If the designated array subtype is unconstrained (which is the usual case),
then for each dimension (in order) the attribute takes either one or two
additional arguments of the corresponding index type - one if the index
subtype is a fixed lower bound subtype, two (low bound first) otherwise.
In this case, the access type shall be an extended access type (see the
description of the Extended_Access aspect). These additional arguments
specify the bounds of the designated array object.

If the designated array subtype is constrained then no additional arguments
are provided and the bounds of the designated object are those of the
designated subtype.

Roughly speaking, My_Access_Type'From_Address (Addr, Lo, Hi) is equivalent to a
declare expression:

.. code-block:: ada

   (declare
      Obj : aliased Designated_Array_Type (Lo .. Hi)
        with Import, Address => Addr;
   begin
      My_Access_Type'(Obj'Unchecked_Access)
   end)

Attribute From_Any
==================
.. index:: From_Any

This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.

Attribute Has_Access_Values
===========================
.. index:: Access values, testing for

.. index:: Has_Access_Values

The prefix of the ``Has_Access_Values`` attribute is a type.  The result
is a Boolean value which is True if the is an access type, or is a composite
type with a component (at any nesting depth) that is an access type, and is
False otherwise.
The intended use of this attribute is in conjunction with generic
definitions.  If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has access values.

Attribute Has_Discriminants
===========================
.. index:: Discriminants, testing for

.. index:: Has_Discriminants

The prefix of the ``Has_Discriminants`` attribute is a type.  The result
is a Boolean value which is True if the type has discriminants, and False
otherwise.  The intended use of this attribute is in conjunction with generic
definitions.  If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has discriminants.

Attribute Has_Tagged_Values
===========================
.. index:: Tagged values, testing for

.. index:: Has_Tagged_Values

The prefix of the ``Has_Tagged_Values`` attribute is a type. The result is a
Boolean value which is True if the type is a composite type (array or record)
that is either a tagged type or has a subcomponent that is tagged, and is False
otherwise. The intended use of this attribute is in conjunction with generic
definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has access values.

Attribute Img
=============
.. index:: Img

The ``Img`` attribute differs from ``Image`` in that, while both can be
applied directly to an object, ``Img`` cannot be applied to types.

Example usage of the attribute:

.. code-block:: ada

  Put_Line ("X = " & X'Img);


which has the same meaning as the more verbose:

.. code-block:: ada

  Put_Line ("X = " & T'Image (X));

where ``T`` is the (sub)type of the object ``X``.

Note that technically, in analogy to ``Image``,
``X'Img`` returns a parameterless function
that returns the appropriate string when called. This means that
``X'Img`` can be renamed as a function-returning-string, or used
in an instantiation as a function parameter.

Attribute Initialized
=====================
.. index:: Initialized

For the syntax and semantics of this attribute, see the SPARK 2014 Reference
Manual, section 6.10.

Attribute Integer_Value
=======================
.. index:: Integer_Value

For every integer type ``S``, ``S'Integer_Value`` denotes a
function with the following spec:

.. code-block:: ada

  function S'Integer_Value (Arg : <Universal_Fixed>) return S;

The value returned is the integer value ``V``, such that::

  Arg = V * T'Small


where ``T`` is the type of ``Arg``.
The effect is thus similar to first doing an unchecked conversion from
the fixed-point type to its corresponding implementation type, and then
converting the result to the target integer type.  The difference is
that there are full range checks, to ensure that the result is in range.
This attribute is primarily intended for use in implementation of the
standard input-output functions for fixed-point values.

Attribute Invalid_Value
=======================
.. index:: Invalid_Value

For every scalar type S, S'Invalid_Value returns an undefined value of the
type. If possible this value is an invalid representation for the type. The
value returned is identical to the value used to initialize an otherwise
uninitialized value of the type if pragma Initialize_Scalars is used,
including the ability to modify the value with the binder -Sxx flag and
relevant environment variables at run time.

Attribute Large
===============
.. index:: Ada 83 attributes

.. index:: Large

The ``Large`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

Attribute Library_Level
=======================
.. index:: Library_Level

``P'Library_Level``, where P is an entity name,
returns a Boolean value which is True if the entity is declared
at the library level, and False otherwise. Note that within a
generic instantiation, the name of the generic unit denotes the
instance, which means that this attribute can be used to test
if a generic is instantiated at the library level, as shown
in this example:

.. code-block:: ada

  generic
    ...
  package Gen is
    pragma Compile_Time_Error
      (not Gen'Library_Level,
       "Gen can only be instantiated at library level");
    ...
  end Gen;


Attribute Loop_Entry
====================
.. index:: Loop_Entry

Syntax::

  X'Loop_Entry [(loop_name)]


The ``Loop_Entry`` attribute is used to refer to the value that an
expression had upon entry to a given loop in much the same way that the
``Old`` attribute in a subprogram postcondition can be used to refer
to the value an expression had upon entry to the subprogram. The
relevant loop is either identified by the given loop name, or it is the
innermost enclosing loop when no loop name is given.

A ``Loop_Entry`` attribute can only occur within an ``Assert``,
``Assert_And_Cut``, ``Assume``, ``Loop_Variant`` or ``Loop_Invariant`` pragma.
In addition, such a pragma must be one of the items in the sequence
of statements of a loop body, or nested inside block statements that
appear in the sequence of statements of a loop body.
A common use of ``Loop_Entry`` is to compare the current value of objects with
their initial value at loop entry, in a ``Loop_Invariant`` pragma.

The effect of using ``X'Loop_Entry`` is the same as declaring
a constant initialized with the initial value of ``X`` at loop
entry. This copy is not performed if the loop is not entered, or if the
corresponding pragmas are ignored or disabled.

Attribute Machine_Size
======================
.. index:: Machine_Size

This attribute is identical to the ``Object_Size`` attribute.  It is
provided for compatibility with the DEC Ada 83 attribute of this name.

Attribute Mantissa
==================
.. index:: Ada 83 attributes

.. index:: Mantissa

The ``Mantissa`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

.. _Attribute_Maximum_Alignment:

Attribute Maximum_Alignment
===========================
.. index:: Alignment, maximum

.. index:: Maximum_Alignment

``Standard'Maximum_Alignment`` (``Standard`` is the only allowed prefix)
provides the maximum default alignment value for the target, that is to
say the maximum alignment that the compiler may choose by default for a
type or an object. Larger alignments are supported up to some maximum
value dependent on the target, but may require specific mechanisms that
are not needed up to ``Standard'Maximum_Alignment``.

Attribute Max_Integer_Size
==========================
.. index:: Max_Integer_Size

``Standard'Max_Integer_Size`` (``Standard`` is the only allowed
prefix) provides the size of the largest supported integer type for
the target. The result is a static constant.

Attribute Mechanism_Code
========================
.. index:: Return values, passing mechanism

.. index:: Parameters, passing mechanism

.. index:: Mechanism_Code

``func'Mechanism_Code`` yields an integer code for the
mechanism used for the result of function ``func``, and
``subprog'Mechanism_Code (n)`` yields the mechanism
used for formal parameter number *n* (a static integer value, with 1
meaning the first parameter) of subprogram ``subprog``.  The code returned is:



*1*
  by copy (value)

*2*
  by reference

Attribute Null_Parameter
========================
.. index:: Zero address, passing

.. index:: Null_Parameter

A reference ``T'Null_Parameter`` denotes an imaginary object of
type or subtype ``T`` allocated at machine address zero.  The attribute
is allowed only as the default expression of a formal parameter, or as
an actual expression of a subprogram call.  In either case, the
subprogram must be imported.

The identity of the object is represented by the address zero in the
argument list, independent of the passing mechanism (explicit or
default).

This capability is needed to specify that a zero address should be
passed for a record or other composite object passed by reference.
There is no way of indicating this without the ``Null_Parameter``
attribute.

.. _Attribute-Object_Size:

Attribute Object_Size
=====================
.. index:: Size, used for objects

.. index:: Object_Size

The size of an object is not necessarily the same as the size of the type
of an object.  This is because by default object sizes are increased to be
a multiple of the alignment of the object.  For example,
``Natural'Size`` is
31, but by default objects of type ``Natural`` will have a size of 32 bits.
Similarly, a record containing an integer and a character:

.. code-block:: ada

  type Rec is record
     I : Integer;
     C : Character;
  end record;


will have a size of 40 (that is ``Rec'Size`` will be 40).  The
alignment will be 4, because of the
integer field, and so the default size of record objects for this type
will be 64 (8 bytes).

If the alignment of the above record is specified to be 1, then the
object size will be 40 (5 bytes). This is true by default, and also
an object size of 40 can be explicitly specified in this case.

A consequence of this capability is that different object sizes can be
given to subtypes that would otherwise be considered in Ada to be
statically matching.  But it makes no sense to consider such subtypes
as statically matching.  Consequently, GNAT adds a rule
to the static matching rules that requires object sizes to match.
Consider this example:

.. code-block:: ada

   1. procedure BadAVConvert is
   2.    type R is new Integer;
   3.    subtype R1 is R range 1 .. 10;
   4.    subtype R2 is R range 1 .. 10;
   5.    for R1'Object_Size use 8;
   6.    for R2'Object_Size use 16;
   7.    type R1P is access all R1;
   8.    type R2P is access all R2;
   9.    R1PV : R1P := new R1'(4);
  10.    R2PV : R2P;
  11. begin
  12.    R2PV := R2P (R1PV);
                 |
         >>> target designated subtype not compatible with
             type "R1" defined at line 3

  13. end;


In the absence of lines 5 and 6,
types ``R1`` and ``R2`` statically match and
hence the conversion on line 12 is legal. But since lines 5 and 6
cause the object sizes to differ, GNAT considers that types
``R1`` and ``R2`` are not statically matching, and line 12
generates the diagnostic shown above.

Similar additional checks are performed in other contexts requiring
statically matching subtypes.

Attribute Old
=============
.. index:: Old

In addition to the usage of ``Old`` defined in the Ada 2012 RM (usage
within ``Post`` aspect), GNAT also permits the use of this attribute
in implementation defined pragmas ``Postcondition``,
``Contract_Cases`` and ``Test_Case``. Also usages of
``Old`` which would be illegal according to the Ada 2012 RM
definition are allowed under control of
implementation defined pragma ``Unevaluated_Use_Of_Old``.

Attribute Passed_By_Reference
=============================
.. index:: Parameters, when passed by reference

.. index:: Passed_By_Reference

``typ'Passed_By_Reference`` for any subtype `typ` returns
a value of type ``Boolean`` value that is ``True`` if the type is
normally passed by reference and ``False`` if the type is normally
passed by copy in calls.  For scalar types, the result is always ``False``
and is static.  For non-scalar types, the result is nonstatic.

Attribute Pool_Address
======================
.. index:: Pool_Address

``X'Pool_Address`` for any object ``X`` returns the address
of X within its storage pool. This is the same as
``X'Address``, except that for an unconstrained array whose
bounds are allocated just before the first component,
``X'Pool_Address`` returns the address of those bounds,
whereas ``X'Address`` returns the address of the first
component.

Here, we are interpreting 'storage pool' broadly to mean
``wherever the object is allocated``, which could be a
user-defined storage pool,
the global heap, on the stack, or in a static memory area.
For an object created by ``new``, ``Ptr.all'Pool_Address`` is
what is passed to ``Allocate`` and returned from ``Deallocate``.

Attribute Range_Length
======================
.. index:: Range_Length

``typ'Range_Length`` for any discrete type `typ` yields
the number of values represented by the subtype (zero for a null
range).  The result is static for static subtypes.  ``Range_Length``
applied to the index subtype of a one dimensional array always gives the
same result as ``Length`` applied to the array itself.

Attribute Ref
=============

``System.Address'Ref`` (``Address`` is the only permissible prefix) is
equivalent to ``System'To_Address``, provided for compatibility with other
compilers.

Attribute Restriction_Set
=========================
.. index:: Restriction_Set
.. index:: Restrictions

This attribute allows compile time testing of restrictions that
are currently in effect. It is primarily intended for specializing
code in the run-time based on restrictions that are active (e.g.
don't need to save fpt registers if restriction No_Floating_Point
is known to be in effect), but can be used anywhere.

There are two forms:

.. code-block:: ada

  System'Restriction_Set (partition_boolean_restriction_NAME)
  System'Restriction_Set (No_Dependence => library_unit_NAME);


In the case of the first form, the only restriction names
allowed are parameterless restrictions that are checked
for consistency at bind time. For a complete list see the
subtype ``System.Rident.Partition_Boolean_Restrictions``.

The result returned is True if the restriction is known to
be in effect, and False if the restriction is known not to
be in effect. An important guarantee is that the value of
a Restriction_Set attribute is known to be consistent throughout
all the code of a partition.

This is trivially achieved if the entire partition is compiled
with a consistent set of restriction pragmas. However, the
compilation model does not require this. It is possible to
compile one set of units with one set of pragmas, and another
set of units with another set of pragmas. It is even possible
to compile a spec with one set of pragmas, and then WITH the
same spec with a different set of pragmas. Inconsistencies
in the actual use of the restriction are checked at bind time.

In order to achieve the guarantee of consistency for the
Restriction_Set pragma, we consider that a use of the pragma
that yields False is equivalent to a violation of the
restriction.

So for example if you write

.. code-block:: ada

  if System'Restriction_Set (No_Floating_Point) then
     ...
  else
     ...
  end if;


And the result is False, so that the else branch is executed,
you can assume that this restriction is not set for any unit
in the partition. This is checked by considering this use of
the restriction pragma to be a violation of the restriction
No_Floating_Point. This means that no other unit can attempt
to set this restriction (if some unit does attempt to set it,
the binder will refuse to bind the partition).

Technical note: The restriction name and the unit name are
interpreted entirely syntactically, as in the corresponding
Restrictions pragma, they are not analyzed semantically,
so they do not have a type.

Attribute Result
================
.. index:: Result

``function'Result`` can only be used with in a Postcondition pragma
for a function. The prefix must be the name of the corresponding function. This
is used to refer to the result of the function in the postcondition expression.
For a further discussion of the use of this attribute and examples of its use,
see the description of pragma Postcondition.

Attribute Round
=====================
.. index:: Round

In addition to the usage of this attribute in the Ada RM, GNAT
also permits the use of the ``'Round`` attribute for ordinary
fixed point types.

Attribute Safe_Emax
===================
.. index:: Ada 83 attributes

.. index:: Safe_Emax

The ``Safe_Emax`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

Attribute Safe_Large
====================
.. index:: Ada 83 attributes

.. index:: Safe_Large

The ``Safe_Large`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

Attribute Safe_Small
====================
.. index:: Ada 83 attributes

.. index:: Safe_Small

The ``Safe_Small`` attribute is provided for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute.

.. _Attribute-Scalar_Storage_Order:

Attribute Scalar_Storage_Order
==============================
.. index:: Endianness

.. index:: Scalar storage order

.. index:: Scalar_Storage_Order

For every array or record type ``S``, the representation attribute
``Scalar_Storage_Order`` denotes the order in which storage elements
that make up scalar components are ordered within S. The value given must
be a static expression of type System.Bit_Order. The following is an example
of the use of this feature:

.. code-block:: ada

     --  Component type definitions

     subtype Yr_Type is Natural range 0 .. 127;
     subtype Mo_Type is Natural range 1 .. 12;
     subtype Da_Type is Natural range 1 .. 31;

     --  Record declaration

     type Date is record
        Years_Since_1980 : Yr_Type;
        Month            : Mo_Type;
        Day_Of_Month     : Da_Type;
     end record;

     --  Record representation clause

     for Date use record
        Years_Since_1980 at 0 range 0  ..  6;
        Month            at 0 range 7  .. 10;
        Day_Of_Month     at 0 range 11 .. 15;
     end record;

     --  Attribute definition clauses

     for Date'Bit_Order use System.High_Order_First;
     for Date'Scalar_Storage_Order use System.High_Order_First;
     --  If Scalar_Storage_Order is specified, it must be consistent with
     --  Bit_Order, so it's best to always define the latter explicitly if
     --  the former is used.


Other properties are as for the standard representation attribute ``Bit_Order``
defined by Ada RM 13.5.3(4). The default is ``System.Default_Bit_Order``.

For a record type ``T``, if ``T'Scalar_Storage_Order`` is
specified explicitly, it shall be equal to ``T'Bit_Order``. Note:
this means that if a ``Scalar_Storage_Order`` attribute definition
clause is not confirming, then the type's ``Bit_Order`` shall be
specified explicitly and set to the same value.

Derived types inherit an explicitly set scalar storage order from their parent
types. This may be overridden for the derived type by giving an explicit scalar
storage order for it. However, for a record extension, the derived type must
have the same scalar storage order as the parent type.

A component of a record type that is itself a record or an array and that does
not start and end on a byte boundary must have have the same scalar storage
order as the record type. A component of a bit-packed array type that is itself
a record or an array must have the same scalar storage order as the array type.

No component of a type that has an explicit ``Scalar_Storage_Order``
attribute definition may be aliased.

A confirming ``Scalar_Storage_Order`` attribute definition clause (i.e.
with a value equal to ``System.Default_Bit_Order``) has no effect.

If the opposite storage order is specified, then whenever the value of
a scalar component of an object of type ``S`` is read, the storage
elements of the enclosing machine scalar are first reversed (before
retrieving the component value, possibly applying some shift and mask
operations on the enclosing machine scalar), and the opposite operation
is done for writes.

In that case, the restrictions set forth in 13.5.1(10.3/2) for scalar components
are relaxed. Instead, the following rules apply:

* the underlying storage elements are those at positions
  ``(position + first_bit / storage_element_size) .. (position + (last_bit + storage_element_size - 1) / storage_element_size)``
* the sequence of underlying storage elements shall have
  a size no greater than the largest machine scalar
* the enclosing machine scalar is defined as the smallest machine
  scalar starting at a position no greater than
  ``position + first_bit / storage_element_size`` and covering
  storage elements at least up to ``position + (last_bit + storage_element_size - 1) / storage_element_size``
* the position of the component is interpreted relative to that machine
  scalar.

If no scalar storage order is specified for a type (either directly, or by
inheritance in the case of a derived type), then the default is normally
the native ordering of the target, but this default can be overridden using
pragma ``Default_Scalar_Storage_Order``.

If a component of ``T`` is itself of a record or array type, the specified
``Scalar_Storage_Order`` does *not* apply to that nested type: an explicit
attribute definition clause must be provided for the component type as well
if desired.

Representation changes that explicitly or implicitly toggle the scalar storage
order are not supported and may result in erroneous execution of the program,
except when performed by means of an instance of ``Ada.Unchecked_Conversion``.

In particular, overlays are not supported and a warning is given for them:

.. code-block:: ada

     type Rec_LE is record
        I : Integer;
     end record;

     for Rec_LE use record
        I at 0 range 0 .. 31;
     end record;

     for Rec_LE'Bit_Order use System.Low_Order_First;
     for Rec_LE'Scalar_Storage_Order use System.Low_Order_First;

     type Rec_BE is record
        I : Integer;
     end record;

     for Rec_BE use record
        I at 0 range 0 .. 31;
     end record;

     for Rec_BE'Bit_Order use System.High_Order_First;
     for Rec_BE'Scalar_Storage_Order use System.High_Order_First;

     R_LE : Rec_LE;

     R_BE : Rec_BE;
     for R_BE'Address use R_LE'Address;

``warning: overlay changes scalar storage order [enabled by default]``

In most cases, such representation changes ought to be replaced by an
instantiation of a function or procedure provided by ``GNAT.Byte_Swapping``.

Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.

Note that debuggers may be unable to display the correct value of scalar
components of a type for which the opposite storage order is specified.

.. _Attribute_Simple_Storage_Pool:

Attribute Simple_Storage_Pool
=============================
.. index:: Storage pool, simple

.. index:: Simple storage pool

.. index:: Simple_Storage_Pool

For every nonformal, nonderived access-to-object type ``Acc``, the
representation attribute ``Simple_Storage_Pool`` may be specified
via an attribute_definition_clause (or by specifying the equivalent aspect):

.. code-block:: ada

  My_Pool : My_Simple_Storage_Pool_Type;

  type Acc is access My_Data_Type;

  for Acc'Simple_Storage_Pool use My_Pool;



The name given in an attribute_definition_clause for the
``Simple_Storage_Pool`` attribute shall denote a variable of
a 'simple storage pool type' (see pragma `Simple_Storage_Pool_Type`).

The use of this attribute is only allowed for a prefix denoting a type
for which it has been specified. The type of the attribute is the type
of the variable specified as the simple storage pool of the access type,
and the attribute denotes that variable.

It is illegal to specify both ``Storage_Pool`` and ``Simple_Storage_Pool``
for the same access type.

If the ``Simple_Storage_Pool`` attribute has been specified for an access
type, then applying the ``Storage_Pool`` attribute to the type is flagged
with a warning and its evaluation raises the exception ``Program_Error``.

If the Simple_Storage_Pool attribute has been specified for an access
type ``S``, then the evaluation of the attribute ``S'Storage_Size``
returns the result of calling ``Storage_Size (S'Simple_Storage_Pool)``,
which is intended to indicate the number of storage elements reserved for
the simple storage pool. If the Storage_Size function has not been defined
for the simple storage pool type, then this attribute returns zero.

If an access type ``S`` has a specified simple storage pool of type
``SSP``, then the evaluation of an allocator for that access type calls
the primitive ``Allocate`` procedure for type ``SSP``, passing
``S'Simple_Storage_Pool`` as the pool parameter. The detailed
semantics of such allocators is the same as those defined for allocators
in section 13.11 of the :title:`Ada Reference Manual`, with the term
*simple storage pool* substituted for *storage pool*.

If an access type ``S`` has a specified simple storage pool of type
``SSP``, then a call to an instance of the ``Ada.Unchecked_Deallocation``
for that access type invokes the primitive ``Deallocate`` procedure
for type ``SSP``, passing ``S'Simple_Storage_Pool`` as the pool
parameter. The detailed semantics of such unchecked deallocations is the same
as defined in section 13.11.2 of the Ada Reference Manual, except that the
term *simple storage pool* is substituted for *storage pool*.

Attribute Small
===============
.. index:: Ada 83 attributes

.. index:: Small

The ``Small`` attribute is defined in Ada 95 (and Ada 2005) only for
fixed-point types.
GNAT also allows this attribute to be applied to floating-point types
for compatibility with Ada 83.  See
the Ada 83 reference manual for an exact description of the semantics of
this attribute when applied to floating-point types.

Attribute Small_Denominator
===========================
.. index:: Small

.. index:: Small_Denominator

``typ'Small_Denominator`` for any fixed-point subtype `typ` yields the
denominator in the representation of ``typ'Small`` as a rational number
with coprime factors (i.e. as an irreducible fraction).

Attribute Small_Numerator
=========================
.. index:: Small

.. index:: Small_Numerator

``typ'Small_Numerator`` for any fixed-point subtype `typ` yields the
numerator in the representation of ``typ'Small`` as a rational number
with coprime factors (i.e. as an irreducible fraction).

Attribute Storage_Unit
======================
.. index:: Storage_Unit

``Standard'Storage_Unit`` (``Standard`` is the only allowed
prefix) provides the same value as ``System.Storage_Unit``.

Attribute Stub_Type
===================
.. index:: Stub_Type

The GNAT implementation of remote access-to-classwide types is
organized as described in AARM section E.4 (20.t): a value of an RACW type
(designating a remote object) is represented as a normal access
value, pointing to a "stub" object which in turn contains the
necessary information to contact the designated remote object. A
call on any dispatching operation of such a stub object does the
remote call, if necessary, using the information in the stub object
to locate the target partition, etc.

For a prefix ``T`` that denotes a remote access-to-classwide type,
``T'Stub_Type`` denotes the type of the corresponding stub objects.

By construction, the layout of ``T'Stub_Type`` is identical to that of
type ``RACW_Stub_Type`` declared in the internal implementation-defined
unit ``System.Partition_Interface``. Use of this attribute will create
an implicit dependency on this unit.

Attribute System_Allocator_Alignment
====================================
.. index:: Alignment, allocator

.. index:: System_Allocator_Alignment

``Standard'System_Allocator_Alignment`` (``Standard`` is the only
allowed prefix) provides the observable guaranteed to be honored by
the system allocator (malloc). This is a static value that can be used
in user storage pools based on malloc either to reject allocation
with alignment too large or to enable a realignment circuitry if the
alignment request is larger than this value.

Attribute Target_Name
=====================
.. index:: Target_Name

``Standard'Target_Name`` (``Standard`` is the only allowed
prefix) provides a static string value that identifies the target
for the current compilation. For GCC implementations, this is the
standard gcc target name without the terminating slash (for
example, GNAT 5.0 on windows yields "i586-pc-mingw32msv").

Attribute To_Address
====================
.. index:: To_Address

The ``System'To_Address``
(``System`` is the only allowed prefix)
denotes a function identical to
``System.Storage_Elements.To_Address`` except that
it is a static attribute.  This means that if its argument is
a static expression, then the result of the attribute is a
static expression.  This means that such an expression can be
used in contexts (e.g., preelaborable packages) which require a
static expression and where the function call could not be used
(since the function call is always nonstatic, even if its
argument is static). The argument must be in the range
-(2**(m-1)) .. 2**m-1, where m is the memory size
(typically 32 or 64). Negative values are interpreted in a
modular manner (e.g., -1 means the same as 16#FFFF_FFFF# on
a 32 bits machine).

Attribute To_Any
================
.. index:: To_Any

This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.

Attribute Type_Class
====================
.. index:: Type_Class

``typ'Type_Class`` for any type or subtype `typ` yields
the value of the type class for the full type of `typ`.  If
`typ` is a generic formal type, the value is the value for the
corresponding actual subtype.  The value of this attribute is of type
``System.Aux_DEC.Type_Class``, which has the following definition:

.. code-block:: ada

  type Type_Class is
    (Type_Class_Enumeration,
     Type_Class_Integer,
     Type_Class_Fixed_Point,
     Type_Class_Floating_Point,
     Type_Class_Array,
     Type_Class_Record,
     Type_Class_Access,
     Type_Class_Task,
     Type_Class_Address);


Protected types yield the value ``Type_Class_Task``, which thus
applies to all concurrent types.  This attribute is designed to
be compatible with the DEC Ada 83 attribute of the same name.

Attribute Type_Key
==================
.. index:: Type_Key

The ``Type_Key`` attribute is applicable to a type or subtype and
yields a value of type Standard.String containing encoded information
about the type or subtype. This provides improved compatibility with
other implementations that support this attribute.

Attribute TypeCode
==================
.. index:: TypeCode

This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.

Attribute Unconstrained_Array
=============================
.. index:: Unconstrained_Array

The ``Unconstrained_Array`` attribute can be used with a prefix that
denotes any type or subtype. It is a static attribute that yields
``True`` if the prefix designates an unconstrained array,
and ``False`` otherwise. In a generic instance, the result is
still static, and yields the result of applying this test to the
generic actual.

Attribute Universal_Literal_String
==================================
.. index:: Named numbers, representation of

.. index:: Universal_Literal_String

The prefix of ``Universal_Literal_String`` must be a named
number.  The static result is the string consisting of the characters of
the number as defined in the original source.  This allows the user
program to access the actual text of named numbers without intermediate
conversions and without the need to enclose the strings in quotes (which
would preclude their use as numbers).

For example, the following program prints the first 50 digits of pi:

.. code-block:: ada

  with Text_IO; use Text_IO;
  with Ada.Numerics;
  procedure Pi is
  begin
     Put (Ada.Numerics.Pi'Universal_Literal_String);
  end;


Attribute Unrestricted_Access
=============================
.. index:: Access, unrestricted

.. index:: Unrestricted_Access

The ``Unrestricted_Access`` attribute is similar to ``Access``
except that all accessibility and aliased view checks are omitted.  This
is a user-beware attribute.

For objects, it is similar to ``Address``, for which it is a
desirable replacement where the value desired is an access type.
In other words, its effect is similar to first applying the
``Address`` attribute and then doing an unchecked conversion to a
desired access type.

For subprograms, ``P'Unrestricted_Access`` may be used where
``P'Access`` would be illegal, to construct a value of a
less-nested named access type that designates a more-nested
subprogram. This value may be used in indirect calls, so long as the
more-nested subprogram still exists; once the subprogram containing it
has returned, such calls are erroneous. For example:

.. code-block:: ada

  package body P is

     type Less_Nested is access procedure;
     Global : Less_Nested;

     procedure P1 is
     begin
        Global.all;
     end P1;

     procedure P2 is
        Local_Var : Integer;

        procedure More_Nested is
        begin
           ... Local_Var ...
        end More_Nested;
     begin
        Global := More_Nested'Unrestricted_Access;
        P1;
     end P2;

  end P;


When P1 is called from P2, the call via Global is OK, but if P1 were
called after P2 returns, it would be an erroneous use of a dangling
pointer.

For objects, it is possible to use ``Unrestricted_Access`` for any
type. However, if the result is of an access-to-unconstrained array
subtype, then the resulting pointer has the same scope as the context
of the attribute, and must not be returned to some enclosing scope.
For instance, if a function uses ``Unrestricted_Access`` to create
an access-to-unconstrained-array and returns that value to the caller,
the result will involve dangling pointers. In addition, it is only
valid to create pointers to unconstrained arrays using this attribute
if the pointer has the normal default 'fat' representation where a
pointer has two components, one points to the array and one points to
the bounds. If a size clause is used to force 'thin' representation
for a pointer to unconstrained where there is only space for a single
pointer, then the resulting pointer is not usable.

In the simple case where a direct use of Unrestricted_Access attempts
to make a thin pointer for a non-aliased object, the compiler will
reject the use as illegal, as shown in the following example:

.. code-block:: ada

  with System; use System;
  procedure SliceUA2 is
     type A is access all String;
     for A'Size use Standard'Address_Size;

     procedure P (Arg : A) is
     begin
        null;
     end P;

     X : String := "hello world!";
     X2 : aliased String := "hello world!";

     AV : A := X'Unrestricted_Access;    -- ERROR
               |
  >>> illegal use of Unrestricted_Access attribute
  >>> attempt to generate thin pointer to unaliased object

  begin
     P (X'Unrestricted_Access);          -- ERROR
        |
  >>> illegal use of Unrestricted_Access attribute
  >>> attempt to generate thin pointer to unaliased object

     P (X(7 .. 12)'Unrestricted_Access); -- ERROR
        |
  >>> illegal use of Unrestricted_Access attribute
  >>> attempt to generate thin pointer to unaliased object

     P (X2'Unrestricted_Access);         -- OK
  end;


but other cases cannot be detected by the compiler, and are
considered to be erroneous. Consider the following example:

.. code-block:: ada

  with System; use System;
  with System; use System;
  procedure SliceUA is
     type AF is access all String;

     type A is access all String;
     for A'Size use Standard'Address_Size;

     procedure P (Arg : A) is
     begin
        if Arg'Length /= 6 then
           raise Program_Error;
        end if;
     end P;

     X : String := "hello world!";
     Y : AF := X (7 .. 12)'Unrestricted_Access;

  begin
     P (A (Y));
  end;


A normal unconstrained array value
or a constrained array object marked as aliased has the bounds in memory
just before the array, so a thin pointer can retrieve both the data and
the bounds.  But in this case, the non-aliased object ``X`` does not have the
bounds before the string.  If the size clause for type ``A``
were not present, then the pointer
would be a fat pointer, where one component is a pointer to the bounds,
and all would be well.  But with the size clause present, the conversion from
fat pointer to thin pointer in the call loses the bounds, and so this
is erroneous, and the program likely raises a ``Program_Error`` exception.

In general, it is advisable to completely
avoid mixing the use of thin pointers and the use of
``Unrestricted_Access`` where the designated type is an
unconstrained array.  The use of thin pointers should be restricted to
cases of porting legacy code that implicitly assumes the size of pointers,
and such code should not in any case be using this attribute.

Another erroneous situation arises if the attribute is
applied to a constant. The resulting pointer can be used to access the
constant, but the effect of trying to modify a constant in this manner
is not well-defined. Consider this example:

.. code-block:: ada

  P : constant Integer := 4;
  type R is access all Integer;
  RV : R := P'Unrestricted_Access;
  ..
  RV.all := 3;


Here we attempt to modify the constant P from 4 to 3, but the compiler may
or may not notice this attempt, and subsequent references to P may yield
either the value 3 or the value 4 or the assignment may blow up if the
compiler decides to put P in read-only memory. One particular case where
``Unrestricted_Access`` can be used in this way is to modify the
value of an ``in`` parameter:

.. code-block:: ada

  procedure K (S : in String) is
     type R is access all Character;
     RV : R := S (3)'Unrestricted_Access;
  begin
     RV.all := 'a';
  end;


In general this is a risky approach. It may appear to "work" but such uses of
``Unrestricted_Access`` are potentially non-portable, even from one version
of GNAT to another, so are best avoided if possible.

Attribute Update
================
.. index:: Update

The ``Update`` attribute creates a copy of an array or record value
with one or more modified components. The syntax is::

  PREFIX'Update ( RECORD_COMPONENT_ASSOCIATION_LIST )
  PREFIX'Update ( ARRAY_COMPONENT_ASSOCIATION {, ARRAY_COMPONENT_ASSOCIATION } )
  PREFIX'Update ( MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION
                  {, MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION } )

  MULTIDIMENSIONAL_ARRAY_COMPONENT_ASSOCIATION ::= INDEX_EXPRESSION_LIST_LIST => EXPRESSION
  INDEX_EXPRESSION_LIST_LIST                   ::= INDEX_EXPRESSION_LIST {| INDEX_EXPRESSION_LIST }
  INDEX_EXPRESSION_LIST                        ::= ( EXPRESSION {, EXPRESSION } )


where ``PREFIX`` is the name of an array or record object, the
association list in parentheses does not contain an ``others``
choice and the box symbol ``<>`` may not appear in any
expression. The effect is to yield a copy of the array or record value
which is unchanged apart from the components mentioned in the
association list, which are changed to the indicated value. The
original value of the array or record value is not affected. For
example:

.. code-block:: ada

  type Arr is Array (1 .. 5) of Integer;
  ...
  Avar1 : Arr := (1,2,3,4,5);
  Avar2 : Arr := Avar1'Update (2 => 10, 3 .. 4 => 20);


yields a value for ``Avar2`` of 1,10,20,20,5 with ``Avar1``
begin unmodified. Similarly:

.. code-block:: ada

  type Rec is A, B, C : Integer;
  ...
  Rvar1 : Rec := (A => 1, B => 2, C => 3);
  Rvar2 : Rec := Rvar1'Update (B => 20);


yields a value for ``Rvar2`` of (A => 1, B => 20, C => 3),
with ``Rvar1`` being unmodified.
Note that the value of the attribute reference is computed
completely before it is used. This means that if you write:

.. code-block:: ada

  Avar1 := Avar1'Update (1 => 10, 2 => Function_Call);


then the value of ``Avar1`` is not modified if ``Function_Call``
raises an exception, unlike the effect of a series of direct assignments
to elements of ``Avar1``. In general this requires that
two extra complete copies of the object are required, which should be
kept in mind when considering efficiency.

The ``Update`` attribute cannot be applied to prefixes of a limited
type, and cannot reference discriminants in the case of a record type.
The accessibility level of an Update attribute result object is defined
as for an aggregate.

In the record case, no component can be mentioned more than once. In
the array case, two overlapping ranges can appear in the association list,
in which case the modifications are processed left to right.

Multi-dimensional arrays can be modified, as shown by this example:

.. code-block:: ada

  A : array (1 .. 10, 1 .. 10) of Integer;
  ..
  A := A'Update ((1, 2) => 20, (3, 4) => 30);


which changes element (1,2) to 20 and (3,4) to 30.

Attribute Valid_Value
=======================
.. index:: Valid_Value

The ``'Valid_Value`` attribute is defined for enumeration types other than
those in package Standard or types derived from those types. This attribute is
a function that takes a String, and returns Boolean. ``T'Valid_Value (S)``
returns True if and only if ``T'Value (S)`` would not raise Constraint_Error.

Attribute Valid_Scalars
=======================
.. index:: Valid_Scalars

The ``'Valid_Scalars`` attribute is intended to make it easier to check the
validity of scalar subcomponents of composite objects. The attribute is defined
for any prefix ``P`` which denotes an object. Prefix ``P`` can be any type
except for ``Unchecked_Union`` types. The value of the attribute is of type
``Boolean``.

``P'Valid_Scalars`` yields ``True`` if and only if the evaluation of
``C'Valid`` yields ``True`` for every scalar subcomponent ``C`` of ``P``, or if
``P`` has no scalar subcomponents. Attribute ``'Valid_Scalars`` is equivalent
to attribute ``'Valid`` for scalar types.

It is not specified in what order the subcomponents are checked, nor whether
any more are checked after any one of them is determined to be invalid. If the
prefix ``P`` is of a class-wide type ``T'Class`` (where ``T`` is the associated
specific type), or if the prefix ``P`` is of a specific tagged type ``T``, then
only the subcomponents of ``T`` are checked; in other words, components of
extensions of ``T`` are not checked even if ``T'Class (P)'Tag /= T'Tag``.

The compiler will issue a warning if it can be determined at compile time that
the prefix of the attribute has no scalar subcomponents.

Note: ``Valid_Scalars`` can generate a lot of code, especially in the case of
a large variant record. If the attribute is called in many places in the same
program applied to objects of the same type, it can reduce program size to
write a function with a single use of the attribute, and then call that
function from multiple places.

Attribute VADS_Size
===================
.. index:: Size, VADS compatibility

.. index:: VADS_Size

The ``'VADS_Size`` attribute is intended to make it easier to port
legacy code which relies on the semantics of ``'Size`` as implemented
by the VADS Ada 83 compiler.  GNAT makes a best effort at duplicating the
same semantic interpretation.  In particular, ``'VADS_Size`` applied
to a predefined or other primitive type with no Size clause yields the
Object_Size (for example, ``Natural'Size`` is 32 rather than 31 on
typical machines).  In addition ``'VADS_Size`` applied to an object
gives the result that would be obtained by applying the attribute to
the corresponding type.

.. _Attribute-Value_Size:

Attribute Value_Size
====================
.. index:: Size, setting for not-first subtype

.. index:: Value_Size

``type'Value_Size`` is the number of bits required to represent
a value of the given subtype.  It is the same as ``type'Size``,
but, unlike ``Size``, may be set for non-first subtypes.

Attribute Wchar_T_Size
======================
.. index:: Wchar_T_Size

``Standard'Wchar_T_Size`` (``Standard`` is the only allowed
prefix) provides the size in bits of the C ``wchar_t`` type
primarily for constructing the definition of this type in
package ``Interfaces.C``. The result is a static constant.

Attribute Word_Size
===================
.. index:: Word_Size

``Standard'Word_Size`` (``Standard`` is the only allowed
prefix) provides the value ``System.Word_Size``. The result is
a static constant.

---

### Gcc Ada Doc Gnat Rm Implementation Defined Characteristics (`gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst`)

.. _Implementation_Defined_Characteristics:

**************************************
Implementation Defined Characteristics
**************************************

In addition to the implementation dependent pragmas and attributes, and the
implementation advice, there are a number of other Ada features that are
potentially implementation dependent and are designated as
implementation-defined. These are mentioned throughout the Ada Reference
Manual, and are summarized in Annex M.

A requirement for conforming Ada compilers is that they provide
documentation describing how the implementation deals with each of these
issues.  In this chapter you will find each point in Annex M listed,
followed by a description of how GNAT handles the implementation dependence.

You can use this chapter as a guide to minimizing implementation
dependent features in your programs if portability to other compilers
and other operating systems is an important consideration.  The numbers
in each entry below correspond to the paragraph numbers in the Ada
Reference Manual.

*
  "Whether or not each recommendation given in Implementation
  Advice is followed.  See 1.1.2(37)."

See :ref:`Implementation_Advice`.

*
  "Capacity limitations of the implementation.  See 1.1.3(3)."

The complexity of programs that can be processed is limited only by the
total amount of available virtual memory, and disk space for the
generated object files.

*
  "Variations from the standard that are impractical to avoid
  given the implementation's execution environment.  See 1.1.3(6)."

There are no variations from the standard.

*
  "Which code_statements cause external
  interactions.  See 1.1.3(10)."

Any *code_statement* can potentially cause external interactions.

*
  "The coded representation for the text of an Ada
  program.  See 2.1(4)."

See separate section on source representation.

*
  "The semantics of an Ada program whose text is not in
  Normalization Form C.  See 2.1(4)."

See separate section on source representation.

*
  "The representation for an end of line.  See 2.2(2)."

See separate section on source representation.

*
  "Maximum supported line length and lexical element
  length.  See 2.2(15)."

The maximum line length is 255 characters and the maximum length of
a lexical element is also 255 characters. This is the default setting
if not overridden by the use of compiler switch *-gnaty* (which
sets the maximum to 79) or *-gnatyMnn* which allows the maximum
line length to be specified to be any value up to 32767. The maximum
length of a lexical element is the same as the maximum line length.

*
  "Implementation defined pragmas.  See 2.8(14)."

See :ref:`Implementation_Defined_Pragmas`.

*
  "Effect of pragma ``Optimize``.  See 2.8(27)."

Pragma ``Optimize``, if given with a ``Time`` or ``Space``
parameter, checks that the optimization flag is set, and aborts if it is
not.

*
  "The message string associated with the Assertion_Error exception raised
  by the failure of a predicate check if there is no applicable
  Predicate_Failure aspect.  See 3.2.4(31)."

In the case of a Dynamic_Predicate aspect, the string is
"Dynamic_Predicate failed at <source position>", where
"<source position>" might be something like "foo.adb:123".
The Static_Predicate case is handled analogously.

*
  "The predefined integer types declared in
  ``Standard``.  See 3.5.4(25)."

.. tabularcolumns:: |l|L|

========================= =======================================
Type                       Representation
========================= =======================================
*Short_Short_Integer*      8-bit signed
*Short_Integer*            16-bit signed
*Integer*                  32-bit signed
*Long_Integer*             64-bit signed (on most 64-bit targets,
                           depending on the C definition of long)
                           32-bit signed (on all other targets)
*Long_Long_Integer*        64-bit signed
*Long_Long_Long_Integer*   128-bit signed (on 64-bit targets)
                           64-bit signed (on 32-bit targets)
========================= =======================================

*
  "Any nonstandard integer types and the operators defined
  for them.  See 3.5.4(26)."

There are no nonstandard integer types.

*
  "Any nonstandard real types and the operators defined for
  them.  See 3.5.6(8)."

There are no nonstandard real types.

*
  "What combinations of requested decimal precision and range
  are supported for floating point types.  See 3.5.7(7)."

The precision and range are defined by the IEEE Standard for Floating-Point
Arithmetic (IEEE 754-2019).

*
  "The predefined floating point types declared in
  ``Standard``.  See 3.5.7(16)."

====================== ===============================================
Type                   Representation
====================== ===============================================
*Short_Float*          IEEE Binary32 (Single)
*Float*                IEEE Binary32 (Single)
*Long_Float*           IEEE Binary64 (Double)
*Long_Long_Float*      IEEE Binary64 (Double) on non-x86 architectures
                       IEEE 80-bit Extended on x86 architecture
====================== ===============================================

The default rounding mode specified by the IEEE 754 Standard is assumed both
for static and dynamic computations (that is, round to nearest, ties to even).
The input routines yield correctly rounded values for Short_Float, Float, and
Long_Float at least. The output routines can compute up to twice as many exact
digits as the value of ``T'Digits`` for any type, for example 30 digits for
Long_Float; if more digits are requested, zeros are printed.

*
  "The small of an ordinary fixed point type.  See 3.5.9(8)."

The small is the largest power of two that does not exceed the delta.

*
  "What combinations of small, range, and digits are
  supported for fixed point types.  See 3.5.9(10)."

For an ordinary fixed point type, on 32-bit platforms, the small must lie in
2.0**(-80) .. 2.0**80 and the range in -9.0E+36 .. 9.0E+36; any combination
is permitted that does not result in a mantissa larger than 63 bits.

On 64-bit platforms, the small must lie in 2.0**(-127) .. 2.0**127 and the
range in -1.0E+76 .. 1.0E+76; any combination is permitted that does not
result in a mantissa larger than 63 bits, and any combination is permitted
that results in a mantissa between 64 and 127 bits if the small is the
ratio of two integers that lie in 1 .. 2.0**127.

If the small is the ratio of two integers with 64-bit magnitude on 32-bit
platforms and 128-bit magnitude on 64-bit platforms, which is the case if
no ``small`` clause is provided, then the operations of the fixed point
type are entirely implemented by means of integer instructions.  In the
other cases, some operations, in particular input and output, may be
implemented by means of floating-point instructions and may be affected
by accuracy issues on architectures other than x86.

For a decimal fixed point type, on 32-bit platforms, the small must lie in
1.0E-18 .. 1.0E+18 and the digits in 1 .. 18.  On 64-bit platforms, the
small must lie in 1.0E-38 .. 1.0E+38 and the digits in 1 .. 38.

*
  "The result of ``Tags.Expanded_Name`` for types declared
  within an unnamed *block_statement*.  See 3.9(10)."

Block numbers of the form :samp:`B{nnn}`, where *nnn* is a
decimal integer are allocated.

*
  "The sequence of characters of the value returned by Tags.Expanded_Name
  (respectively, Tags.Wide_Expanded_Name) when some of the graphic
  characters of Tags.Wide_Wide_Expanded_Name are not defined in Character
  (respectively, Wide_Character).  See 3.9(10.1)."

This is handled in the same way as the implementation-defined behavior
referenced in A.4.12(34).

*
  "Implementation-defined attributes.  See 4.1.4(12)."

See :ref:`Implementation_Defined_Attributes`.

*
  "The value of the parameter to Empty for some container aggregates.
  See 4.3.5(40)."

As per the suggestion given in the Annotated Ada RM, the default value
of the formal parameter is used if one exists and zero is used otherwise.

*
  "The maximum number of chunks for a parallel reduction expression without
  a chunk_specification.  See 4.5.10(21)."

Feature unimplemented.

*
  "Rounding of real static expressions which are exactly half-way between
  two machine numbers.  See 4.9(38)."

Round to even is used in all such cases.

*
  "The maximum number of chunks for a parallel generalized iterator without
  a chunk_specification.  See 5.5.2(10)."

Feature unimplemented.

*
  "The number of chunks for an array component iterator.  See 5.5.2(11)."

Feature unimplemented.

*
  "Any extensions of the Global aspect.  See 6.1.2(43)."

Feature unimplemented.

*
  "The circumstances the implementation passes in the null value for a view
  conversion of an access type used as an out parameter.  See 6.4.1(19)."

Difficult to characterize.

*
  "Any extensions of the Default_Initial_Condition aspect.  See 7.3.3(11)."

SPARK allows specifying *null* as the Default_Initial_Condition
aspect of a type. See the SPARK reference manual for further details.

*
  "Any implementation-defined time types.  See 9.6(6)."

There are no implementation-defined time types.

*
  "The time base associated with relative delays.  See 9.6(20)."

See 9.6(20).  The time base used is that provided by the C library
function ``gettimeofday``.

*
  "The time base of the type ``Calendar.Time``.  See 9.6(23)."

The time base used is that provided by the C library function
``gettimeofday``.

*
  "The time zone used for package ``Calendar``
  operations.  See 9.6(24)."

The time zone used by package ``Calendar`` is the current system time zone
setting for local time, as accessed by the C library function
``localtime``.

*
  "Any limit on *delay_until_statements* of
  *select_statements*.  See 9.6(29)."

There are no such limits.

*
  "The result of Calendar.Formatting.Image if its argument represents more
  than 100 hours.  See 9.6.1(86)."

Calendar.Time_Error is raised.

*
  "Implementation-defined conflict check policies.  See 9.10.1(5)."

There are no implementation-defined conflict check policies.

*
  "The representation for a compilation.  See 10.1(2)."

A compilation is represented by a sequence of files presented to the
compiler in a single invocation of the *gcc* command.

*
  "Any restrictions on compilations that contain multiple
  compilation_units.  See 10.1(4)."

No single file can contain more than one compilation unit, but any
sequence of files can be presented to the compiler as a single
compilation.

*
  "The mechanisms for creating an environment and for adding
  and replacing compilation units.  See 10.1.4(3)."

See separate section on compilation model.

*
  "The manner of explicitly assigning library units to a
  partition.  See 10.2(2)."

If a unit contains an Ada main program, then the Ada units for the partition
are determined by recursive application of the rules in the Ada Reference
Manual section 10.2(2-6).  In other words, the Ada units will be those that
are needed by the main program, and then this definition of need is applied
recursively to those units, and the partition contains the transitive
closure determined by this relationship.  In short, all the necessary units
are included, with no need to explicitly specify the list.  If additional
units are required, e.g., by foreign language units, then all units must be
mentioned in the context clause of one of the needed Ada units.

If the partition contains no main program, or if the main program is in
a language other than Ada, then GNAT
provides the binder options *-z* and *-n* respectively, and in
this case a list of units can be explicitly supplied to the binder for
inclusion in the partition (all units needed by these units will also
be included automatically).  For full details on the use of these
options, refer to *GNAT Make Program gnatmake* in the
:title:`GNAT User's Guide`.

*
  "The implementation-defined means, if any, of specifying which compilation
  units are needed by a given compilation unit.  See 10.2(2)."

The units needed by a given compilation unit are as defined in
the Ada Reference Manual section 10.2(2-6).  There are no
implementation-defined pragmas or other implementation-defined
means for specifying needed units.

*
  "The manner of designating the main subprogram of a
  partition.  See 10.2(7)."

The main program is designated by providing the name of the
corresponding :file:`ALI` file as the input parameter to the binder.

*
  "The order of elaboration of *library_items*.  See 10.2(18)."

The first constraint on ordering is that it meets the requirements of
Chapter 10 of the Ada Reference Manual.  This still leaves some
implementation-dependent choices, which are resolved by analyzing
the elaboration code of each unit and identifying implicit
elaboration-order dependencies.

*
  "Parameter passing and function return for the main
  subprogram.  See 10.2(21)."

The main program has no parameters.  It may be a procedure, or a function
returning an integer type.  In the latter case, the returned integer
value is the return code of the program (overriding any value that
may have been set by a call to ``Ada.Command_Line.Set_Exit_Status``).

*
  "The mechanisms for building and running partitions.  See 10.2(24)."

GNAT itself supports programs with only a single partition. The PolyORB product (which also includes an implementation of the PCS) provides a completely flexible method for building and running programs consisting of multiple partitions. **NB!** See the note in :ref:`polyORB` regarding the lifetime
of this product.

*
  "The details of program execution, including program
  termination.  See 10.2(25)."

See separate section on compilation model.

*
  "The semantics of any non-active partitions supported by the
  implementation.  See 10.2(28)."

Passive partitions are supported on targets where shared memory is
provided by the operating system. **NB!** See the note in :ref:`polyORB` regarding the lifetime of this product.

*
  "The information returned by ``Exception_Message``.  See 11.4.1(10)."

Exception message returns the null string unless a specific message has
been passed by the program.

*
  "The result of ``Exceptions.Exception_Name`` for types
  declared within an unnamed *block_statement*.  See 11.4.1(12)."

Blocks have implementation defined names of the form :samp:`B{nnn}`
where *nnn* is an integer.

*
  "The information returned by
  ``Exception_Information``.  See 11.4.1(13)."

``Exception_Information`` returns a string in the following format::

  *Exception_Name:* nnnnn
  *Message:* mmmmm
  *PID:* ppp
  *Load address:* 0xhhhh
  *Call stack traceback locations:*
  0xhhhh 0xhhhh 0xhhhh ... 0xhhh

where

  *  ``nnnn`` is the fully qualified name of the exception in all upper
     case letters. This line is always present.

  *  ``mmmm`` is the message (this line present only if message is non-null)

  *  ``ppp`` is the Process Id value as a decimal integer (this line is
     present only if the Process Id is nonzero). Currently we are
     not making use of this field.

  *  The Load address line, the Call stack traceback locations line and the
     following values are present only if at least one traceback location was
     recorded. The Load address indicates the address at which the main executable
     was loaded; this line may not be present if operating system hasn't relocated
     the main executable. The values are given in C style format, with lower case
     letters for a-f, and only as many digits present as are necessary.
     The line terminator sequence at the end of each line, including
     the last line is a single ``LF`` character (``16#0A#``).

*
  "The sequence of characters of the value returned by
  Exceptions.Exception_Name (respectively, Exceptions.Wide_Exception_Name)
  when some of the graphic characters of Exceptions.Wide_Wide_Exception_Name
  are not defined in Character (respectively, Wide_Character).
  See 11.4.1(12.1)."

This is handled in the same way as the implementation-defined behavior
referenced in A.4.12(34).

*
  "The information returned by Exception_Information.  See 11.4.1(13)."

The exception name and the source location at which the exception was
raised are included.

*
  "Implementation-defined policy_identifiers and assertion_aspect_marks
  allowed in a pragma Assertion_Policy.  See 11.4.2(9)."

Implementation-defined assertion_aspect_marks include Assert_And_Cut,
Assume, Contract_Cases, Debug, Ghost, Initial_Condition, Loop_Invariant,
Loop_Variant, Postcondition, Precondition, Predicate, Refined_Post,
Statement_Assertions, and Subprogram_Variant. Implementation-defined
policy_identifiers include Disable and Suppressible.

*
  "The default assertion policy.  See 11.4.2(10)."

The default assertion policy is Ignore, although this can be overridden
via compiler switches such as "-gnata".

*
  "Implementation-defined check names.  See 11.5(27)."

The implementation-defined check names include Alignment_Check,
Container_Checks, Duplicated_Tag_Check, Predicate_Check,
Raise_Check, Tampering_Check, and Validity_Check. In addition, a
user program can add implementation-defined check names by means
of the pragma Check_Name. See the description of pragma
``Suppress`` for details.

*
  "Existence and meaning of second parameter of pragma Unsuppress.
  See 11.5(27.1)."

The legality rules for and semantics of the second parameter of pragma
Unsuppress match those for the second argument of pragma Suppress.

*
  "The cases that cause conflicts between the representation of the
  ancestors of a type_declaration.  See 13.1(13.1)."

No such cases exist.

*
  "The interpretation of each representation aspect.  See 13.1(20)."

See separate section on data representations.

*
  "Any restrictions placed upon the specification of representation aspects.
  See 13.1(20)."

See separate section on data representations.

*
  "Implementation-defined aspects, including the syntax for specifying
  such aspects and the legality rules for such aspects.  See 13.1.1(38)."

See :ref:`Implementation_Defined_Aspects`.

*
  "The set of machine scalars.  See 13.3(8.1)."

See separate section on data representations.

*
  "The meaning of ``Size`` for indefinite subtypes.  See 13.3(48)."

The Size attribute of an indefinite subtype is not less than the Size
attribute of any object of that type.

*
  "The meaning of Object_Size for indefinite subtypes.  See 13.3(58)."

The Object_Size attribute of an indefinite subtype is not less than the
Object_Size attribute of any object of that type.

*
  "The default external representation for a type tag.  See 13.3(75)."

The default external representation for a type tag is the fully expanded
name of the type in upper case letters.

*
  "What determines whether a compilation unit is the same in
  two different partitions.  See 13.3(76)."

A compilation unit is the same in two different partitions if and only
if it derives from the same source file.

*
  "Implementation-defined components.  See 13.5.1(15)."

The only implementation defined component is the tag for a tagged type,
which contains a pointer to the dispatching table.

*
  "If ``Word_Size`` = ``Storage_Unit``, the default bit
  ordering.  See 13.5.3(5)."

``Word_Size`` does not equal ``Storage_Unit`` in this implementation.

*
  "The contents of the visible part of package ``System``.  See 13.7(2)."

See the definition of package System in :file:`system.ads`.
Note that two declarations are added to package System.

.. code-block:: ada

  Max_Priority           : constant Positive := Priority'Last;
  Max_Interrupt_Priority : constant Positive := Interrupt_Priority'Last;

*
  "The range of Storage_Elements.Storage_Offset, the modulus of
  Storage_Elements.Storage_Element, and the declaration of
  Storage_Elements.Integer_Address.  See 13.7.1(11)."

See the definition of package System.Storage_Elements in :file:`s-stoele.ads`.

*
  "The contents of the visible part of package ``System.Machine_Code``,
  and the meaning of *code_statements*.  See 13.8(7)."

See the definition and documentation in file :file:`s-maccod.ads`.

*
  "The result of unchecked conversion for instances with scalar result
  types whose result is not defined by the language.  See 13.9(11)."

Unchecked conversion between types of the same size
results in an uninterpreted transmission of the bits from one type
to the other.  If the types are of unequal sizes, then in the case of
discrete types, a shorter source is first zero or sign extended as
necessary, and a shorter target is simply truncated on the left.
For all non-discrete types, the source is first copied if necessary
to ensure that the alignment requirements of the target are met, then
a pointer is constructed to the source value, and the result is obtained
by dereferencing this pointer after converting it to be a pointer to the
target type. Unchecked conversions where the target subtype is an
unconstrained array are not permitted. If the target alignment is
greater than the source alignment, then a copy of the result is
made with appropriate alignment

*
  "The result of unchecked conversion for instances with nonscalar result
  types whose result is not defined by the language.  See 13.9(11)."

See preceding definition for the scalar result case.

*
  "Whether or not the implementation provides user-accessible
  names for the standard pool type(s).  See 13.11(17)."

There are 3 different standard pools used by the compiler when
``Storage_Pool`` is not specified depending whether the type is local
to a subprogram or defined at the library level and whether
``Storage_Size``is specified or not. See documentation in the runtime
library units ``System.Pool_Global``, ``System.Pool_Size`` and
``System.Pool_Local`` in files :file:`s-poosiz.ads`,
:file:`s-pooglo.ads` and :file:`s-pooloc.ads` for full details on the
default pools used.  All these pools are accessible by means of `with`\ ing
these units.

*
  "The meaning of ``Storage_Size`` when neither the Storage_Size nor the
  Storage_Pool is specified for an access type.  See 13.11(18)."

``Storage_Size`` is measured in storage units, and refers to the
total space available for an access type collection, or to the primary
stack space for a task.

*
  "The effect of specifying aspect Default_Storage_Pool on an instance
  of a language-defined generic unit.  See 13.11.3(5)."

Instances of language-defined generic units are treated the same as other
instances with respect to the Default_Storage_Pool aspect.

*
  "Implementation-defined restrictions allowed in a pragma
  ``Restrictions``.  See 13.12(8.7)."

See :ref:`Standard_and_Implementation_Defined_Restrictions`.

*
  "The consequences of violating limitations on
  ``Restrictions`` pragmas.  See 13.12(9)."

Restrictions that can be checked at compile time are enforced at
compile time; violations are illegal. For other restrictions, any
violation during program execution results in erroneous execution.

*
  "Implementation-defined usage profiles allowed in a pragma Profile.
  See 13.12(15)."

See :ref:`Implementation_Defined_Pragmas`.

*
  "The contents of the stream elements read and written by the Read and
  Write attributes of elementary types.  See 13.13.2(9)."

The representation is the in-memory representation of the base type of
the type, using the number of bits corresponding to the
``type'Size`` value, and the natural ordering of the machine.

*
  "The names and characteristics of the numeric subtypes
  declared in the visible part of package ``Standard``.  See A.1(3)."

See items describing the integer and floating-point types supported.

*
  "The values returned by Strings.Hash.  See A.4.9(3)."

This hash function has predictable collisions and is subject to
equivalent substring attacks. It is not suitable for construction of a
hash table keyed on possibly malicious user input.

*
  "The value returned by a call to a Text_Buffer Get procedure if any
  character in the returned sequence is not defined in Character.
  See A.4.12(34)."

The contents of a buffer is represented internally as a UTF_8 string.
The value return by Text_Buffer.Get is the result of passing that
UTF_8 string to UTF_Encoding.Strings.Decode.

*
  "The value returned by a call to a Text_Buffer Wide_Get procedure if
  any character in the returned sequence is not defined in Wide_Character.
  See A.4.12(34)."

The contents of a buffer is represented internally as a UTF_8 string.
The value return by Text_Buffer.Wide_Get is the result of passing that
UTF_8 string to UTF_Encoding.Wide_Strings.Decode.

*
  "The accuracy actually achieved by the elementary
  functions.  See A.5.1(1)."

The elementary functions correspond to the functions available in the C
library.  Only fast math mode is implemented.

*
  "The sign of a zero result from some of the operators or
  functions in ``Numerics.Generic_Elementary_Functions``, when
  ``Float_Type'Signed_Zeros`` is ``True``.  See A.5.1(46)."

The sign of zeroes follows the requirements of the IEEE 754 standard on
floating-point.

*
  "The value of
  ``Numerics.Float_Random.Max_Image_Width``.  See A.5.2(27)."

Maximum image width is 6864, see library file :file:`s-rannum.ads`.

*
  "The value of
  ``Numerics.Discrete_Random.Max_Image_Width``.  See A.5.2(27)."

Maximum image width is 6864, see library file :file:`s-rannum.ads`.

*
  "The string representation of a random number generator's
  state.  See A.5.2(38)."

The value returned by the Image function is the concatenation of
the fixed-width decimal representations of the 624 32-bit integers
of the state vector.

*
  "The values of the ``Model_Mantissa``,
  ``Model_Emin``, ``Model_Epsilon``, ``Model``,
  ``Safe_First``, and ``Safe_Last`` attributes, if the Numerics
  Annex is not supported.  See A.5.3(72)."

Running the compiler with *-gnatS* to produce a listing of package
``Standard`` displays the values of these attributes.

*
  "The value of ``Buffer_Size`` in ``Storage_IO``.  See A.9(10)."

All type representations are contiguous, and the ``Buffer_Size`` is
the value of ``type'Size`` rounded up to the next storage unit
boundary.

*
  "External files for standard input, standard output, and
  standard error See A.10(5)."

These files are mapped onto the files provided by the C streams
libraries. See source file :file:`i-cstrea.ads` for further details.

*
  "The accuracy of the value produced by ``Put``.  See A.10.9(36)."

If more digits are requested in the output than are represented by the
precision of the value, zeroes are output in the corresponding least
significant digit positions.

*
  "Current size for a stream file for which positioning is not supported.
  See A.12.1(1.1)."

Positioning is supported.

*
  "The meaning of ``Argument_Count``, ``Argument``, and
  ``Command_Name``.  See A.15(1)."

These are mapped onto the ``argv`` and ``argc`` parameters of the
main program in the natural manner.

*
  "The interpretation of file names and directory names.  See A.16(46)."

These names are interpreted consistently with the underlying file system.

*
  "The maximum value for a file size in Directories.  See A.16(87)."

Directories.File_Size'Last is equal to Long_Long_Integer'Last .

*
  "The result for Directories.Size for a directory or special file.
  See A.16(93)."

Name_Error is raised.

*
  "The result for Directories.Modification_Time for a directory or special file.
  See A.16(93)."

Name_Error is raised.

*
  "The interpretation of a nonnull search pattern in Directories.
  See A.16(104)."

When the ``Pattern`` parameter is not the null string, it is interpreted
according to the syntax of regular expressions as defined in the
``GNAT.Regexp`` package.

See :ref:`GNAT.Regexp_(g-regexp.ads)`.

*
  "The results of a Directories search if the contents of the directory are
  altered while a search is in progress.  See A.16(110)."

The effect of a call to Get_Next_Entry is determined by the current
state of the directory.

*
  "The definition and meaning of an environment variable.  See A.17(1)."

This definition is determined by the underlying operating system.

*
  "The circumstances where an environment variable cannot be defined.
  See A.17(16)."

There are no such implementation-defined circumstances.

*
  "Environment names for which Set has the effect of Clear.  See A.17(17)."

There are no such names.

*
  "The value of Containers.Hash_Type'Modulus. The value of
  Containers.Count_Type'Last.  See A.18.1(7)."

Containers.Hash_Type'Modulus is 2**32.
Containers.Count_Type'Last is 2**31 - 1.

*
  "Implementation-defined convention names.  See B.1(11)."

The following convention names are supported

.. tabularcolumns:: |l|L|

======================= ==============================================================================
Convention Name         Interpretation
======================= ==============================================================================
*Ada*                   Ada
*Ada_Pass_By_Copy*      Allowed for any types except by-reference types such as limited
                        records. Compatible with convention Ada, but causes any parameters
                        with this convention to be passed by copy.
*Ada_Pass_By_Reference* Allowed for any types except by-copy types such as scalars.
                        Compatible with convention Ada, but causes any parameters
                        with this convention to be passed by reference.
*Assembler*             Assembly language
*Asm*                   Synonym for Assembler
*Assembly*              Synonym for Assembler
*C*                     C
*C_Pass_By_Copy*        Allowed only for record types, like C, but also notes that record
                        is to be passed by copy rather than reference.
*COBOL*                 COBOL
*C_Plus_Plus (or CPP)*  C++
*Default*               Treated the same as C
*External*              Treated the same as C
*Fortran*               Fortran
*Intrinsic*             For support of pragma ``Import`` with convention Intrinsic, see
                        separate section on Intrinsic Subprograms.
*Stdcall*               Stdcall (used for Windows implementations only).  This convention correspond
                        to the WINAPI (previously called Pascal convention) C/C++ convention under
                        Windows.  A routine with this convention cleans the stack before
                        exit. This pragma cannot be applied to a dispatching call.
*DLL*                   Synonym for Stdcall
*Win32*                 Synonym for Stdcall
*Stubbed*               Stubbed is a special convention used to indicate that the body of the
                        subprogram will be entirely ignored.  Any call to the subprogram
                        is converted into a raise of the ``Program_Error`` exception.  If a
                        pragma ``Import`` specifies convention ``stubbed`` then no body need
                        be present at all.  This convention is useful during development for the
                        inclusion of subprograms whose body has not yet been written.
                        In addition, all otherwise unrecognized convention names are also
                        treated as being synonymous with convention C.  In all implementations,
                        use of such other names results in a warning.
======================= ==============================================================================

*
  "The meaning of link names.  See B.1(36)."

Link names are the actual names used by the linker.

*
  "The manner of choosing link names when neither the link name nor the
  address of an imported or exported entity is specified.  See B.1(36)."

The default linker name is that which would be assigned by the relevant
external language, interpreting the Ada name as being in all lower case
letters.

*
  "The effect of pragma ``Linker_Options``.  See B.1(37)."

The string passed to ``Linker_Options`` is presented uninterpreted as
an argument to the link command, unless it contains ASCII.NUL characters.
NUL characters if they appear act as argument separators, so for example

.. code-block:: ada

  pragma Linker_Options ("-labc" & ASCII.NUL & "-ldef");

causes two separate arguments ``-labc`` and ``-ldef`` to be passed to the
linker. The order of linker options is preserved for a given unit. The final
list of options passed to the linker is in reverse order of the elaboration
order. For example, linker options for a body always appear before the options
from the corresponding package spec.

*
  "The contents of the visible part of package
  ``Interfaces`` and its language-defined descendants.  See B.2(1)."

See files with prefix :file:`i-` in the distributed library.

*
  "Implementation-defined children of package
  ``Interfaces``.  The contents of the visible part of package
  ``Interfaces``.  See B.2(11)."

See files with prefix :file:`i-` in the distributed library.

*
  "The definitions of certain types and constants in Interfaces.C.
  See B.3(41)."

See source file :file:`i-c.ads`.

*
  "The types ``Floating``, ``Long_Floating``,
  ``Binary``, ``Long_Binary``, ``Decimal_ Element``, and
  ``COBOL_Character``; and the initialization of the variables
  ``Ada_To_COBOL`` and ``COBOL_To_Ada``, in
  ``Interfaces.COBOL``.  See B.4(50)."

===================== ====================================
COBOL                 Ada
===================== ====================================
*Floating*            Float
*Long_Floating*       (Floating) Long_Float
*Binary*              Integer
*Long_Binary*         Long_Long_Integer
*Decimal_Element*     Character
*COBOL_Character*     Character
===================== ====================================

For initialization, see the file :file:`i-cobol.ads` in the distributed library.

*
  "The types Fortran_Integer, Real, Double_Precision, and Character_Set
  in Interfaces.Fortran.  See B.5(17)."

See source file :file:`i-fortra.ads`. These types are derived, respectively,
from Integer, Float, Long_Float, and Character.

*
  "Implementation-defined intrinsic subprograms.  See C.1(1)."

See separate section on Intrinsic Subprograms.

*
  "Any restrictions on a protected procedure or its containing type when an
  aspect Attach_handler or Interrupt_Handler is specified.  See C.3.1(17)."

There are no such restrictions.

*
  "Any other forms of interrupt handler supported by the Attach_Handler and
  Interrupt_Handler aspects.  See C.3.1(19)."

There are no such forms.

*
  "The semantics of some attributes and functions of an entity for which
  aspect Discard_Names is True.  See C.5(7)."

If Discard_Names is True for an enumeration type, the Image attribute
provides the image of the Pos of the literal, and Value accepts
Pos values.

If both of the aspects``Discard_Names`` and ``No_Tagged_Streams`` are true
for a tagged type, its Expanded_Name and External_Tag values are
empty strings. This is useful to avoid exposing entity names at binary
level.

*
  "The modulus and size of Test_and_Set_Flag.  See C.6.3(8)."

The modulus is 2**8. The size is 8.

*
  "The value used to represent the set value for Atomic_Test_and_Set.
  See C.6.3(10)."

The value is 1.

*
  "The result of the ``Task_Identification.Image``
  attribute.  See C.7.1(7)."

The result of this attribute is a string that identifies
the object or component that denotes a given task. If a variable ``Var``
has a task type, the image for this task will have the form :samp:`Var_{XXXXXXXX}`,
where the suffix *XXXXXXXX*
is the hexadecimal representation of the virtual address of the corresponding
task control block. If the variable is an array of tasks, the image of each
task will have the form of an indexed component indicating the position of a
given task in the array, e.g., :samp:`Group(5)_{XXXXXXX}`. If the task is a
component of a record, the image of the task will have the form of a selected
component. These rules are fully recursive, so that the image of a task that
is a subcomponent of a composite object corresponds to the expression that
designates this task.

If a task is created by an allocator, its image depends on the context. If the
allocator is part of an object declaration, the rules described above are used
to construct its image, and this image is not affected by subsequent
assignments. If the allocator appears within an expression, the image
includes only the name of the task type.

If the configuration pragma Discard_Names is present, or if the restriction
No_Implicit_Heap_Allocation is in effect,  the image reduces to
the numeric suffix, that is to say the hexadecimal representation of the
virtual address of the control block of the task.

*
  "The value of ``Current_Task`` when in a protected entry
  or interrupt handler.  See C.7.1(17)."

Protected entries or interrupt handlers can be executed by any
convenient thread, so the value of ``Current_Task`` is undefined.

*
  "Granularity of locking for Task_Attributes.  See C.7.2(16)."

No locking is needed if the formal type Attribute has the size and
alignment of either Integer or System.Address and the bit representation
of Initial_Value is all zeroes. Otherwise, locking is performed.

*
  "The declarations of ``Any_Priority`` and
  ``Priority``.  See D.1(11)."

See declarations in file :file:`system.ads`.

*
  "Implementation-defined execution resources.  See D.1(15)."

There are no implementation-defined execution resources.

*
  "Whether, on a multiprocessor, a task that is waiting for
  access to a protected object keeps its processor busy.  See D.2.1(3)."

On a multi-processor, a task that is waiting for access to a protected
object does not keep its processor busy.

*
  "The affect of implementation defined execution resources
  on task dispatching.  See D.2.1(9)."

Tasks map to threads in the threads package used by GNAT.  Where possible
and appropriate, these threads correspond to native threads of the
underlying operating system.

*
  "Implementation-defined task dispatching policies.  See D.2.2(3)."

There are no implementation-defined task dispatching policies.

*
  "The value of Default_Quantum in Dispatching.Round_Robin.  See D.2.5(4)."

The value is 10 milliseconds.

*
  "Implementation-defined *policy_identifiers* allowed
  in a pragma ``Locking_Policy``.  See D.3(4)."

The two implementation defined policies permitted in GNAT are
``Inheritance_Locking`` and  ``Concurrent_Readers_Locking``. On
targets that support the ``Inheritance_Locking`` policy, locking is
implemented by inheritance, i.e., the task owning the lock operates
at a priority equal to the highest priority of any task currently
requesting the lock. On targets that support the
``Concurrent_Readers_Locking`` policy, locking is implemented with a
read/write lock allowing multiple protected object functions to enter
concurrently.

*
  "Default ceiling priorities.  See D.3(10)."

The ceiling priority of protected objects of the type
``System.Interrupt_Priority'Last`` as described in the Ada
Reference Manual D.3(10),

*
  "The ceiling of any protected object used internally by
  the implementation.  See D.3(16)."

The ceiling priority of internal protected objects is
``System.Priority'Last``.

*
  "Implementation-defined queuing policies.  See D.4(1)."

There are no implementation-defined queuing policies.

*
  "Implementation-defined admission policies.  See D.4.1(1)."

There are no implementation-defined admission policies.

*
  "Any operations that implicitly require heap storage
  allocation.  See D.7(8)."

The only operation that implicitly requires heap storage allocation is
task creation.

*
  "When restriction No_Dynamic_CPU_Assignment applies to a partition, the
  processor on which a task with a CPU value of a Not_A_Specific_CPU will
  execute.  See D.7(10)."

Unknown.

*
  "When restriction No_Task_Termination applies to a partition, what happens
  when a task terminates.  See D.7(15.1)."

Execution is erroneous in that case.

*
  "The behavior when restriction Max_Storage_At_Blocking is violated.
  See D.7(17)."

Execution is erroneous in that case.

*
  "The behavior when restriction Max_Asynchronous_Select_Nesting is violated.
  See D.7(18)."

Execution is erroneous in that case.

*
  "The behavior when restriction Max_Tasks is violated.  See D.7(19)."

Execution is erroneous in that case.

* "Whether the use of pragma Restrictions results in a reduction in program
  code or data size or execution time.  See D.7(20)."

Yes it can, but the precise circumstances and properties of such reductions
are difficult to characterize.

*
  "The value of Barrier_Limit'Last in Synchronous_Barriers.  See D.10.1(4)."

Synchronous_Barriers.Barrier_Limit'Last is Integer'Last .

*
  "When an aborted task that is waiting on a Synchronous_Barrier is aborted.
  See D.10.1(13)."

Difficult to characterize.

*
  "The value of Min_Handler_Ceiling in Execution_Time.Group_Budgets.
  See D.14.2(7)."

See source file :file:`a-etgrbu.ads`.

*
  "The value of CPU_Range'Last in System.Multiprocessors.  See D.16(4)."

See source file :file:`s-multip.ads`.

*
  "The processor on which the environment task executes in the absence
  of a value for the aspect CPU.  See D.16(13)."

Unknown.

*
  "The means for creating and executing distributed
  programs.  See E(5)."

The PolyORB product provides means creating and executing
distributed programs. **NB!** See the note in :ref:`polyORB` regarding the lifetime of this product.

*
  "Any events that can result in a partition becoming
  inaccessible.  See E.1(7)."

See the PolyORB user guide for full details on such events.
**NB!** Consider the note in :ref:`polyORB` regarding the lifetime
of this product.

*
  "The scheduling policies, treatment of priorities, and management of
  shared resources between partitions in certain cases.  See E.1(11)."

See the PolyORB user guide for full details on these aspects of
multi-partition execution. **NB!** Consider the note in :ref:`polyORB` regarding the lifetime of this product.

*
  "Whether the execution of the remote subprogram is
  immediately aborted as a result of cancellation.  See E.4(13)."

See the PolyORB user guide for details on the effect of abort in
a distributed application.  **NB!** Consider the note in :ref:`polyORB` regarding the lifetime of this product.

*
  "The range of type System.RPC.Partition_Id.  See E.5(14)."

System.RPC.Partition_ID'Last is Integer'Last. See source file :file:`s-rpc.ads`.

*
  "Implementation-defined interfaces in the PCS.  See E.5(26)."

See the PolyORB user guide for a full description of all
implementation defined interfaces.  **NB!** See the note in :ref:`polyORB` regarding the lifetime of this product.

*
  "The values of named numbers in the package
  ``Decimal``.  See F.2(7)."

==================== ==========
Named Number         Value
==================== ==========
*Max_Scale*           +18
*Min_Scale*           -18
*Min_Delta*           1.0E-18
*Max_Delta*           1.0E+18
*Max_Decimal_Digits*  18
==================== ==========

*
  "The value of ``Max_Picture_Length`` in the package
  ``Text_IO.Editing``.  See F.3.3(16)."

  64

*
  "The value of ``Max_Picture_Length`` in the package
  ``Wide_Text_IO.Editing``.  See F.3.4(5)."

  64

*
  "The accuracy actually achieved by the complex elementary
  functions and by other complex arithmetic operations.  See G.1(1)."

Standard library functions are used for the complex arithmetic
operations.  Only fast math mode is currently supported.

*
  "The sign of a zero result (or a component thereof) from
  any operator or function in ``Numerics.Generic_Complex_Types``, when
  ``Real'Signed_Zeros`` is True.  See G.1.1(53)."

The signs of zero values are as recommended by the relevant
implementation advice.

*
  "The sign of a zero result (or a component thereof) from
  any operator or function in
  ``Numerics.Generic_Complex_Elementary_Functions``, when
  ``Real'Signed_Zeros`` is ``True``.  See G.1.2(45)."

The signs of zero values are as recommended by the relevant
implementation advice.

*
  "Whether the strict mode or the relaxed mode is the
  default.  See G.2(2)."

The strict mode is the default.  There is no separate relaxed mode.  GNAT
provides a highly efficient implementation of strict mode.

*
  "The result interval in certain cases of fixed-to-float
  conversion.  See G.2.1(10)."

For cases where the result interval is implementation dependent, the
accuracy is that provided by performing all operations in 64-bit IEEE
floating-point format.

*
  "The result of a floating point arithmetic operation in
  overflow situations, when the ``Machine_Overflows`` attribute of the
  result type is ``False``.  See G.2.1(13)."

Infinite and NaN values are produced as dictated by the IEEE
floating-point standard.
Note that on machines that are not fully compliant with the IEEE
floating-point standard, such as Alpha, the *-mieee* compiler flag
must be used for achieving IEEE conforming behavior (although at the cost
of a significant performance penalty), so infinite and NaN values are
properly generated.

*
  "The result interval for division (or exponentiation by a
  negative exponent), when the floating point hardware implements division
  as multiplication by a reciprocal.  See G.2.1(16)."

Not relevant, division is IEEE exact.

*
  "The definition of close result set, which determines the accuracy of
  certain fixed point multiplications and divisions.  See G.2.3(5)."

Operations in the close result set are performed using IEEE long format
floating-point arithmetic.  The input operands are converted to
floating-point, the operation is done in floating-point, and the result
is converted to the target type.

*
  "Conditions on a *universal_real* operand of a fixed
  point multiplication or division for which the result shall be in the
  perfect result set.  See G.2.3(22)."

The result is only defined to be in the perfect result set if the result
can be computed by a single scaling operation involving a scale factor
representable in 64 bits.

*
  "The result of a fixed point arithmetic operation in
  overflow situations, when the ``Machine_Overflows`` attribute of the
  result type is ``False``.  See G.2.3(27)."

Not relevant, ``Machine_Overflows`` is ``True`` for fixed-point
types.

*
  "The result of an elementary function reference in
  overflow situations, when the ``Machine_Overflows`` attribute of the
  result type is ``False``.  See G.2.4(4)."

IEEE infinite and Nan values are produced as appropriate.

*
  "The value of the angle threshold, within which certain
  elementary functions, complex arithmetic operations, and complex
  elementary functions yield results conforming to a maximum relative
  error bound.  See G.2.4(10)."

Information on this subject is not yet available.

*
  "The accuracy of certain elementary functions for
  parameters beyond the angle threshold.  See G.2.4(10)."

Information on this subject is not yet available.

*
  "The result of a complex arithmetic operation or complex
  elementary function reference in overflow situations, when the
  ``Machine_Overflows`` attribute of the corresponding real type is
  ``False``.  See G.2.6(5)."

IEEE infinite and Nan values are produced as appropriate.

*
  "The accuracy of certain complex arithmetic operations and
  certain complex elementary functions for parameters (or components
  thereof) beyond the angle threshold.  See G.2.6(8)."

Information on those subjects is not yet available.

*
  "The accuracy requirements for the subprograms Solve, Inverse,
  Determinant, Eigenvalues and Eigensystem for type Real_Matrix.
  See G.3.1(81)."

Information on those subjects is not yet available.

*
  "The accuracy requirements for the subprograms Solve, Inverse,
  Determinant, Eigenvalues and Eigensystem for type Complex_Matrix.
  See G.3.2(149)."

Information on those subjects is not yet available.

*
  "The consequences of violating No_Hidden_Indirect_Globals.  See H.4(23.9)."

Execution is erroneous in that case.

---

### Gcc Ada Doc Gnat Rm Implementation Defined Pragmas (`gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst`)

.. role:: switch(samp)

.. _Implementation_Defined_Pragmas:

******************************
Implementation Defined Pragmas
******************************

Ada defines a set of pragmas that can be used to supply additional
information to the compiler.  These language defined pragmas are
implemented in GNAT and work as described in the Ada Reference Manual.

In addition, Ada allows implementations to define additional pragmas
whose meaning is defined by the implementation.  GNAT provides a number
of these implementation-defined pragmas, which can be used to extend
and enhance the functionality of the compiler.  This section of the GNAT
Reference Manual describes these additional pragmas.

Note that any program using these pragmas might not be portable to other
compilers (although GNAT implements this set of pragmas on all
platforms).  Therefore if portability to other compilers is an important
consideration, the use of these pragmas should be minimized.

Pragma Abort_Defer
==================

.. index:: Deferring aborts

Syntax:

.. code-block:: ada

  pragma Abort_Defer;


This pragma must appear at the start of the statement sequence of a
handled sequence of statements (right after the ``begin``).  It has
the effect of deferring aborts for the sequence of statements (but not
for the declarations or handlers, if any, associated with this statement
sequence). This can also be useful for adding a polling point in Ada code,
where asynchronous abort of tasks is checked when leaving the statement
sequence, and is lighter than, for example, using ``delay 0.0;``, since with
zero-cost exception handling, propagating exceptions (implicitly used to
implement task abort) cannot be done reliably in an asynchronous way.

An example of usage would be:

.. code-block:: ada

  --  Add a polling point to check for task aborts

  begin
     pragma Abort_Defer;
  end;

.. _Pragma-Abstract_State:

Pragma Abstract_State
=====================

Syntax:

.. code-block:: ada

  pragma Abstract_State (ABSTRACT_STATE_LIST);

  ABSTRACT_STATE_LIST ::=
       null
    |  STATE_NAME_WITH_OPTIONS
    | (STATE_NAME_WITH_OPTIONS {, STATE_NAME_WITH_OPTIONS} )

  STATE_NAME_WITH_OPTIONS ::=
       STATE_NAME
    | (STATE_NAME with OPTION_LIST)

  OPTION_LIST ::= OPTION {, OPTION}

  OPTION ::=
      SIMPLE_OPTION
    | NAME_VALUE_OPTION

  SIMPLE_OPTION ::= Ghost | Synchronous

  NAME_VALUE_OPTION ::=
      Part_Of => ABSTRACT_STATE
    | External [=> EXTERNAL_PROPERTY_LIST]

  EXTERNAL_PROPERTY_LIST ::=
       EXTERNAL_PROPERTY
    | (EXTERNAL_PROPERTY {, EXTERNAL_PROPERTY} )

  EXTERNAL_PROPERTY ::=
      Async_Readers    [=> static_boolean_EXPRESSION]
    | Async_Writers    [=> static_boolean_EXPRESSION]
    | Effective_Reads  [=> static_boolean_EXPRESSION]
    | Effective_Writes [=> static_boolean_EXPRESSION]
      others            => static_boolean_EXPRESSION

  STATE_NAME ::= defining_identifier

  ABSTRACT_STATE ::= name

For the semantics of this pragma, see the entry for aspect ``Abstract_State`` in
the SPARK 2014 Reference Manual, section 7.1.4.

Pragma Ada_83
=============

Syntax:

.. code-block:: ada

  pragma Ada_83;


A configuration pragma that establishes Ada 83 mode for the unit to
which it applies, regardless of the mode set by the command line
switches.  In Ada 83 mode, GNAT attempts to be as compatible with
the syntax and semantics of Ada 83, as defined in the original Ada
83 Reference Manual as possible.  In particular, the keywords added by Ada 95
and Ada 2005 are not recognized, optional package bodies are allowed,
and generics may name types with unknown discriminants without using
the ``(<>)`` notation.  In addition, some but not all of the additional
restrictions of Ada 83 are enforced.

Like all configuration pragmas, if the pragma is placed before a library
level package specification it is not propagated to the corresponding
package body (see RM 10.1.5(8)); it must be added explicitly to the
package body.

Ada 83 mode is intended for two purposes.  Firstly, it allows existing
Ada 83 code to be compiled and adapted to GNAT with less effort.
Secondly, it aids in keeping code backwards compatible with Ada 83.
However, there is no guarantee that code that is processed correctly
by GNAT in Ada 83 mode will in fact compile and execute with an Ada
83 compiler, since GNAT does not enforce all the additional checks
required by Ada 83.

Pragma Ada_95
=============

Syntax:

.. code-block:: ada

  pragma Ada_95;


A configuration pragma that establishes Ada 95 mode for the unit to which
it applies, regardless of the mode set by the command line switches.
This mode is set automatically for the ``Ada`` and ``System``
packages and their children, so you need not specify it in these
contexts.  This pragma is useful when writing a reusable component that
itself uses Ada 95 features, but which is intended to be usable from
either Ada 83 or Ada 95 programs.

Like all configuration pragmas, if the pragma is placed before a library
level package specification it is not propagated to the corresponding
package body (see RM 10.1.5(8)); it must be added explicitly to the
package body.

Pragma Ada_05
=============

Syntax:

.. code-block:: ada

  pragma Ada_05;
  pragma Ada_05 (local_NAME);


A configuration pragma that establishes Ada 2005 mode for the unit to which
it applies, regardless of the mode set by the command line switches.
This pragma is useful when writing a reusable component that
itself uses Ada 2005 features, but which is intended to be usable from
either Ada 83 or Ada 95 programs.

Like all configuration pragmas, if the pragma is placed before a library
level package specification it is not propagated to the corresponding
package body (see RM 10.1.5(8)); it must be added explicitly to the
package body.

The one argument form (which is not a configuration pragma)
is used for managing the transition from
Ada 95 to Ada 2005 in the run-time library. If an entity is marked
as Ada_2005 only, then referencing the entity in Ada_83 or Ada_95
mode will generate a warning. In addition, in Ada_83 or Ada_95
mode, a preference rule is established which does not choose
such an entity unless it is unambiguously specified. This avoids
extra subprograms marked this way from generating ambiguities in
otherwise legal pre-Ada_2005 programs. The one argument form is
intended for exclusive use in the GNAT run-time library.

Pragma Ada_2005
===============

Syntax:

.. code-block:: ada

  pragma Ada_2005;


This configuration pragma is a synonym for pragma Ada_05 and has the
same syntax and effect.

Pragma Ada_12
=============

Syntax:

.. code-block:: ada

  pragma Ada_12;
  pragma Ada_12 (local_NAME);


A configuration pragma that establishes Ada 2012 mode for the unit to which
it applies, regardless of the mode set by the command line switches.
This mode is set automatically for the ``Ada`` and ``System``
packages and their children, so you need not specify it in these
contexts.  This pragma is useful when writing a reusable component that
itself uses Ada 2012 features, but which is intended to be usable from
Ada 83, Ada 95, or Ada 2005 programs.

Like all configuration pragmas, if the pragma is placed before a library
level package specification it is not propagated to the corresponding
package body (see RM 10.1.5(8)); it must be added explicitly to the
package body.

The one argument form, which is not a configuration pragma,
is used for managing the transition from Ada
2005 to Ada 2012 in the run-time library. If an entity is marked
as Ada_2012 only, then referencing the entity in any pre-Ada_2012
mode will generate a warning. In addition, in any pre-Ada_2012
mode, a preference rule is established which does not choose
such an entity unless it is unambiguously specified. This avoids
extra subprograms marked this way from generating ambiguities in
otherwise legal pre-Ada_2012 programs. The one argument form is
intended for exclusive use in the GNAT run-time library.

Pragma Ada_2012
===============

Syntax:

.. code-block:: ada

  pragma Ada_2012;


This configuration pragma is a synonym for pragma Ada_12 and has the
same syntax and effect.

Pragma Ada_2022
===============

Syntax:

.. code-block:: ada

  pragma Ada_2022;
  pragma Ada_2022 (local_NAME);


A configuration pragma that establishes Ada 2022 mode for the unit to which
it applies, regardless of the mode set by the command line switches.
This mode is set automatically for the ``Ada`` and ``System``
packages and their children, so you need not specify it in these
contexts.  This pragma is useful when writing a reusable component that
itself uses Ada 2022 features, but which is intended to be usable from
Ada 83, Ada 95, Ada 2005 or Ada 2012 programs.

Like all configuration pragmas, if the pragma is placed before a library
level package specification it is not propagated to the corresponding
package body (see RM 10.1.5(8)); it must be added explicitly to the
package body.

The one argument form, which is not a configuration pragma,
is used for managing the transition from Ada
2012 to Ada 2022 in the run-time library. If an entity is marked
as Ada_2022 only, then referencing the entity in any pre-Ada_2022
mode will generate a warning. In addition, in any pre-Ada_2012
mode, a preference rule is established which does not choose
such an entity unless it is unambiguously specified. This avoids
extra subprograms marked this way from generating ambiguities in
otherwise legal pre-Ada_2022 programs. The one argument form is
intended for exclusive use in the GNAT run-time library.

Pragma Aggregate_Individually_Assign
====================================

Syntax:

.. code-block:: ada

  pragma Aggregate_Individually_Assign;

Where possible, GNAT will store the binary representation of a record aggregate
in memory for space and performance reasons. This configuration pragma changes
this behavior so that record aggregates are instead always converted into
individual assignment statements.


Pragma Allow_Integer_Address
============================

Syntax:

.. code-block:: ada

  pragma Allow_Integer_Address;


In almost all versions of GNAT, ``System.Address`` is a private
type in accordance with the implementation advice in the RM. This
means that integer values,
in particular integer literals, are not allowed as address values.
If the configuration pragma
``Allow_Integer_Address`` is given, then integer expressions may
be used anywhere a value of type ``System.Address`` is required.
The effect is to introduce an implicit unchecked conversion from the
integer value to type ``System.Address``. The reverse case of using
an address where an integer type is required is handled analogously.
The following example compiles without errors:


.. code-block:: ada

  pragma Allow_Integer_Address;
  with System; use System;
  package AddrAsInt is
     X : Integer;
     Y : Integer;
     for X'Address use 16#1240#;
     for Y use at 16#3230#;
     m : Address := 16#4000#;
     n : constant Address := 4000;
     p : constant Address := Address (X + Y);
     v : Integer := y'Address;
     w : constant Integer := Integer (Y'Address);
     type R is new integer;
     RR : R := 1000;
     Z : Integer;
     for Z'Address use RR;
  end AddrAsInt;


Note that pragma ``Allow_Integer_Address`` is ignored if ``System.Address``
is not a private type. In implementations of ``GNAT`` where
System.Address is a visible integer type,
this pragma serves no purpose but is ignored
rather than rejected to allow common sets of sources to be used
in the two situations.

.. _Pragma-Always_Terminates:

Pragma Always_Terminates
========================

Syntax:

.. code-block:: ada

  pragma Always_Terminates [ (boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Always_Terminates``
in the SPARK 2014 Reference Manual, section 6.1.11.

.. _Pragma-Annotate:

Pragma Annotate
===============

Syntax::

  pragma Annotate (IDENTIFIER [, IDENTIFIER {, ARG}] [, entity => local_NAME]);

  ARG ::= NAME | EXPRESSION


This pragma is used to annotate programs.  IDENTIFIER identifies
the type of annotation.  GNAT verifies that it is an identifier, but does
not otherwise analyze it. The second optional identifier is also left
unanalyzed, and by convention is used to control the action of the tool to
which the annotation is addressed.  The remaining ARG arguments
can be either string literals or more generally expressions.
String literals (and concatenations of string literals) are assumed to be
either of type
``Standard.String`` or else ``Wide_String`` or ``Wide_Wide_String``
depending on the character literals they contain.
All other kinds of arguments are analyzed as expressions, and must be
unambiguous. The last argument if present must have the identifier
``Entity`` and GNAT verifies that a local name is given.

The analyzed pragma is retained in the tree, but not otherwise processed
by any part of the GNAT compiler, except to generate corresponding note
lines in the generated ALI file. For the format of these note lines, see
the compiler source file lib-writ.ads. This pragma is intended for use by
external tools. The use of pragma Annotate does not affect the compilation
process in any way. This pragma may be used as a configuration pragma.

Pragma Assert
=============

Syntax::

  pragma Assert (
    boolean_EXPRESSION
    [, string_EXPRESSION]);


The effect of this pragma depends on whether the corresponding command
line switch is set to activate assertions.  The pragma expands into code
equivalent to the following:

.. code-block:: ada

  if assertions-enabled then
     if not boolean_EXPRESSION then
        System.Assertions.Raise_Assert_Failure
          (string_EXPRESSION);
     end if;
  end if;


The string argument, if given, is the message that will be associated
with the exception occurrence if the exception is raised.  If no second
argument is given, the default message is ``file``:``nnn``,
where ``file`` is the name of the source file containing the assert,
and ``nnn`` is the line number of the assert.

Note that, as with the ``if`` statement to which it is equivalent, the
type of the expression is either ``Standard.Boolean``, or any type derived
from this standard type.

Assert checks can be either checked or ignored. By default they are ignored.
They will be checked if either the command line switch *-gnata* is
used, or if an ``Assertion_Policy`` or ``Check_Policy`` pragma is used
to enable ``Assert_Checks``.

If assertions are ignored, then there
is no run-time effect (and in particular, any side effects from the
expression will not occur at run time).  (The expression is still
analyzed at compile time, and may cause types to be frozen if they are
mentioned here for the first time).

If assertions are checked, then the given expression is tested, and if
it is ``False`` then ``System.Assertions.Raise_Assert_Failure`` is called
which results in the raising of ``Assert_Failure`` with the given message.

You should generally avoid side effects in the expression arguments of
this pragma, because these side effects will turn on and off with the
setting of the assertions mode, resulting in assertions that have an
effect on the program.  However, the expressions are analyzed for
semantic correctness whether or not assertions are enabled, so turning
assertions on and off cannot affect the legality of a program.

Note that the implementation defined policy ``DISABLE``, given in a
pragma ``Assertion_Policy``, can be used to suppress this semantic analysis.

Note: this is a standard language-defined pragma in versions
of Ada from 2005 on. In GNAT, it is implemented in all versions
of Ada, and the DISABLE policy is an implementation-defined
addition.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Assert_And_Cut
=====================

Syntax::

  pragma Assert_And_Cut (
    boolean_EXPRESSION
    [, string_EXPRESSION]);


The effect of this pragma is identical to that of pragma ``Assert``,
except that in an ``Assertion_Policy`` pragma, the identifier
``Assert_And_Cut`` is used to control whether it is ignored or checked
(or disabled).

The intention is that this be used within a subprogram when the
given test expression sums up all the work done so far in the
subprogram, so that the rest of the subprogram can be verified
(informally or formally) using only the entry preconditions,
and the expression in this pragma. This allows dividing up
a subprogram into sections for the purposes of testing or
formal verification. The pragma also serves as useful
documentation.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Assertion_Level
=======================

Syntax::

  pragma Assertion_Level (LEVEL_IDENTIFIER
                          [, depends => DEPENDENCY_DESCRIPTOR]);

  DEPENDENCY_DESCRIPTOR ::= LEVEL_IDENTIFIER | LEVEL_IDENTIFIER_LIST

  LEVEL_IDENTIFIER_LIST ::= '[' LEVEL_IDENTIFIER {, LEVEL_IDENTIFIER} ']'

For the semantics of this pragma, see the SPARK 2014 Reference Manual,
section 11.4.3.

Pragma Assertion_Policy
=======================

Syntax::

  pragma Assertion_Policy (CHECK | DISABLE | IGNORE | SUPPRESSIBLE);

  pragma Assertion_Policy (
      ASSERTION_KIND => POLICY_IDENTIFIER
   {, ASSERTION_KIND => POLICY_IDENTIFIER});

  ASSERTION_KIND ::= RM_ASSERTION_KIND | ID_ASSERTION_KIND | ASSERTION_LEVEL

  RM_ASSERTION_KIND ::= Assert                    |
                        Static_Predicate          |
                        Dynamic_Predicate         |
                        Pre                       |
                        Pre'Class                 |
                        Post                      |
                        Post'Class                |
                        Type_Invariant            |
                        Type_Invariant'Class      |
                        Default_Initial_Condition

  ID_ASSERTION_KIND ::= Assertions           |
                        Assert_And_Cut       |
                        Assume               |
                        Contract_Cases       |
                        Debug                |
                        Ghost                |
                        Initial_Condition    |
                        Invariant            |
                        Invariant'Class      |
                        Loop_Invariant       |
                        Loop_Variant         |
                        Postcondition        |
                        Precondition         |
                        Predicate            |
                        Refined_Post         |
                        Statement_Assertions |
                        Subprogram_Variant

  POLICY_IDENTIFIER ::= Check | Disable | Ignore | Suppressible


This is a standard Ada 2012 pragma that is available as an
implementation-defined pragma in earlier versions of Ada.
The assertion kinds ``RM_ASSERTION_KIND`` are those defined in
the Ada standard. The assertion kinds ``ID_ASSERTION_KIND``
are implementation defined additions recognized by the GNAT compiler.

Additionally the pragma can apply to an assertion level defined by the
``Assertion_Level`` pragma. For more details see the SPARK 2014 Reference
Manual, section 11.4.2.

The pragma applies in both cases to pragmas and aspects with matching
names, e.g. ``Pre`` applies to the Pre aspect, and ``Precondition``
applies to both the ``Precondition`` pragma
and the aspect ``Precondition``. Note that the identifiers for
pragmas Pre_Class and Post_Class are Pre'Class and Post'Class (not
Pre_Class and Post_Class), since these pragmas are intended to be
identical to the corresponding aspects.

If the policy is ``CHECK``, then assertions are enabled, i.e.
the corresponding pragma or aspect is activated.
If the policy is ``IGNORE``, then assertions are ignored, i.e.
the corresponding pragma or aspect is deactivated.
This pragma overrides the effect of the *-gnata* switch on the
command line.
If the policy is ``SUPPRESSIBLE``, then assertions are enabled by default,
however, if the *-gnatp* switch is specified all assertions are ignored.

The implementation defined policy ``DISABLE`` is like
``IGNORE`` except that it completely disables semantic
checking of the corresponding pragma or aspect. This is
useful when the pragma or aspect argument references subprograms
in a with'ed package which is replaced by a dummy package
for the final build.

The implementation defined assertion kind ``Assertions`` applies to all
assertion kinds. The form with no assertion kind given implies this
choice, so it applies to all assertion kinds (RM defined, and
implementation defined).

The implementation defined assertion kind ``Statement_Assertions``
applies to ``Assert``, ``Assert_And_Cut``,
``Assume``, ``Loop_Invariant``, and ``Loop_Variant``.

Pragma Assume
=============

Syntax:

::

  pragma Assume (
    boolean_EXPRESSION
    [, string_EXPRESSION]);


The effect of this pragma is identical to that of pragma ``Assert``,
except that in an ``Assertion_Policy`` pragma, the identifier
``Assume`` is used to control whether it is ignored or checked
(or disabled).

The intention is that this be used for assumptions about the
external environment. So you cannot expect to verify formally
or informally that the condition is met, this must be
established by examining things outside the program itself.
For example, we may have code that depends on the size of
``Long_Long_Integer`` being at least 64. So we could write:

.. code-block:: ada

  pragma Assume (Long_Long_Integer'Size >= 64);


This assumption cannot be proved from the program itself,
but it acts as a useful run-time check that the assumption
is met, and documents the need to ensure that it is met by
reference to information outside the program.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Assume_No_Invalid_Values
===============================
.. index:: Invalid representations

.. index:: Invalid values

Syntax:

.. code-block:: ada

  pragma Assume_No_Invalid_Values (On | Off);


This is a configuration pragma that controls the assumptions made by the
compiler about the occurrence of invalid representations (invalid values)
in the code.

The default behavior (corresponding to an Off argument for this pragma), is
to assume that values may in general be invalid unless the compiler can
prove they are valid. Consider the following example:

.. code-block:: ada

  V1 : Integer range 1 .. 10;
  V2 : Integer range 11 .. 20;
  ...
  for J in V2 .. V1 loop
     ...
  end loop;


if V1 and V2 have valid values, then the loop is known at compile
time not to execute since the lower bound must be greater than the
upper bound. However in default mode, no such assumption is made,
and the loop may execute. If ``Assume_No_Invalid_Values (On)``
is given, the compiler will assume that any occurrence of a variable
other than in an explicit ``'Valid`` test always has a valid
value, and the loop above will be optimized away.

The use of ``Assume_No_Invalid_Values (On)`` is appropriate if
you know your code is free of uninitialized variables and other
possible sources of invalid representations, and may result in
more efficient code. A program that accesses an invalid representation
with this pragma in effect is erroneous, so no guarantees can be made
about its behavior.

It is peculiar though permissible to use this pragma in conjunction
with validity checking (-gnatVa). In such cases, accessing invalid
values will generally give an exception, though formally the program
is erroneous so there are no guarantees that this will always be the
case, and it is recommended that these two options not be used together.

.. _Pragma-Async_Readers:

Pragma Async_Readers
====================

Syntax:

.. code-block:: ada

  pragma Async_Readers [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Async_Readers`` in
the SPARK 2014 Reference Manual, section 7.1.2.

.. _Pragma-Async_Writers:

Pragma Async_Writers
====================

Syntax:

.. code-block:: ada

  pragma Async_Writers [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Async_Writers`` in
the SPARK 2014 Reference Manual, section 7.1.2.

Pragma Attribute_Definition
===========================

Syntax:

::

  pragma Attribute_Definition
    ([Attribute  =>] ATTRIBUTE_DESIGNATOR,
     [Entity     =>] LOCAL_NAME,
     [Expression =>] EXPRESSION | NAME);


If ``Attribute`` is a known attribute name, this pragma is equivalent to
the attribute definition clause:


.. code-block:: ada

    for Entity'Attribute use Expression;


If ``Attribute`` is not a recognized attribute name, the pragma is
ignored, and a warning is emitted. This allows source
code to be written that takes advantage of some new attribute, while remaining
compilable with earlier compilers.

Pragma C_Pass_By_Copy
=====================
.. index:: Passing by copy


Syntax:

::

  pragma C_Pass_By_Copy
    ([Max_Size =>] static_integer_EXPRESSION);


Normally the default mechanism for passing C convention records to C
convention subprograms is to pass them by reference, as suggested by RM
B.3(69).  Use the configuration pragma ``C_Pass_By_Copy`` to change
this default, by requiring that record formal parameters be passed by
copy if all of the following conditions are met:

*
  The size of the record type does not exceed the value specified for
  ``Max_Size``.
*
  The record type has ``Convention C``.
*
  The formal parameter has this record type, and the subprogram has a
  foreign (non-Ada) convention.

If these conditions are met the argument is passed by copy; i.e., in a
manner consistent with what C expects if the corresponding formal in the
C prototype is a struct (rather than a pointer to a struct).

You can also pass records by copy by specifying the convention
``C_Pass_By_Copy`` for the record type, or by using the extended
``Import`` and ``Export`` pragmas, which allow specification of
passing mechanisms on a parameter by parameter basis.

Pragma Check
============
.. index:: Assertions

.. index:: Named assertions


Syntax:

::

  pragma Check (
       [Name    =>] CHECK_KIND,
       [Check   =>] Boolean_EXPRESSION
    [, [Message =>] string_EXPRESSION] );

  CHECK_KIND ::= IDENTIFIER           |
                 Pre'Class            |
                 Post'Class           |
                 Type_Invariant'Class |
                 Invariant'Class


This pragma is similar to the predefined pragma ``Assert`` except that an
extra identifier argument is present. In conjunction with pragma
``Check_Policy``, this can be used to define groups of assertions that can
be independently controlled. The identifier ``Assertion`` is special, it
refers to the normal set of pragma ``Assert`` statements.

Checks introduced by this pragma are normally deactivated by default. They can
be activated either by the command line option *-gnata*, which turns on
all checks, or individually controlled using pragma ``Check_Policy``.

The identifiers ``Assertions`` and ``Statement_Assertions`` are not
permitted as check kinds, since this would cause confusion with the use
of these identifiers in ``Assertion_Policy`` and ``Check_Policy``
pragmas, where they are used to refer to sets of assertions.

Pragma Check_Float_Overflow
===========================
.. index:: Floating-point overflow


Syntax:

.. code-block:: ada

  pragma Check_Float_Overflow;


In Ada, the predefined floating-point types (``Short_Float``,
``Float``, ``Long_Float``, ``Long_Long_Float``) are
defined to be *unconstrained*. This means that even though each
has a well-defined base range, an operation that delivers a result
outside this base range is not required to raise an exception.
This implementation permission accommodates the notion
of infinities in IEEE floating-point, and corresponds to the
efficient execution mode on most machines. GNAT will not raise
overflow exceptions on these machines; instead it will generate
infinities and NaN's as defined in the IEEE standard.

Generating infinities, although efficient, is not always desirable.
Often the preferable approach is to check for overflow, even at the
(perhaps considerable) expense of run-time performance.
This can be accomplished by defining your own constrained floating-point subtypes -- i.e., by supplying explicit
range constraints -- and indeed such a subtype
can have the same base range as its base type. For example:


.. code-block:: ada

  subtype My_Float is Float range Float'Range;


Here ``My_Float`` has the same range as
``Float`` but is constrained, so operations on
``My_Float`` values will be checked for overflow
against this range.

This style will achieve the desired goal, but
it is often more convenient to be able to simply use
the standard predefined floating-point types as long
as overflow checking could be guaranteed.
The ``Check_Float_Overflow``
configuration pragma achieves this effect. If a unit is compiled
subject to this configuration pragma, then all operations
on predefined floating-point types including operations on
base types of these floating-point types will be treated as
though those types were constrained, and overflow checks
will be generated. The ``Constraint_Error``
exception is raised if the result is out of range.

This mode can also be set by use of the compiler
switch *-gnateF*.

Pragma Check_Name
=================
.. index:: Defining check names

.. index:: Check names, defining


Syntax:

.. code-block:: ada

  pragma Check_Name (check_name_IDENTIFIER);


This is a configuration pragma that defines a new implementation
defined check name (unless IDENTIFIER matches one of the predefined
check names, in which case the pragma has no effect). Check names
are global to a partition, so if two or more configuration pragmas
are present in a partition mentioning the same name, only one new
check name is introduced.

An implementation defined check name introduced with this pragma may
be used in only three contexts: ``pragma Suppress``,
``pragma Unsuppress``,
and as the prefix of a ``Check_Name'Enabled`` attribute reference. For
any of these three cases, the check name must be visible. A check
name is visible if it is in the configuration pragmas applying to
the current unit, or if it appears at the start of any unit that
is part of the dependency set of the current unit (e.g., units that
are mentioned in ``with`` clauses).

Check names introduced by this pragma are subject to control by compiler
switches (in particular -gnatp) in the usual manner.

Pragma Check_Policy
===================
.. index:: Controlling assertions

.. index:: Assertions, control

.. index:: Check pragma control

.. index:: Named assertions


Syntax:

::

  pragma Check_Policy
   ([Name   =>] CHECK_KIND,
    [Policy =>] POLICY_IDENTIFIER);

  pragma Check_Policy (
      CHECK_KIND => POLICY_IDENTIFIER
   {, CHECK_KIND => POLICY_IDENTIFIER});

  ASSERTION_KIND ::= RM_ASSERTION_KIND | ID_ASSERTION_KIND

  CHECK_KIND ::= IDENTIFIER           |
                 Pre'Class            |
                 Post'Class           |
                 Type_Invariant'Class |
                 Invariant'Class

  The identifiers Name and Policy are not allowed as CHECK_KIND values. This
  avoids confusion between the two possible syntax forms for this pragma.

  POLICY_IDENTIFIER ::= ON | OFF | CHECK | DISABLE | IGNORE


This pragma is used to set the checking policy for assertions (specified
by aspects or pragmas), the ``Debug`` pragma, or additional checks
to be checked using the ``Check`` pragma. It may appear either as
a configuration pragma, or within a declarative part of package. In the
latter case, it applies from the point where it appears to the end of
the declarative region (like pragma ``Suppress``).

The ``Check_Policy`` pragma is similar to the
predefined ``Assertion_Policy`` pragma,
and if the check kind corresponds to one of the assertion kinds that
are allowed by ``Assertion_Policy``, then the effect is identical.

If the first argument is Debug, then the policy applies to Debug pragmas,
disabling their effect if the policy is ``OFF``, ``DISABLE``, or
``IGNORE``, and allowing them to execute with normal semantics if
the policy is ``ON`` or ``CHECK``. In addition if the policy is
``DISABLE``, then the procedure call in ``Debug`` pragmas will
be totally ignored and not analyzed semantically.

Finally the first argument may be some other identifier than the above
possibilities, in which case it controls a set of named assertions
that can be checked using pragma ``Check``. For example, if the pragma:


.. code-block:: ada

  pragma Check_Policy (Critical_Error, OFF);


is given, then subsequent ``Check`` pragmas whose first argument is also
``Critical_Error`` will be disabled.

The check policy is ``OFF`` to turn off corresponding checks, and ``ON``
to turn on corresponding checks. The default for a set of checks for which no
``Check_Policy`` is given is ``OFF`` unless the compiler switch
*-gnata* is given, which turns on all checks by default.

The check policy settings ``CHECK`` and ``IGNORE`` are recognized
as synonyms for ``ON`` and ``OFF``. These synonyms are provided for
compatibility with the standard ``Assertion_Policy`` pragma. The check
policy setting ``DISABLE`` causes the second argument of a corresponding
``Check`` pragma to be completely ignored and not analyzed.

Pragma Comment
==============

Syntax:


.. code-block:: ada

  pragma Comment (static_string_EXPRESSION);


This is almost identical in effect to pragma ``Ident``.  It allows the
placement of a comment into the object file and hence into the
executable file if the operating system permits such usage.  The
difference is that ``Comment``, unlike ``Ident``, has
no limitations on placement of the pragma (it can be placed
anywhere in the main source unit), and if more than one pragma
is used, all comments are retained.

Pragma Common_Object
====================

Syntax:


::

  pragma Common_Object (
       [Internal =>] LOCAL_NAME
    [, [External =>] EXTERNAL_SYMBOL]
    [, [Size     =>] EXTERNAL_SYMBOL] );

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION


This pragma enables the shared use of variables stored in overlaid
linker areas corresponding to the use of ``COMMON``
in Fortran.  The single
object ``LOCAL_NAME`` is assigned to the area designated by
the ``External`` argument.
You may define a record to correspond to a series
of fields.  The ``Size`` argument
is syntax checked in GNAT, but otherwise ignored.

``Common_Object`` is not supported on all platforms.  If no
support is available, then the code generator will issue a message
indicating that the necessary attribute for implementation of this
pragma is not available.

.. _Compile_Time_Error:

Pragma Compile_Time_Error
=========================

Syntax:


.. code-block:: ada

  pragma Compile_Time_Error
           (boolean_EXPRESSION, static_string_EXPRESSION);


This pragma can be used to generate additional compile time
error messages. It
is particularly useful in generics, where errors can be issued for
specific problematic instantiations. The first parameter is a boolean
expression. The pragma ensures that the value of an expression
is known at compile time, and has the value False. The set of expressions
whose values are known at compile time includes all static boolean
expressions, and also other values which the compiler can determine
at compile time (e.g., the size of a record type set by an explicit
size representation clause, or the value of a variable which was
initialized to a constant and is known not to have been modified).
If these conditions are not met, an error message is generated using
the value given as the second argument. This string value may contain
embedded ASCII.LF characters to break the message into multiple lines.

Pragma Compile_Time_Warning
===========================

Syntax:


.. code-block:: ada

  pragma Compile_Time_Warning
           (boolean_EXPRESSION, static_string_EXPRESSION);


Same as pragma Compile_Time_Error, except a warning is issued instead
of an error message. If switch *-gnatw_C* is used, a warning is only issued
if the value of the expression is known to be True at compile time, not when
the value of the expression is not known at compile time.
Note that if this pragma is used in a package that
is with'ed by a client, the client will get the warning even though it
is issued by a with'ed package (normally warnings in with'ed units are
suppressed, but this is a special exception to that rule).

One typical use is within a generic where compile time known characteristics
of formal parameters are tested, and warnings given appropriately. Another use
with a first parameter of True is to warn a client about use of a package,
for example that it is not fully implemented.

In previous versions of the compiler, combining *-gnatwe* with
Compile_Time_Warning resulted in a fatal error. Now the compiler always emits
a warning. You can use :ref:`Compile_Time_Error` to force the generation of
an error.

Pragma Complete_Representation
==============================

Syntax:


.. code-block:: ada

  pragma Complete_Representation;


This pragma must appear immediately within a record representation
clause. Typical placements are before the first component clause
or after the last component clause. The effect is to give an error
message if any component is missing a component clause. This pragma
may be used to ensure that a record representation clause is
complete, and that this invariant is maintained if fields are
added to the record in the future.

Pragma Complex_Representation
=============================

Syntax:


::

  pragma Complex_Representation
          ([Entity =>] LOCAL_NAME);


The ``Entity`` argument must be the name of a record type which has
two fields of the same floating-point type.  The effect of this pragma is
to force gcc to use the special internal complex representation form for
this record, which may be more efficient.  Note that this may result in
the code for this type not conforming to standard ABI (application
binary interface) requirements for the handling of record types.  For
example, in some environments, there is a requirement for passing
records by pointer, and the use of this pragma may result in passing
this type in floating-point registers.

Pragma Component_Alignment
==========================
.. index:: Alignments of components
.. index:: Pragma Component_Alignment


Syntax:

::

  pragma Component_Alignment (
       [Form =>] ALIGNMENT_CHOICE
    [, [Name =>] type_LOCAL_NAME]);

  ALIGNMENT_CHOICE ::=
    Component_Size
  | Component_Size_4
  | Storage_Unit
  | Default


Specifies the alignment of components in array or record types.
The meaning of the ``Form`` argument is as follows:


  .. index:: Component_Size (in pragma Component_Alignment)

*Component_Size*
  Aligns scalar components and subcomponents of the array or record type
  on boundaries appropriate to their inherent size (naturally
  aligned).  For example, 1-byte components are aligned on byte boundaries,
  2-byte integer components are aligned on 2-byte boundaries, 4-byte
  integer components are aligned on 4-byte boundaries and so on.  These
  alignment rules correspond to the normal rules for C compilers on all
  machines except the VAX.

  .. index:: Component_Size_4 (in pragma Component_Alignment)

*Component_Size_4*
  Naturally aligns components with a size of four or fewer
  bytes.  Components that are larger than 4 bytes are placed on the next
  4-byte boundary.

  .. index:: Storage_Unit (in pragma Component_Alignment)

*Storage_Unit*
  Specifies that array or record components are byte aligned, i.e.,
  aligned on boundaries determined by the value of the constant
  ``System.Storage_Unit``.

  .. index:: Default (in pragma Component_Alignment)

*Default*
  Specifies that array or record components are aligned on default
  boundaries, appropriate to the underlying hardware or operating system or
  both. The ``Default`` choice is the same as ``Component_Size`` (natural
  alignment).

If the ``Name`` parameter is present, ``type_LOCAL_NAME`` must
refer to a local record or array type, and the specified alignment
choice applies to the specified type.  The use of
``Component_Alignment`` together with a pragma ``Pack`` causes the
``Component_Alignment`` pragma to be ignored.  The use of
``Component_Alignment`` together with a record representation clause
is only effective for fields not specified by the representation clause.

If the ``Name`` parameter is absent, the pragma can be used as either
a configuration pragma, in which case it applies to one or more units in
accordance with the normal rules for configuration pragmas, or it can be
used within a declarative part, in which case it applies to types that
are declared within this declarative part, or within any nested scope
within this declarative part.  In either case it specifies the alignment
to be applied to any record or array type which has otherwise standard
representation.

If the alignment for a record or array type is not specified (using
pragma ``Pack``, pragma ``Component_Alignment``, or a record rep
clause), the GNAT uses the default alignment as described previously.

.. _Pragma-Constant_After_Elaboration:

Pragma Constant_After_Elaboration
=================================

Syntax:

.. code-block:: ada

  pragma Constant_After_Elaboration [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect
``Constant_After_Elaboration`` in the SPARK 2014 Reference Manual, section 3.3.1.

.. _Pragma-Contract_Cases:

Pragma Contract_Cases
=====================
.. index:: Contract cases

Syntax:

.. code-block:: ada

  pragma Contract_Cases (CONTRACT_CASE {, CONTRACT_CASE});

  CONTRACT_CASE ::= CASE_GUARD => CONSEQUENCE

  CASE_GUARD ::= boolean_EXPRESSION | others

  CONSEQUENCE ::= boolean_EXPRESSION

The ``Contract_Cases`` pragma allows defining fine-grain specifications
that can complement or replace the contract given by a precondition and a
postcondition. Additionally, the ``Contract_Cases`` pragma can be used
by testing and formal verification tools. The compiler checks its validity and,
depending on the assertion policy at the point of declaration of the pragma,
it may insert a check in the executable. For code generation, the contract
cases


.. code-block:: ada

  pragma Contract_Cases (
    Cond1 => Pred1,
    Cond2 => Pred2);


are equivalent to


.. code-block:: ada

  C1 : constant Boolean := Cond1;  --  evaluated at subprogram entry
  C2 : constant Boolean := Cond2;  --  evaluated at subprogram entry
  pragma Precondition ((C1 and not C2) or (C2 and not C1));
  pragma Postcondition (if C1 then Pred1);
  pragma Postcondition (if C2 then Pred2);


The precondition ensures that one and only one of the case guards is
satisfied on entry to the subprogram.
The postcondition ensures that for the case guard that was True on entry,
the corresponding consequence is True on exit. Other consequence expressions
are not evaluated.

A precondition ``P`` and postcondition ``Q`` can also be
expressed as contract cases:

.. code-block:: ada

  pragma Contract_Cases (P => Q);


The placement and visibility rules for ``Contract_Cases`` pragmas are
identical to those described for preconditions and postconditions.

The compiler checks that boolean expressions given in case guards and
consequences are valid, where the rules for case guards are the same as
the rule for an expression in ``Precondition`` and the rules for
consequences are the same as the rule for an expression in
``Postcondition``. In particular, attributes ``'Old`` and
``'Result`` can only be used within consequence expressions.
The case guard for the last contract case may be ``others``, to denote
any case not captured by the previous cases. The
following is an example of use within a package spec:


.. code-block:: ada

  package Math_Functions is
     ...
     function Sqrt (Arg : Float) return Float;
     pragma Contract_Cases (((Arg in 0.0 .. 99.0) => Sqrt'Result < 10.0,
                             Arg >= 100.0         => Sqrt'Result >= 10.0,
                             others               => Sqrt'Result = 0.0));
     ...
  end Math_Functions;


The meaning of contract cases is that only one case should apply at each
call, as determined by the corresponding case guard evaluating to True,
and that the consequence for this case should hold when the subprogram
returns.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Convention_Identifier
============================
.. index:: Conventions, synonyms

Syntax:


::

  pragma Convention_Identifier (
           [Name =>]       IDENTIFIER,
           [Convention =>] convention_IDENTIFIER);


This pragma provides a mechanism for supplying synonyms for existing
convention identifiers. The ``Name`` identifier can subsequently
be used as a synonym for the given convention in other pragmas (including
for example pragma ``Import`` or another ``Convention_Identifier``
pragma). As an example of the use of this, suppose you had legacy code
which used Fortran77 as the identifier for Fortran. Then the pragma:


.. code-block:: ada

  pragma Convention_Identifier (Fortran77, Fortran);


would allow the use of the convention identifier ``Fortran77`` in
subsequent code, avoiding the need to modify the sources. As another
example, you could use this to parameterize convention requirements
according to systems. Suppose you needed to use ``Stdcall`` on
windows systems, and ``C`` on some other system, then you could
define a convention identifier ``Library`` and use a single
``Convention_Identifier`` pragma to specify which convention
would be used system-wide.

Pragma CPP_Class
================
.. index:: Interfacing with C++

Syntax:


::

  pragma CPP_Class ([Entity =>] LOCAL_NAME);


The argument denotes an entity in the current declarative region that is
declared as a record type. It indicates that the type corresponds to an
externally declared C++ class type, and is to be laid out the same way
that C++ would lay out the type. If the C++ class has virtual primitives
then the record must be declared as a tagged record type.

Types for which ``CPP_Class`` is specified do not have assignment or
equality operators defined (such operations can be imported or declared
as subprograms as required). Initialization is allowed only by constructor
functions (see pragma ``CPP_Constructor``). Such types are implicitly
limited if not explicitly declared as limited or derived from a limited
type, and an error is issued in that case.

See :ref:`Interfacing_to_C++` for related information.

Note: Pragma ``CPP_Class`` is currently obsolete. It is supported
for backward compatibility but its functionality is available
using pragma ``Import`` with ``Convention`` = ``CPP``.

Pragma CPP_Constructor
======================
.. index:: Interfacing with C++


Syntax:


::

  pragma CPP_Constructor ([Entity =>] LOCAL_NAME
    [, [External_Name =>] static_string_EXPRESSION ]
    [, [Link_Name     =>] static_string_EXPRESSION ]);


This pragma identifies an imported function (imported in the usual way
with pragma ``Import``) as corresponding to a C++ constructor. If
``External_Name`` and ``Link_Name`` are not specified then the
``Entity`` argument is a name that must have been previously mentioned
in a pragma ``Import`` with ``Convention`` = ``CPP``. Such name
must be of one of the following forms:

*
  **function** ``Fname`` **return** T`

*
  **function** ``Fname`` **return** T'Class

*
  **function** ``Fname`` (...) **return** T`

*
  **function** ``Fname`` (...) **return** T'Class

where ``T`` is a limited record type imported from C++ with pragma
``Import`` and ``Convention`` = ``CPP``.

The first two forms import the default constructor, used when an object
of type ``T`` is created on the Ada side with no explicit constructor.
The latter two forms cover all the non-default constructors of the type.
See the GNAT User's Guide for details.

If no constructors are imported, it is impossible to create any objects
on the Ada side and the type is implicitly declared abstract.

Pragma ``CPP_Constructor`` is intended primarily for automatic generation
using an automatic binding generator tool (such as the :switch:`-fdump-ada-spec`
GCC switch).
See :ref:`Interfacing_to_C++` for more related information.

Note: The use of functions returning class-wide types for constructors is
currently obsolete. They are supported for backward compatibility. The
use of functions returning the type T leave the Ada sources more clear
because the imported C++ constructors always return an object of type T;
that is, they never return an object whose type is a descendant of type T.

Pragma CPP_Virtual
==================
.. index:: Interfacing to C++


This pragma is now obsolete and, other than generating a warning if warnings
on obsolescent features are enabled, is completely ignored.
It is retained for compatibility
purposes. It used to be required to ensure compatibility with C++, but
is no longer required for that purpose because GNAT generates
the same object layout as the G++ compiler by default.

See :ref:`Interfacing_to_C++` for related information.

Pragma CPP_Vtable
=================
.. index:: Interfacing with C++


This pragma is now obsolete and, other than generating a warning if warnings
on obsolescent features are enabled, is completely ignored.
It used to be required to ensure compatibility with C++, but
is no longer required for that purpose because GNAT generates
the same object layout as the G++ compiler by default.

See :ref:`Interfacing_to_C++` for related information.

Pragma CPU
==========

Syntax:


.. code-block:: ada

  pragma CPU (EXPRESSION);


This pragma is standard in Ada 2012, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

Pragma Deadline_Floor
=====================

Syntax:


.. code-block:: ada

  pragma Deadline_Floor (time_span_EXPRESSION);


This pragma applies only to protected types and specifies the floor
deadline inherited by a task when the task enters a protected object.
It is effective only when the EDF scheduling policy is used.

Pragma Debug
============

Syntax:


::

  pragma Debug ([CONDITION, ]PROCEDURE_CALL_WITHOUT_SEMICOLON);

  PROCEDURE_CALL_WITHOUT_SEMICOLON ::=
    PROCEDURE_NAME
  | PROCEDURE_PREFIX ACTUAL_PARAMETER_PART


The procedure call argument has the syntactic form of an expression, meeting
the syntactic requirements for pragmas.

If debug pragmas are not enabled or if the condition is present and evaluates
to False, this pragma has no effect. If debug pragmas are enabled, the
semantics of the pragma is exactly equivalent to the procedure call statement
corresponding to the argument with a terminating semicolon. Pragmas are
permitted in sequences of declarations, so you can use pragma ``Debug`` to
intersperse calls to debug procedures in the middle of declarations. Debug
pragmas can be enabled either by use of the command line switch *-gnata*
or by use of the pragma ``Check_Policy`` with a first argument of
``Debug``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Debug_Policy
===================

Syntax:


.. code-block:: ada

  pragma Debug_Policy (CHECK | DISABLE | IGNORE | ON | OFF);


This pragma is equivalent to a corresponding ``Check_Policy`` pragma
with a first argument of ``Debug``. It is retained for historical
compatibility reasons.

.. _Pragma-Default_Initial_Condition:

Pragma Default_Initial_Condition
================================

Syntax:

.. code-block:: ada

  pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect
``Default_Initial_Condition`` in the SPARK 2014 Reference Manual, section 7.3.3.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Default_Scalar_Storage_Order
===================================
.. index:: Default_Scalar_Storage_Order

.. index:: Scalar_Storage_Order


Syntax:


.. code-block:: ada

  pragma Default_Scalar_Storage_Order (High_Order_First | Low_Order_First);


Normally if no explicit ``Scalar_Storage_Order`` is given for a record
type or array type, then the scalar storage order defaults to the ordinary
default for the target. But this default may be overridden using this pragma.
The pragma may appear as a configuration pragma, or locally within a package
spec or declarative part. In the latter case, it applies to all subsequent
types declared within that package spec or declarative part.

The following example shows the use of this pragma:


.. code-block:: ada

  pragma Default_Scalar_Storage_Order (High_Order_First);
  with System; use System;
  package DSSO1 is
     type H1 is record
        a : Integer;
     end record;

     type L2 is record
        a : Integer;
     end record;
     for L2'Scalar_Storage_Order use Low_Order_First;

     type L2a is new L2;

     package Inner is
        type H3 is record
           a : Integer;
        end record;

        pragma Default_Scalar_Storage_Order (Low_Order_First);

        type L4 is record
           a : Integer;
        end record;
     end Inner;

     type H4a is new Inner.L4;

     type H5 is record
        a : Integer;
     end record;
  end DSSO1;


In this example record types with names starting with *L* have `Low_Order_First` scalar
storage order, and record types with names starting with *H* have ``High_Order_First``.
Note that in the case of ``H4a``, the order is not inherited
from the parent type. Only an explicitly set ``Scalar_Storage_Order``
gets inherited on type derivation.

If this pragma is used as a configuration pragma which appears within a
configuration pragma file (as opposed to appearing explicitly at the start
of a single unit), then the binder will require that all units in a partition
be compiled in a similar manner, other than run-time units, which are not
affected by this pragma. Note that the use of this form is discouraged because
it may significantly degrade the run-time performance of the software, instead
the default scalar storage order ought to be changed only on a local basis.

Pragma Default_Storage_Pool
===========================
.. index:: Default_Storage_Pool


Syntax:


.. code-block:: ada

  pragma Default_Storage_Pool (storage_pool_NAME | null);


This pragma is standard in Ada 2012, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

.. _Pragma-Depends:

Pragma Depends
==============

Syntax:

.. code-block:: ada

  pragma Depends (DEPENDENCY_RELATION);

  DEPENDENCY_RELATION ::=
       null
    | (DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE})

  DEPENDENCY_CLAUSE ::=
      OUTPUT_LIST =>[+] INPUT_LIST
    | NULL_DEPENDENCY_CLAUSE

  NULL_DEPENDENCY_CLAUSE ::= null => INPUT_LIST

  OUTPUT_LIST ::= OUTPUT | (OUTPUT {, OUTPUT})

  INPUT_LIST ::= null | INPUT | (INPUT {, INPUT})

  OUTPUT ::= NAME | FUNCTION_RESULT
  INPUT  ::= NAME

  where FUNCTION_RESULT is a function Result attribute_reference

For the semantics of this pragma, see the entry for aspect ``Depends`` in the
SPARK 2014 Reference Manual, section 6.1.5.

Pragma Detect_Blocking
======================

Syntax:

.. code-block:: ada

  pragma Detect_Blocking;


This is a standard pragma in Ada 2005, that is available in all earlier
versions of Ada as an implementation-defined pragma.

This is a configuration pragma that forces the detection of potentially
blocking operations within a protected operation, and to raise Program_Error
if that happens.

Pragma Disable_Atomic_Synchronization
=====================================

.. index:: Atomic Synchronization

Syntax:

::

  pragma Disable_Atomic_Synchronization [(Entity)];

  pragma Enable_Atomic_Synchronization [(Entity)];

Ada requires that accesses (reads or writes) of an atomic variable be
regarded as synchronization points in the case of multiple tasks.
Particularly in the case of multi-processors this may require special
handling, e.g. the generation of memory barriers. This synchronization
is performed by default, but can be turned off using pragma
``Disable_Atomic_Synchronization``.
The ``Enable_Atomic_Synchronization`` pragma turns it back on.

The placement and scope rules for these pragmas are the same as those
for ``pragma Suppress``. In particular they can be used as
configuration pragmas, or in a declaration sequence where they apply
until the end of the scope. If an ``Entity`` argument is present,
the action applies only to that entity.

Pragma Dispatching_Domain
=========================

Syntax:


.. code-block:: ada

  pragma Dispatching_Domain (EXPRESSION);


This pragma is standard in Ada 2012, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

.. _Pragma-Effective_Reads:

Pragma Effective_Reads
======================

Syntax:

.. code-block:: ada

  pragma Effective_Reads [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Effective_Reads`` in
the SPARK 2014 Reference Manual, section 7.1.2.

.. _Pragma-Effective_Writes:

Pragma Effective_Writes
=======================

Syntax:

.. code-block:: ada

  pragma Effective_Writes [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Effective_Writes``
in the SPARK 2014 Reference Manual, section 7.1.2.

Pragma Elaboration_Checks
=========================
.. index:: Elaboration control


Syntax:


.. code-block:: ada

  pragma Elaboration_Checks (Dynamic | Static);


This is a configuration pragma which specifies the elaboration model to be
used during compilation. For more information on the elaboration models of
GNAT, consult the chapter on elaboration order handling in the *GNAT User's
Guide*.

The pragma may appear in the following contexts:

* Configuration pragmas file

* Prior to the context clauses of a compilation unit's initial declaration

Any other placement of the pragma will result in a warning and the effects of
the offending pragma will be ignored.

If the pragma argument is ``Dynamic``, then the dynamic elaboration model is in
effect. If the pragma argument is ``Static``, then the static elaboration model
is in effect.

Pragma Eliminate
================
.. index:: Elimination of unused subprograms


Syntax:


::

   pragma Eliminate (
               [  Unit_Name       => ] IDENTIFIER | SELECTED_COMPONENT ,
               [  Entity          => ] IDENTIFIER |
                                       SELECTED_COMPONENT |
                                       STRING_LITERAL
               [, Source_Location =>   SOURCE_TRACE ] );

           SOURCE_TRACE    ::= STRING_LITERAL


This pragma indicates that the given entity is not used in the program to be
compiled and built, thus allowing the compiler to
eliminate the code or data associated with the named entity. Any reference to
an eliminated entity causes a compile-time or link-time error.

The pragma has the following semantics, where ``U`` is the unit specified by
the ``Unit_Name`` argument and ``E`` is the entity specified by the ``Entity``
argument:

* ``E`` must be a subprogram that is explicitly declared either:

  * Within ``U``, or
  * Within a generic package that is instantiated in ``U``, or
  * As an instance of generic subprogram instantiated in ``U``.

  Otherwise the pragma is ignored.

* If ``E`` is overloaded within ``U`` then, in the absence of a
  ``Source_Location`` argument, all overloadings are eliminated.
* If ``E`` is overloaded within ``U`` and only some overloadings
  are to be eliminated, then each overloading to be eliminated
  must be specified in a corresponding pragma ``Eliminate``
  with a ``Source_Location`` argument identifying the line where the
  declaration appears, as described below.
* If ``E`` is declared as the result of a generic instantiation, then
  a ``Source_Location`` argument is needed, as described below.

Pragma ``Eliminate`` allows a program to be compiled in a system-independent
manner, so that unused entities are eliminated but without
needing to modify the source text. Normally the required set of
``Eliminate`` pragmas is constructed automatically using the ``gnatelim`` tool.

Any source file change that removes, splits, or
adds lines may make the set of ``Eliminate`` pragmas invalid because their
``Source_Location`` argument values may get out of date.

Pragma ``Eliminate`` may be used where the referenced entity is a dispatching
operation. In this case all the subprograms to which the given operation can
dispatch are considered to be unused (are never called as a result of a direct
or a dispatching call).

The string literal given for the source location specifies the line number
of the declaration of the entity, using the following syntax for ``SOURCE_TRACE``:

::

   SOURCE_TRACE     ::= SOURCE_REFERENCE [ LBRACKET SOURCE_TRACE RBRACKET ]

   LBRACKET         ::= '['
   RBRACKET         ::= ']'

   SOURCE_REFERENCE ::= FILE_NAME : LINE_NUMBER

   LINE_NUMBER      ::= DIGIT {DIGIT}


Spaces around the colon in a ``SOURCE_REFERENCE`` are optional.

The source trace that is given as the ``Source_Location`` must obey the
following rules (or else the pragma is ignored), where ``U`` is
the unit ``U`` specified by the ``Unit_Name`` argument and ``E`` is the
subprogram specified by the ``Entity`` argument:

*  ``FILE_NAME`` is the short name (with no directory
   information) of the Ada source file for ``U``, using the required syntax
   for the underlying file system (e.g. case is significant if the underlying
   operating system is case sensitive).
   If ``U`` is a package and ``E`` is a subprogram declared in the package
   specification and its full declaration appears in the package body,
   then the  relevant source file is the one for the package specification;
   analogously if ``U`` is a generic package.

*  If ``E`` is not declared in a generic instantiation (this includes
   generic subprogram instances), the source trace includes only one source
   line reference. ``LINE_NUMBER`` gives the line number of the occurrence
   of the declaration of ``E`` within the source file (as a decimal literal
   without an exponent or point).

*  If ``E`` is declared by a generic instantiation, its source trace
   (from left to right) starts with the source location of the
   declaration of ``E`` in the generic unit and ends with the source
   location of the instantiation, given in square brackets. This approach is
   applied recursively with nested instantiations: the rightmost (nested
   most deeply in square brackets) element of the source trace is the location
   of the outermost instantiation, and the leftmost element (that is, outside
   of any square brackets) is the location of the declaration of ``E`` in
   the generic unit.

Examples:

   .. code-block:: ada

      pragma Eliminate (Pkg0, Proc);
      -- Eliminate (all overloadings of) Proc in Pkg0

      pragma Eliminate (Pkg1, Proc,
                        Source_Location => "pkg1.ads:8");
      -- Eliminate overloading of Proc at line 8 in pkg1.ads

      -- Assume the following file contents:
      --   gen_pkg.ads
      --   1: generic
      --   2:   type T is private;
      --   3: package Gen_Pkg is
      --   4:   procedure Proc(N : T);
      --  ...   ...
      --  ... end Gen_Pkg;
      --
      --    q.adb
      --   1: with Gen_Pkg;
      --   2: procedure Q is
      --   3:   package Inst_Pkg is new Gen_Pkg(Integer);
      --  ...   -- No calls on Inst_Pkg.Proc
      --  ... end Q;

      -- The following pragma eliminates Inst_Pkg.Proc from Q
      pragma Eliminate (Q, Proc,
                        Source_Location => "gen_pkg.ads:4[q.adb:3]");



Pragma Enable_Atomic_Synchronization
====================================
.. index:: Atomic Synchronization


Syntax:


::

  pragma Enable_Atomic_Synchronization [(Entity)];

Reenables atomic synchronization; see ``pragma Disable_Atomic_Synchronization``
for details.

Pragma Exceptional_Cases
========================
.. index:: Exceptional_Cases

Syntax:


::

  pragma Exceptional_Cases (EXCEPTIONAL_CASE_LIST);

  EXCEPTIONAL_CASE_LIST ::= EXCEPTIONAL_CASE {, EXCEPTIONAL_CASE}
  EXCEPTIONAL_CASE      ::= exception_choice {'|' exception_choice} => CONSEQUENCE
  CONSEQUENCE           ::= Boolean_expression

For the semantics of this aspect, see the SPARK 2014 Reference Manual, section
6.1.9.

Pragma Exit_Cases
=================
.. index:: Exit_Cases

Syntax:

::

  pragma Exit_Cases (EXIT_CASE_LIST);

  EXIT_CASE_LIST ::= EXIT_CASE {, EXIT_CASE}
  EXIT_CASE      ::= GUARD => EXIT_KIND
  EXIT_KIND      ::= Normal_Return
                   | Exception_Raised
                   | (Exception_Raised => exception_name)
                   | Program_Exit
  GUARD          ::= Boolean_expression

For the semantics of this aspect, see the SPARK 2014 Reference Manual, section
6.1.10.

Pragma Export_Function
======================
.. index:: Argument passing mechanisms


Syntax:


::

  pragma Export_Function (
       [Internal         =>] LOCAL_NAME
    [, [External         =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types  =>] PARAMETER_TYPES]
    [, [Result_Type      =>] result_SUBTYPE_MARK]
    [, [Mechanism        =>] MECHANISM]
    [, [Result_Mechanism =>] MECHANISM_NAME]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION
  | ""

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::= Value | Reference


Use this pragma to make a function externally callable and optionally
provide information on mechanisms to be used for passing parameter and
result values.  We recommend, for the purposes of improving portability,
this pragma always be used in conjunction with a separate pragma
``Export``, which must precede the pragma ``Export_Function``.
GNAT does not require a separate pragma ``Export``, but if none is
present, ``Convention Ada`` is assumed, which is usually
not what is wanted, so it is usually appropriate to use this
pragma in conjunction with a ``Export`` or ``Convention``
pragma that specifies the desired foreign convention.
Pragma ``Export_Function``
(and ``Export``, if present) must appear in the same declarative
region as the function to which they apply.

The ``internal_name`` must uniquely designate the function to which the
pragma applies.  If more than one function name exists of this name in
the declarative part you must use the ``Parameter_Types`` and
``Result_Type`` parameters to achieve the required
unique designation.  The `subtype_mark`\ s in these parameters must
exactly match the subtypes in the corresponding function specification,
using positional notation to match parameters with subtype marks.
The form with an ``'Access`` attribute can be used to match an
anonymous access parameter.

.. index:: Suppressing external name

Special treatment is given if the EXTERNAL is an explicit null
string or a static string expressions that evaluates to the null
string. In this case, no external name is generated. This form
still allows the specification of parameter mechanisms.

Pragma Export_Object
====================

Syntax:


::

  pragma Export_Object (
        [Internal =>] LOCAL_NAME
     [, [External =>] EXTERNAL_SYMBOL]
     [, [Size     =>] EXTERNAL_SYMBOL]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION


This pragma designates an object as exported, and apart from the
extended rules for external symbols, is identical in effect to the use of
the normal ``Export`` pragma applied to an object.  You may use a
separate Export pragma (and you probably should from the point of view
of portability), but it is not required.  ``Size`` is syntax checked,
but otherwise ignored by GNAT.

Pragma Export_Procedure
=======================

Syntax:


::

  pragma Export_Procedure (
       [Internal        =>] LOCAL_NAME
    [, [External        =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types =>] PARAMETER_TYPES]
    [, [Mechanism       =>] MECHANISM]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION
  | ""

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::= Value | Reference


This pragma is identical to ``Export_Function`` except that it
applies to a procedure rather than a function and the parameters
``Result_Type`` and ``Result_Mechanism`` are not permitted.
GNAT does not require a separate pragma ``Export``, but if none is
present, ``Convention Ada`` is assumed, which is usually
not what is wanted, so it is usually appropriate to use this
pragma in conjunction with a ``Export`` or ``Convention``
pragma that specifies the desired foreign convention.

.. index:: Suppressing external name

Special treatment is given if the EXTERNAL is an explicit null
string or a static string expressions that evaluates to the null
string. In this case, no external name is generated. This form
still allows the specification of parameter mechanisms.

Pragma Export_Valued_Procedure
==============================

Syntax:


::

  pragma Export_Valued_Procedure (
       [Internal        =>] LOCAL_NAME
    [, [External        =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types =>] PARAMETER_TYPES]
    [, [Mechanism       =>] MECHANISM]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION
  | ""

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::= Value | Reference


This pragma is identical to ``Export_Procedure`` except that the
first parameter of ``LOCAL_NAME``, which must be present, must be of
mode ``out``, and externally the subprogram is treated as a function
with this parameter as the result of the function.  GNAT provides for
this capability to allow the use of ``out`` and ``in out``
parameters in interfacing to external functions (which are not permitted
in Ada functions).
GNAT does not require a separate pragma ``Export``, but if none is
present, ``Convention Ada`` is assumed, which is almost certainly
not what is wanted since the whole point of this pragma is to interface
with foreign language functions, so it is usually appropriate to use this
pragma in conjunction with a ``Export`` or ``Convention``
pragma that specifies the desired foreign convention.

.. index:: Suppressing external name

Special treatment is given if the EXTERNAL is an explicit null
string or a static string expressions that evaluates to the null
string. In this case, no external name is generated. This form
still allows the specification of parameter mechanisms.

Pragma Extend_System
====================
.. index:: System, extending

.. index:: DEC Ada 83


Syntax:


::

  pragma Extend_System ([Name =>] IDENTIFIER);


This pragma is used to provide backwards compatibility with other
implementations that extend the facilities of package ``System``.  In
GNAT, ``System`` contains only the definitions that are present in
the Ada RM.  However, other implementations, notably the DEC Ada 83
implementation, provide many extensions to package ``System``.

For each such implementation accommodated by this pragma, GNAT provides a
package :samp:`Aux_{xxx}`, e.g., ``Aux_DEC`` for the DEC Ada 83
implementation, which provides the required additional definitions.  You
can use this package in two ways.  You can ``with`` it in the normal
way and access entities either by selection or using a ``use``
clause.  In this case no special processing is required.

However, if existing code contains references such as
:samp:`System.{xxx}` where *xxx* is an entity in the extended
definitions provided in package ``System``, you may use this pragma
to extend visibility in ``System`` in a non-standard way that
provides greater compatibility with the existing code.  Pragma
``Extend_System`` is a configuration pragma whose single argument is
the name of the package containing the extended definition
(e.g., ``Aux_DEC`` for the DEC Ada case).  A unit compiled under
control of this pragma will be processed using special visibility
processing that looks in package :samp:`System.Aux_{xxx}` where
:samp:`Aux_{xxx}` is the pragma argument for any entity referenced in
package ``System``, but not found in package ``System``.

You can use this pragma either to access a predefined ``System``
extension supplied with the compiler, for example ``Aux_DEC`` or
you can construct your own extension unit following the above
definition.  Note that such a package is a child of ``System``
and thus is considered part of the implementation.
To compile it you will have to use the *-gnatg* switch
for compiling System units, as explained in the
GNAT User's Guide.

.. _Pragma_Extensions_Allowed:

Pragma Extensions_Allowed
=========================
.. index:: Ada Extensions

.. index:: GNAT Extensions


Syntax:

.. code-block:: ada

  pragma Extensions_Allowed (On | Off | All_Extensions);


This configuration pragma enables (via the "On" or "All_Extensions" argument)
or disables (via the "Off" argument) the implementation extension mode; the
pragma takes precedence over the ``-gnatX`` and ``-gnatX0`` command switches.

If an argument of ``"On"`` is specified, the latest version of the Ada language
is implemented (currently Ada 2022) and, in addition, a curated set of GNAT
specific extensions are recognized. (See the list here
:ref:`here<Curated_Language_Extensions>`)

An argument of ``"All_Extensions"`` has the same effect except that some extra
experimental extensions are enabled (See the list here
:ref:`here<Experimental_Language_Extensions>`)

.. _Pragma-Extensions_Visible:

Pragma Extensions_Visible
=========================

Syntax:

.. code-block:: ada

  pragma Extensions_Visible [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Extensions_Visible``
in the SPARK 2014 Reference Manual, section 6.1.7.

Pragma External
===============

Syntax:


::

  pragma External (
    [   Convention    =>] convention_IDENTIFIER,
    [   Entity        =>] LOCAL_NAME
    [, [External_Name =>] static_string_EXPRESSION ]
    [, [Link_Name     =>] static_string_EXPRESSION ]);


This pragma is identical in syntax and semantics to pragma
``Export`` as defined in the Ada Reference Manual.  It is
provided for compatibility with some Ada 83 compilers that
used this pragma for exactly the same purposes as pragma
``Export`` before the latter was standardized.

Pragma External_Name_Casing
===========================
.. index:: Dec Ada 83 casing compatibility

.. index:: External Names, casing

.. index:: Casing of External names


Syntax:


::

  pragma External_Name_Casing (
    Uppercase | Lowercase
    [, Uppercase | Lowercase | As_Is]);


This pragma provides control over the casing of external names associated
with Import and Export pragmas.  There are two cases to consider:



* Implicit external names

  Implicit external names are derived from identifiers.  The most common case
  arises when a standard Ada Import or Export pragma is used with only two
  arguments, as in:

  .. code-block:: ada

       pragma Import (C, C_Routine);

  Since Ada is a case-insensitive language, the spelling of the identifier in
  the Ada source program does not provide any information on the desired
  casing of the external name, and so a convention is needed.  In GNAT the
  default treatment is that such names are converted to all lower case
  letters.  This corresponds to the normal C style in many environments.
  The first argument of pragma ``External_Name_Casing`` can be used to
  control this treatment.  If ``Uppercase`` is specified, then the name
  will be forced to all uppercase letters.  If ``Lowercase`` is specified,
  then the normal default of all lower case letters will be used.

  This same implicit treatment is also used in the case of extended DEC Ada 83
  compatible Import and Export pragmas where an external name is explicitly
  specified using an identifier rather than a string.


* Explicit external names

  Explicit external names are given as string literals.  The most common case
  arises when a standard Ada Import or Export pragma is used with three
  arguments, as in:

  .. code-block:: ada

    pragma Import (C, C_Routine, "C_routine");

  In this case, the string literal normally provides the exact casing required
  for the external name.  The second argument of pragma
  ``External_Name_Casing`` may be used to modify this behavior.
  If ``Uppercase`` is specified, then the name
  will be forced to all uppercase letters.  If ``Lowercase`` is specified,
  then the name will be forced to all lowercase letters.  A specification of
  ``As_Is`` provides the normal default behavior in which the casing is
  taken from the string provided.

This pragma may appear anywhere that a pragma is valid. In particular, it
can be used as a configuration pragma in the :file:`gnat.adc` file, in which
case it applies to all subsequent compilations, or it can be used as a program
unit pragma, in which case it only applies to the current unit, or it can
be used more locally to control individual Import/Export pragmas.

It was primarily intended for use with OpenVMS systems, where many
compilers convert all symbols to upper case by default.  For interfacing to
such compilers (e.g., the DEC C compiler), it may be convenient to use
the pragma:

.. code-block:: ada

  pragma External_Name_Casing (Uppercase, Uppercase);


to enforce the upper casing of all external symbols.

Pragma Fast_Math
================

Syntax:


.. code-block:: ada

  pragma Fast_Math;


This is a configuration pragma which activates a mode in which speed is
considered more important for floating-point operations than absolutely
accurate adherence to the requirements of the standard. Currently the
following operations are affected:



*Complex Multiplication*
  The normal simple formula for complex multiplication can result in intermediate
  overflows for numbers near the end of the range. The Ada standard requires that
  this situation be detected and corrected by scaling, but in Fast_Math mode such
  cases will simply result in overflow. Note that to take advantage of this you
  must instantiate your own version of ``Ada.Numerics.Generic_Complex_Types``
  under control of the pragma, rather than use the preinstantiated versions.

.. _Pragma-Favor_Top_Level:

Pragma Favor_Top_Level
======================

Syntax:


.. code-block:: ada

  pragma Favor_Top_Level (type_LOCAL_NAME);


The argument of pragma ``Favor_Top_Level`` must be a named access-to-subprogram
type. This pragma is an efficiency hint to the compiler, regarding the use of
``'Access`` or ``'Unrestricted_Access`` on nested (non-library-level) subprograms.
The pragma means that nested subprograms are not used with this type, or are
rare, so that the generated code should be efficient in the top-level case.
When this pragma is used, dynamically generated trampolines may be used on some
targets for nested subprograms. See restriction ``No_Implicit_Dynamic_Code``.

Pragma Finalize_Storage_Only
============================

Syntax:


.. code-block:: ada

  pragma Finalize_Storage_Only (first_subtype_LOCAL_NAME);


The argument of pragma ``Finalize_Storage_Only`` must denote a local type which
is derived from ``Ada.Finalization.Controlled`` or ``Limited_Controlled``. The
pragma suppresses the call to ``Finalize`` for declared library-level objects
of the argument type. This is mostly useful for types where finalization is
only used to deal with storage reclamation since in most environments it is
not necessary to reclaim memory just before terminating execution, hence the
name. Note that this pragma does not suppress Finalize calls for library-level
heap-allocated objects (see pragma ``No_Heap_Finalization``).

Pragma Float_Representation
===========================

Syntax::

  pragma Float_Representation (FLOAT_REP[, float_type_LOCAL_NAME]);

  FLOAT_REP ::= VAX_Float | IEEE_Float


In the one argument form, this pragma is a configuration pragma which
allows control over the internal representation chosen for the predefined
floating point types declared in the packages ``Standard`` and
``System``. This pragma is only provided for compatibility and has no effect.

The two argument form specifies the representation to be used for
the specified floating-point type. The argument must
be ``IEEE_Float`` to specify the use of IEEE format, as follows:

*
  For a digits value of 6, 32-bit IEEE short format will be used.
*
  For a digits value of 15, 64-bit IEEE long format will be used.
*
  No other value of digits is permitted.

.. _Pragma-Ghost:

Pragma Ghost
============

Syntax:

.. code-block:: ada

  pragma Ghost [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Ghost`` in the SPARK
2014 Reference Manual, section 6.9.

.. _Pragma-Global:

Pragma Global
=============

Syntax:

.. code-block:: ada

  pragma Global (GLOBAL_SPECIFICATION);

  GLOBAL_SPECIFICATION ::=
       null
    | (GLOBAL_LIST)
    | (MODED_GLOBAL_LIST {, MODED_GLOBAL_LIST})

  MODED_GLOBAL_LIST ::= MODE_SELECTOR => GLOBAL_LIST

  MODE_SELECTOR ::= In_Out | Input | Output | Proof_In
  GLOBAL_LIST   ::= GLOBAL_ITEM | (GLOBAL_ITEM {, GLOBAL_ITEM})
  GLOBAL_ITEM   ::= NAME

For the semantics of this pragma, see the entry for aspect ``Global`` in the
SPARK 2014 Reference Manual, section 6.1.4.

Pragma Ident
============

Syntax:


.. code-block:: ada

  pragma Ident (static_string_EXPRESSION);


This pragma is identical in effect to pragma ``Comment``. It is provided
for compatibility with other Ada compilers providing this pragma.

Pragma Ignore_Pragma
====================

Syntax:


.. code-block:: ada

  pragma Ignore_Pragma (pragma_IDENTIFIER);

This is a configuration pragma
that takes a single argument that is a simple identifier. Any subsequent
use of a pragma whose pragma identifier matches this argument will be
silently ignored. Any preceding use of a pragma whose pragma identifier
matches this argument will be parsed and then ignored.
This may be useful when legacy code or code intended
for compilation with some other compiler contains pragmas that match the
name, but not the exact implementation, of a GNAT pragma. The use of this
pragma allows such pragmas to be ignored, which may be useful in CodePeer
mode, or during porting of legacy code.

Pragma Implementation_Defined
=============================

Syntax:


.. code-block:: ada

  pragma Implementation_Defined (local_NAME);


This pragma marks a previously declared entity as implementation-defined.
For an overloaded entity, applies to the most recent homonym.


.. code-block:: ada

  pragma Implementation_Defined;


The form with no arguments appears anywhere within a scope, most
typically a package spec, and indicates that all entities that are
defined within the package spec are Implementation_Defined.

This pragma is used within the GNAT runtime library to identify
implementation-defined entities introduced in language-defined units,
for the purpose of implementing the No_Implementation_Identifiers
restriction.

Pragma Implemented
==================

Syntax:


::

  pragma Implemented (procedure_LOCAL_NAME, implementation_kind);

  implementation_kind ::= By_Entry | By_Protected_Procedure | By_Any


This is an Ada 2012 representation pragma which applies to protected, task
and synchronized interface primitives. The use of pragma Implemented provides
a way to impose a static requirement on the overriding operation by adhering
to one of the three implementation kinds: entry, protected procedure or any of
the above. This pragma is available in all earlier versions of Ada as an
implementation-defined pragma.


.. code-block:: ada

  type Synch_Iface is synchronized interface;
  procedure Prim_Op (Obj : in out Iface) is abstract;
  pragma Implemented (Prim_Op, By_Protected_Procedure);

  protected type Prot_1 is new Synch_Iface with
     procedure Prim_Op;  --  Legal
  end Prot_1;

  protected type Prot_2 is new Synch_Iface with
     entry Prim_Op;      --  Illegal
  end Prot_2;

  task type Task_Typ is new Synch_Iface with
     entry Prim_Op;      --  Illegal
  end Task_Typ;


When applied to the procedure_or_entry_NAME of a requeue statement, pragma
Implemented determines the runtime behavior of the requeue. Implementation kind
By_Entry guarantees that the action of requeueing will proceed from an entry to
another entry. Implementation kind By_Protected_Procedure transforms the
requeue into a dispatching call, thus eliminating the chance of blocking. Kind
By_Any shares the behavior of By_Entry and By_Protected_Procedure depending on
the target's overriding subprogram kind.

Pragma Implicit_Packing
=======================
.. index:: Rational Profile

Syntax:


.. code-block:: ada

  pragma Implicit_Packing;


This is a configuration pragma that requests implicit packing for packed
arrays for which a size clause is given but no explicit pragma Pack or
specification of Component_Size is present. It also applies to records
where no record representation clause is present. Consider this example:


.. code-block:: ada

  type R is array (0 .. 7) of Boolean;
  for R'Size use 8;


In accordance with the recommendation in the RM (RM 13.3(53)), a Size clause
does not change the layout of a composite object. So the Size clause in the
above example is normally rejected, since the default layout of the array uses
8-bit components, and thus the array requires a minimum of 64 bits.

If this declaration is compiled in a region of code covered by an occurrence
of the configuration pragma Implicit_Packing, then the Size clause in this
and similar examples will cause implicit packing and thus be accepted. For
this implicit packing to occur, the type in question must be an array of small
components whose size is known at compile time, and the Size clause must
specify the exact size that corresponds to the number of elements in the array
multiplied by the size in bits of the component type (both single and
multi-dimensioned arrays can be controlled with this pragma).

.. index:: Array packing

Similarly, the following example shows the use in the record case


.. code-block:: ada

  type r is record
     a, b, c, d, e, f, g, h : boolean;
     chr                    : character;
  end record;
  for r'size use 16;


Without a pragma Pack, each Boolean field requires 8 bits, so the
minimum size is 72 bits, but with a pragma Pack, 16 bits would be
sufficient. The use of pragma Implicit_Packing allows this record
declaration to compile without an explicit pragma Pack.

Pragma Import_Function
======================

Syntax:


::

  pragma Import_Function (
       [Internal         =>] LOCAL_NAME,
    [, [External         =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types  =>] PARAMETER_TYPES]
    [, [Result_Type      =>] SUBTYPE_MARK]
    [, [Mechanism        =>] MECHANISM]
    [, [Result_Mechanism =>] MECHANISM_NAME]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::=
    Value
  | Reference


This pragma is used in conjunction with a pragma ``Import`` to
specify additional information for an imported function.  The pragma
``Import`` (or equivalent pragma ``Interface``) must precede the
``Import_Function`` pragma and both must appear in the same
declarative part as the function specification.

The ``Internal`` argument must uniquely designate
the function to which the
pragma applies.  If more than one function name exists of this name in
the declarative part you must use the ``Parameter_Types`` and
``Result_Type`` parameters to achieve the required unique
designation.  Subtype marks in these parameters must exactly match the
subtypes in the corresponding function specification, using positional
notation to match parameters with subtype marks.
The form with an ``'Access`` attribute can be used to match an
anonymous access parameter.

You may optionally use the ``Mechanism`` and ``Result_Mechanism``
parameters to specify passing mechanisms for the
parameters and result.  If you specify a single mechanism name, it
applies to all parameters.  Otherwise you may specify a mechanism on a
parameter by parameter basis using either positional or named
notation.  If the mechanism is not specified, the default mechanism
is used.

Pragma Import_Object
====================

Syntax:


::

  pragma Import_Object (
       [Internal =>] LOCAL_NAME
    [, [External =>] EXTERNAL_SYMBOL]
    [, [Size     =>] EXTERNAL_SYMBOL]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION


This pragma designates an object as imported, and apart from the
extended rules for external symbols, is identical in effect to the use of
the normal ``Import`` pragma applied to an object.  Unlike the
subprogram case, you need not use a separate ``Import`` pragma,
although you may do so (and probably should do so from a portability
point of view).  ``size`` is syntax checked, but otherwise ignored by
GNAT.

Pragma Import_Procedure
=======================

Syntax:


::

  pragma Import_Procedure (
       [Internal        =>] LOCAL_NAME
    [, [External        =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types =>] PARAMETER_TYPES]
    [, [Mechanism       =>] MECHANISM]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::= Value | Reference


This pragma is identical to ``Import_Function`` except that it
applies to a procedure rather than a function and the parameters
``Result_Type`` and ``Result_Mechanism`` are not permitted.

Pragma Import_Valued_Procedure
==============================

Syntax:


::

  pragma Import_Valued_Procedure (
       [Internal        =>] LOCAL_NAME
    [, [External        =>] EXTERNAL_SYMBOL]
    [, [Parameter_Types =>] PARAMETER_TYPES]
    [, [Mechanism       =>] MECHANISM]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION

  PARAMETER_TYPES ::=
    null
  | TYPE_DESIGNATOR {, TYPE_DESIGNATOR}

  TYPE_DESIGNATOR ::=
    subtype_NAME
  | subtype_Name ' Access

  MECHANISM ::=
    MECHANISM_NAME
  | (MECHANISM_ASSOCIATION {, MECHANISM_ASSOCIATION})

  MECHANISM_ASSOCIATION ::=
    [formal_parameter_NAME =>] MECHANISM_NAME

  MECHANISM_NAME ::= Value | Reference


This pragma is identical to ``Import_Procedure`` except that the
first parameter of ``LOCAL_NAME``, which must be present, must be of
mode ``out``, and externally the subprogram is treated as a function
with this parameter as the result of the function.  The purpose of this
capability is to allow the use of ``out`` and ``in out``
parameters in interfacing to external functions (which are not permitted
in Ada functions).  You may optionally use the ``Mechanism``
parameters to specify passing mechanisms for the parameters.
If you specify a single mechanism name, it applies to all parameters.
Otherwise you may specify a mechanism on a parameter by parameter
basis using either positional or named notation.  If the mechanism is not
specified, the default mechanism is used.

Note that it is important to use this pragma in conjunction with a separate
pragma Import that specifies the desired convention, since otherwise the
default convention is Ada, which is almost certainly not what is required.

Pragma Independent
==================

Syntax:


.. code-block:: ada

  pragma Independent (component_LOCAL_NAME);


This pragma is standard in Ada 2012 mode (which also provides an aspect
of the same name). It is also available as an implementation-defined
pragma in all earlier versions. It specifies that the
designated object or all objects of the designated type must be
independently addressable. This means that separate tasks can safely
manipulate such objects. For example, if two components of a record are
independent, then two separate tasks may access these two components.
This may place
constraints on the representation of the object (for instance prohibiting
tight packing).

Pragma Independent_Components
=============================

Syntax:


.. code-block:: ada

  pragma Independent_Components (Local_NAME);


This pragma is standard in Ada 2012 mode (which also provides an aspect
of the same name). It is also available as an implementation-defined
pragma in all earlier versions. It specifies that the components of the
designated object, or the components of each object of the designated
type, must be
independently addressable. This means that separate tasks can safely
manipulate separate components in the composite object. This may place
constraints on the representation of the object (for instance prohibiting
tight packing).

.. _Pragma-Initial_Condition:

Pragma Initial_Condition
========================

Syntax:

.. code-block:: ada

  pragma Initial_Condition (boolean_EXPRESSION);

For the semantics of this pragma, see the entry for aspect ``Initial_Condition``
in the SPARK 2014 Reference Manual, section 7.1.6.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Initialize_Scalars
=========================
.. index:: debugging with Initialize_Scalars

Syntax:


.. code-block:: ada

  pragma Initialize_Scalars
    [ ( TYPE_VALUE_PAIR {, TYPE_VALUE_PAIR} ) ];

  TYPE_VALUE_PAIR ::=
    SCALAR_TYPE => static_EXPRESSION

  SCALAR_TYPE :=
    Short_Float
  | Float
  | Long_Float
  | Long_Long_Flat
  | Signed_8
  | Signed_16
  | Signed_32
  | Signed_64
  | Unsigned_8
  | Unsigned_16
  | Unsigned_32
  | Unsigned_64


This pragma is similar to ``Normalize_Scalars`` conceptually but has two
important differences.

First, there is no requirement for the pragma to be used uniformly in all units
of a partition. In particular, it is fine to use this just for some or all of
the application units of a partition, without needing to recompile the run-time
library. In the case where some units are compiled with the pragma, and some
without, then a declaration of a variable where the type is defined in package
Standard or is locally declared will always be subject to initialization, as
will any declaration of a scalar variable. For composite variables, whether the
variable is initialized may also depend on whether the package in which the
type of the variable is declared is compiled with the pragma.

The other important difference is that the programmer can control the value
used for initializing scalar objects. This effect can be achieved in several
different ways:

* At compile time, the programmer can specify the invalid value for a
  particular family of scalar types using the optional arguments of the pragma.

  The compile-time approach is intended to optimize the generated code for the
  pragma, by possibly using fast operations such as ``memset``. Note that such
  optimizations require using values where the bytes all have the same binary
  representation.

* At bind time, the programmer has several options:

  * Initialization with invalid values (similar to Normalize_Scalars, though
    for Initialize_Scalars it is not always possible to determine the invalid
    values in complex cases like signed component fields with nonstandard
    sizes).

  * Initialization with high values.

  * Initialization with low values.

  * Initialization with a specific bit pattern.

  See the GNAT User's Guide for binder options for specifying these cases.

  The bind-time approach is intended to provide fast turnaround for testing
  with different values, without having to recompile the program.

* At execution time, the programmer can specify the invalid values using an
  environment variable. See the GNAT User's Guide for details.

  The execution-time approach is intended to provide fast turnaround for
  testing with different values, without having to recompile and rebind the
  program.

Note that pragma ``Initialize_Scalars`` is particularly useful in conjunction
with the enhanced validity checking that is now provided in GNAT, which checks
for invalid values under more conditions. Using this feature (see description
of the *-gnatV* flag in the GNAT User's Guide) in conjunction with pragma
``Initialize_Scalars`` provides a powerful new tool to assist in the detection
of problems caused by uninitialized variables.

Note: the use of ``Initialize_Scalars`` has a fairly extensive effect on the
generated code. This may cause your code to be substantially larger. It may
also cause an increase in the amount of stack required, so it is probably a
good idea to turn on stack checking (see description of stack checking in the
GNAT User's Guide) when using this pragma.

.. _Pragma-Initializes:

Pragma Initializes
==================

Syntax:

.. code-block:: ada

  pragma Initializes (INITIALIZATION_LIST);

  INITIALIZATION_LIST ::=
       null
    | (INITIALIZATION_ITEM {, INITIALIZATION_ITEM})

  INITIALIZATION_ITEM ::= name [=> INPUT_LIST]

  INPUT_LIST ::=
       null
    |  INPUT
    | (INPUT {, INPUT})

  INPUT ::= name

For the semantics of this pragma, see the entry for aspect ``Initializes`` in the
SPARK 2014 Reference Manual, section 7.1.5.

.. _Pragma-Inline_Always:

Pragma Inline_Always
====================

Syntax:


::

  pragma Inline_Always (NAME [, NAME]);


Similar to pragma ``Inline`` except that inlining is unconditional.
Inline_Always instructs the compiler to inline every direct call to the
subprogram or else to emit a compilation error, independently of any
option, in particular *-gnatn* or *-gnatN* or the optimization level.
It is an error to take the address or access of ``NAME``. It is also an error to
apply this pragma to a primitive operation of a tagged type. Thanks to such
restrictions, the compiler is allowed to remove the out-of-line body of ``NAME``.

Pragma Inline_Generic
=====================

Syntax:


::

  pragma Inline_Generic (GNAME {, GNAME});

  GNAME ::= generic_unit_NAME | generic_instance_NAME


This pragma is provided for compatibility with Dec Ada 83. It has
no effect in GNAT (which always inlines generics), other
than to check that the given names are all names of generic units or
generic instances.

Pragma Interface
================

Syntax:


::

  pragma Interface (
       [Convention    =>] convention_identifier,
       [Entity        =>] local_NAME
    [, [External_Name =>] static_string_expression]
    [, [Link_Name     =>] static_string_expression]);


This pragma is identical in syntax and semantics to
the standard Ada pragma ``Import``.  It is provided for compatibility
with Ada 83.  The definition is upwards compatible both with pragma
``Interface`` as defined in the Ada 83 Reference Manual, and also
with some extended implementations of this pragma in certain Ada 83
implementations.  The only difference between pragma ``Interface``
and pragma ``Import`` is that there is special circuitry to allow
both pragmas to appear for the same subprogram entity (normally it
is illegal to have multiple ``Import`` pragmas). This is useful in
maintaining Ada 83/Ada 95 compatibility and is compatible with other
Ada 83 compilers.

Pragma Interface_Name
=====================

Syntax:


::

  pragma Interface_Name (
       [Entity        =>] LOCAL_NAME
    [, [External_Name =>] static_string_EXPRESSION]
    [, [Link_Name     =>] static_string_EXPRESSION]);


This pragma provides an alternative way of specifying the interface name
for an interfaced subprogram, and is provided for compatibility with Ada
83 compilers that use the pragma for this purpose.  You must provide at
least one of ``External_Name`` or ``Link_Name``.

Pragma Interrupt_Handler
========================

Syntax:


.. code-block:: ada

  pragma Interrupt_Handler (procedure_LOCAL_NAME);


This program unit pragma is supported for parameterless protected procedures
as described in Annex C of the Ada Reference Manual.

Pragma Interrupt_State
======================

Syntax:


::

  pragma Interrupt_State
   ([Name  =>] value,
    [State =>] SYSTEM | RUNTIME | USER);


Normally certain interrupts are reserved to the implementation.  Any attempt
to attach an interrupt causes Program_Error to be raised, as described in
RM C.3.2(22).  A typical example is the ``SIGINT`` interrupt used in
many systems for an :kbd:`Ctrl-C` interrupt.  Normally this interrupt is
reserved to the implementation, so that :kbd:`Ctrl-C` can be used to
interrupt execution.  Additionally, signals such as ``SIGSEGV``,
``SIGABRT``, ``SIGFPE`` and ``SIGILL`` are often mapped to specific
Ada exceptions, or used to implement run-time functions such as the
``abort`` statement and stack overflow checking.

Pragma ``Interrupt_State`` provides a general mechanism for overriding
such uses of interrupts.  It subsumes the functionality of pragma
``Unreserve_All_Interrupts``.  Pragma ``Interrupt_State`` is not
available on Windows.  On all other platforms than VxWorks,
it applies to signals; on VxWorks, it applies to vectored hardware interrupts
and may be used to mark interrupts required by the board support package
as reserved.

Interrupts can be in one of three states:

* System

  The interrupt is reserved (no Ada handler can be installed), and the
  Ada run-time may not install a handler. As a result you are guaranteed
  standard system default action if this interrupt is raised. This also allows
  installing a low level handler via C APIs such as sigaction(), outside
  of Ada control.

* Runtime

  The interrupt is reserved (no Ada handler can be installed). The run time
  is allowed to install a handler for internal control purposes, but is
  not required to do so.

* User

  The interrupt is unreserved.  The user may install an Ada handler via
  Ada.Interrupts and pragma Interrupt_Handler or Attach_Handler to provide
  some other action.

These states are the allowed values of the ``State`` parameter of the
pragma.  The ``Name`` parameter is a value of the type
``Ada.Interrupts.Interrupt_ID``.  Typically, it is a name declared in
``Ada.Interrupts.Names``.

This is a configuration pragma, and the binder will check that there
are no inconsistencies between different units in a partition in how a
given interrupt is specified. It may appear anywhere a pragma is legal.

The effect is to move the interrupt to the specified state.

By declaring interrupts to be SYSTEM, you guarantee the standard system
action, such as a core dump.

By declaring interrupts to be USER, you guarantee that you can install
a handler.

Note that certain signals on many operating systems cannot be caught and
handled by applications.  In such cases, the pragma is ignored.  See the
operating system documentation, or the value of the array ``Reserved``
declared in the spec of package ``System.OS_Interface``.

Overriding the default state of signals used by the Ada runtime may interfere
with an application's runtime behavior in the cases of the synchronous signals,
and in the case of the signal used to implement the ``abort`` statement.

Pragma Interrupts_System_By_Default
===================================

Syntax:


::

  pragma Interrupts_System_By_Default;

Default all interrupts to the System state as defined above in pragma
``Interrupt_State``. This is a configuration pragma.

.. _Pragma-Invariant:

Pragma Invariant
================

Syntax:


::

  pragma Invariant
    ([Entity =>]    private_type_LOCAL_NAME,
     [Check  =>]    EXPRESSION
     [,[Message =>] String_Expression]);


This pragma provides exactly the same capabilities as the Type_Invariant aspect
defined in AI05-0146-1, and in the Ada 2012 Reference Manual. The
Type_Invariant aspect is fully implemented in Ada 2012 mode, but since it
requires the use of the aspect syntax, which is not available except in 2012
mode, it is not possible to use the Type_Invariant aspect in earlier versions
of Ada. However the Invariant pragma may be used in any version of Ada. Also
note that the aspect Invariant is a synonym in GNAT for the aspect
Type_Invariant, but there is no pragma Type_Invariant.

The pragma must appear within the visible part of the package specification,
after the type to which its Entity argument appears. As with the Invariant
aspect, the Check expression is not analyzed until the end of the visible
part of the package, so it may contain forward references. The Message
argument, if present, provides the exception message used if the invariant
is violated. If no Message parameter is provided, a default message that
identifies the line on which the pragma appears is used.

It is permissible to have multiple Invariants for the same type entity, in
which case they are and'ed together. It is permissible to use this pragma
in Ada 2012 mode, but you cannot have both an invariant aspect and an
invariant pragma for the same entity.

For further details on the use of this pragma, see the Ada 2012 documentation
of the Type_Invariant aspect.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Keep_Names
=================

Syntax:


::

  pragma Keep_Names ([On =>] enumeration_first_subtype_LOCAL_NAME);


The ``LOCAL_NAME`` argument
must refer to an enumeration first subtype
in the current declarative part. The effect is to retain the enumeration
literal names for use by ``Image`` and ``Value`` even if a global
``Discard_Names`` pragma applies. This is useful when you want to
generally suppress enumeration literal names and for example you therefore
use a ``Discard_Names`` pragma in the :file:`gnat.adc` file, but you
want to retain the names for specific enumeration types.

Pragma License
==============
.. index:: License checking

Syntax:


.. code-block:: ada

  pragma License (Unrestricted | GPL | Modified_GPL | Restricted);


This pragma is provided to allow automated checking for appropriate license
conditions with respect to the standard and modified GPL.  A pragma
``License``, which is a configuration pragma that typically appears at
the start of a source file or in a separate :file:`gnat.adc` file, specifies
the licensing conditions of a unit as follows:

* Unrestricted
  This is used for a unit that can be freely used with no license restrictions.
  Examples of such units are public domain units, and units from the Ada
  Reference Manual.

* GPL
  This is used for a unit that is licensed under the unmodified GPL, and which
  therefore cannot be ``with``\ ed by a restricted unit.

* Modified_GPL
  This is used for a unit licensed under the GNAT modified GPL that includes
  a special exception paragraph that specifically permits the inclusion of
  the unit in programs without requiring the entire program to be released
  under the GPL.

* Restricted
  This is used for a unit that is restricted in that it is not permitted to
  depend on units that are licensed under the GPL.  Typical examples are
  proprietary code that is to be released under more restrictive license
  conditions.  Note that restricted units are permitted to ``with`` units
  which are licensed under the modified GPL (this is the whole point of the
  modified GPL).


Normally a unit with no ``License`` pragma is considered to have an
unknown license, and no checking is done.  However, standard GNAT headers
are recognized, and license information is derived from them as follows.

A GNAT license header starts with a line containing 78 hyphens.  The following
comment text is searched for the appearance of any of the following strings.

If the string 'GNU General Public License' is found, then the unit is assumed
to have GPL license, unless the string 'As a special exception' follows, in
which case the license is assumed to be modified GPL.

If one of the strings
'This specification is adapted from the Ada Semantic Interface' or
'This specification is derived from the Ada Reference Manual' is found
then the unit is assumed to be unrestricted.

These default actions means that a program with a restricted license pragma
will automatically get warnings if a GPL unit is inappropriately
``with``\ ed.  For example, the program:

.. code-block:: ada

  with Sem_Ch3;
  with GNAT.Sockets;
  procedure Secret_Stuff is
    ...
  end Secret_Stuff


if compiled with pragma ``License`` (``Restricted``) in a
:file:`gnat.adc` file will generate the warning::

  1.  with Sem_Ch3;
          |
     >>> license of withed unit "Sem_Ch3" is incompatible

  2.  with GNAT.Sockets;
  3.  procedure Secret_Stuff is


Here we get a warning on ``Sem_Ch3`` since it is part of the GNAT
compiler and is licensed under the
GPL, but no warning for ``GNAT.Sockets`` which is part of the GNAT
run time, and is therefore licensed under the modified GPL.

Pragma Link_With
================

Syntax:


::

  pragma Link_With (static_string_EXPRESSION {,static_string_EXPRESSION});


This pragma is provided for compatibility with certain Ada 83 compilers.
It has exactly the same effect as pragma ``Linker_Options`` except
that spaces occurring within one of the string expressions are treated
as separators. For example, in the following case:

.. code-block:: ada

  pragma Link_With ("-labc -ldef");


results in passing the strings ``-labc`` and ``-ldef`` as two
separate arguments to the linker. In addition pragma Link_With allows
multiple arguments, with the same effect as successive pragmas.

Pragma Linker_Alias
===================

Syntax:


::

  pragma Linker_Alias (
    [Entity =>] LOCAL_NAME,
    [Target =>] static_string_EXPRESSION);


``LOCAL_NAME`` must refer to an object that is declared at the library
level. This pragma establishes the given entity as a linker alias for the
given target. It is equivalent to ``__attribute__((alias))`` in GNU C
and causes ``LOCAL_NAME`` to be emitted as an alias for the symbol
``static_string_EXPRESSION`` in the object file, that is to say no space
is reserved for ``LOCAL_NAME`` by the assembler and it will be resolved
to the same address as ``static_string_EXPRESSION`` by the linker.

The actual linker name for the target must be used (e.g., the fully
encoded name with qualification in Ada, or the mangled name in C++),
or it must be declared using the C convention with ``pragma Import``
or ``pragma Export``.

Not all target machines support this pragma. On some of them it is accepted
only if ``pragma Weak_External`` has been applied to ``LOCAL_NAME``.


.. code-block:: ada

  --  Example of the use of pragma Linker_Alias

  package p is
    i : Integer := 1;
    pragma Export (C, i);

    new_name_for_i : Integer;
    pragma Linker_Alias (new_name_for_i, "i");
  end p;


Pragma Linker_Constructor
=========================

Syntax:


.. code-block:: ada

  pragma Linker_Constructor (procedure_LOCAL_NAME);


``procedure_LOCAL_NAME`` must refer to a parameterless procedure that
is declared at the library level. A procedure to which this pragma is
applied will be treated as an initialization routine by the linker.
It is equivalent to ``__attribute__((constructor))`` in GNU C and
causes ``procedure_LOCAL_NAME`` to be invoked before the entry point
of the executable is called (or immediately after the shared library is
loaded if the procedure is linked in a shared library), in particular
before the Ada run-time environment is set up.

Because of these specific contexts, the set of operations such a procedure
can perform is very limited and the type of objects it can manipulate is
essentially restricted to the elementary types. In particular, it must only
contain code to which pragma Restrictions (No_Elaboration_Code) applies.

This pragma is used by GNAT to implement auto-initialization of shared Stand
Alone Libraries, which provides a related capability without the restrictions
listed above. Where possible, the use of Stand Alone Libraries is preferable
to the use of this pragma.

Pragma Linker_Destructor
========================

Syntax:


.. code-block:: ada

  pragma Linker_Destructor (procedure_LOCAL_NAME);


``procedure_LOCAL_NAME`` must refer to a parameterless procedure that
is declared at the library level. A procedure to which this pragma is
applied will be treated as a finalization routine by the linker.
It is equivalent to ``__attribute__((destructor))`` in GNU C and
causes ``procedure_LOCAL_NAME`` to be invoked after the entry point
of the executable has exited (or immediately before the shared library
is unloaded if the procedure is linked in a shared library), in particular
after the Ada run-time environment is shut down.

See ``pragma Linker_Constructor`` for the set of restrictions that apply
because of these specific contexts.

.. _Pragma-Linker_Section:

Pragma Linker_Section
=====================

Syntax:


::

  pragma Linker_Section (
    [Entity  =>] LOCAL_NAME,
    [Section =>] static_string_EXPRESSION);


``LOCAL_NAME`` must refer to an object, type, or subprogram that is
declared at the library level. This pragma specifies the name of the
linker section for the given entity. It is equivalent to
``__attribute__((section))`` in GNU C and causes ``LOCAL_NAME`` to
be placed in the ``static_string_EXPRESSION`` section of the
executable (assuming the linker doesn't rename the section).
GNAT also provides an implementation defined aspect of the same name.

In the case of specifying this aspect for a type, the effect is to
specify the corresponding section for all library-level objects of
the type that do not have an explicit linker section set. Note that
this only applies to whole objects, not to components of composite objects.

In the case of a subprogram, the linker section applies to all previously
declared matching overloaded subprograms in the current declarative part
which do not already have a linker section assigned. The linker section
aspect is useful in this case for specifying different linker sections
for different elements of such an overloaded set.

Note that an empty string specifies that no linker section is specified.
This is not quite the same as omitting the pragma or aspect, since it
can be used to specify that one element of an overloaded set of subprograms
has the default linker section, or that one object of a type for which a
linker section is specified should has the default linker section.

The compiler normally places library-level entities in standard sections
depending on the class: procedures and functions generally go in the
``.text`` section, initialized variables in the ``.data`` section
and uninitialized variables in the ``.bss`` section.

Other, special sections may exist on given target machines to map special
hardware, for example I/O ports or flash memory. This pragma is a means to
defer the final layout of the executable to the linker, thus fully working
at the symbolic level with the compiler.

Some file formats do not support arbitrary sections so not all target
machines support this pragma. The use of this pragma may cause a program
execution to be erroneous if it is used to place an entity into an
inappropriate section (e.g., a modified variable into the ``.text``
section). See also ``pragma Persistent_BSS``.


.. code-block:: ada

  --  Example of the use of pragma Linker_Section

  package IO_Card is
    Port_A : Integer;
    pragma Volatile (Port_A);
    pragma Linker_Section (Port_A, ".bss.port_a");

    Port_B : Integer;
    pragma Volatile (Port_B);
    pragma Linker_Section (Port_B, ".bss.port_b");

    type Port_Type is new Integer with Linker_Section => ".bss";
    PA : Port_Type with Linker_Section => ".bss.PA";
    PB : Port_Type; --  ends up in linker section ".bss"

    procedure Q with Linker_Section => "Qsection";
  end IO_Card;

.. _Pragma-Lock_Free:

Pragma Lock_Free
================

Syntax:

.. code-block:: ada

  pragma Lock_Free [ (static_boolean_EXPRESSION) ];

This pragma may be specified for protected types or objects. It specifies that
the implementation of protected operations must be implemented without locks.
Compilation fails if the compiler cannot generate lock-free code for the
operations.

The current conditions required to support this pragma are:

* Protected type declarations may not contain entries
* Protected subprogram declarations may not have nonelementary parameters

In addition, each protected subprogram body must satisfy:

* May reference only one protected component
* May not reference nonconstant entities outside the protected subprogram
  scope
* May not contain address representation items, allocators, or quantified
  expressions
* May not contain delay, goto, loop, or procedure-call statements
* May not contain exported and imported entities
* May not dereferenced access values
* Function calls and attribute references must be static

If the Lock_Free aspect is specified to be True for a protected unit
and the Ceiling_Locking locking policy is in effect, then the run-time
actions associated with the Ceiling_Locking locking policy (described in
Ada RM D.3) are not performed when a protected operation of the protected
unit is executed.

Pragma Loop_Invariant
=====================

Syntax:


.. code-block:: ada

  pragma Loop_Invariant ( boolean_EXPRESSION );


The effect of this pragma is similar to that of pragma ``Assert``,
except that in an ``Assertion_Policy`` pragma, the identifier
``Loop_Invariant`` is used to control whether it is ignored or checked
(or disabled).

``Loop_Invariant`` can only appear as one of the items in the sequence
of statements of a loop body, or nested inside block statements that
appear in the sequence of statements of a loop body.
The intention is that it be used to
represent a "loop invariant" assertion, i.e. something that is true each
time through the loop, and which can be used to show that the loop is
achieving its purpose.

Multiple ``Loop_Invariant`` and ``Loop_Variant`` pragmas that
apply to the same loop should be grouped in the same sequence of
statements.

To aid in writing such invariants, the special attribute ``Loop_Entry``
may be used to refer to the value of an expression on entry to the loop. This
attribute can only be used within the expression of a ``Loop_Invariant``
pragma. For full details, see documentation of attribute ``Loop_Entry``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Loop_Optimize
====================

Syntax:


::

  pragma Loop_Optimize (OPTIMIZATION_HINT {, OPTIMIZATION_HINT});

  OPTIMIZATION_HINT ::= Ivdep | No_Unroll | Unroll | No_Vector | Vector


This pragma must appear immediately within a loop statement.  It allows the
programmer to specify optimization hints for the enclosing loop.  The hints
are not mutually exclusive and can be freely mixed, but not all combinations
will yield a sensible outcome.

There are five supported optimization hints for a loop:

* Ivdep

  The programmer asserts that there are no loop-carried dependencies
  which would prevent consecutive iterations of the loop from being
  executed simultaneously.

* No_Unroll

  The loop must not be unrolled.  This is a strong hint: the compiler will not
  unroll a loop marked with this hint.

* Unroll

  The loop should be unrolled.  This is a weak hint: the compiler will try to
  apply unrolling to this loop preferably to other optimizations, notably
  vectorization, but there is no guarantee that the loop will be unrolled.

* No_Vector

  The loop must not be vectorized.  This is a strong hint: the compiler will not
  vectorize a loop marked with this hint.

* Vector

  The loop should be vectorized.  This is a weak hint: the compiler will try to
  apply vectorization to this loop preferably to other optimizations, notably
  unrolling, but there is no guarantee that the loop will be vectorized.


These hints do not remove the need to pass the appropriate switches to the
compiler in order to enable the relevant optimizations, that is to say
*-funroll-loops* for unrolling and *-ftree-vectorize* for
vectorization.

Pragma Loop_Variant
===================

Syntax:


::

  pragma Loop_Variant ( LOOP_VARIANT_ITEM {, LOOP_VARIANT_ITEM } );
  LOOP_VARIANT_ITEM ::= CHANGE_DIRECTION => discrete_EXPRESSION
  CHANGE_DIRECTION ::= Increases | Decreases


``Loop_Variant`` can only appear as one of the items in the sequence
of statements of a loop body, or nested inside block statements that
appear in the sequence of statements of a loop body.
It allows the specification of quantities which must always
decrease or increase in successive iterations of the loop. In its simplest
form, just one expression is specified, whose value must increase or decrease
on each iteration of the loop.

In a more complex form, multiple arguments can be given which are interpreted
in a nesting lexicographic manner. For example:

.. code-block:: ada

  pragma Loop_Variant (Increases => X, Decreases => Y);


specifies that each time through the loop either X increases, or X stays
the same and Y decreases. A ``Loop_Variant`` pragma ensures that the
loop is making progress. It can be useful in helping to show informally
or prove formally that the loop always terminates.

``Loop_Variant`` is an assertion whose effect can be controlled using
an ``Assertion_Policy`` with a check name of ``Loop_Variant``. The
policy can be ``Check`` to enable the loop variant check, ``Ignore``
to ignore the check (in which case the pragma has no effect on the program),
or ``Disable`` in which case the pragma is not even checked for correct
syntax.

Multiple ``Loop_Invariant`` and ``Loop_Variant`` pragmas that
apply to the same loop should be grouped in the same sequence of
statements.

The ``Loop_Entry`` attribute may be used within the expressions of the
``Loop_Variant`` pragma to refer to values on entry to the loop.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Machine_Attribute
========================

Syntax:


::

  pragma Machine_Attribute (
       [Entity         =>] LOCAL_NAME,
       [Attribute_Name =>] static_string_EXPRESSION
    [, [Info           =>] static_EXPRESSION {, static_EXPRESSION}] );


Machine-dependent attributes can be specified for types and/or
declarations.  This pragma is semantically equivalent to
:samp:`__attribute__(({attribute_name}))` (if ``info`` is not
specified) or :samp:`__attribute__(({attribute_name(info})))`
or :samp:`__attribute__(({attribute_name(info,...})))` in GNU C,
where *attribute_name* is recognized by the compiler middle-end
or the ``TARGET_ATTRIBUTE_TABLE`` machine specific macro.  Note
that a string literal for the optional parameter ``info`` or the
following ones is transformed by default into an identifier,
which may make this pragma unusable for some attributes.
For further information see :title:`GNU Compiler Collection (GCC) Internals`.

Pragma Main
===========

Syntax::

  pragma Main
   (MAIN_OPTION [, MAIN_OPTION]);

  MAIN_OPTION ::=
    [Stack_Size              =>] static_integer_EXPRESSION
  | [Task_Stack_Size_Default =>] static_integer_EXPRESSION
  | [Time_Slicing_Enabled    =>] static_boolean_EXPRESSION


This pragma is provided for compatibility with OpenVMS VAX Systems.  It has
no effect in GNAT, other than being syntax checked.

Pragma Main_Storage
===================

Syntax::

  pragma Main_Storage
    (MAIN_STORAGE_OPTION [, MAIN_STORAGE_OPTION]);

  MAIN_STORAGE_OPTION ::=
    [WORKING_STORAGE =>] static_SIMPLE_EXPRESSION
  | [TOP_GUARD       =>] static_SIMPLE_EXPRESSION


This pragma is provided for compatibility with OpenVMS VAX Systems.  It has
no effect in GNAT, other than being syntax checked.

.. _Pragma-Max_Queue_Length:

Pragma Max_Queue_Length
=======================

Syntax::

   pragma Max_Queue_Length (static_integer_EXPRESSION);


This pragma is used to specify the maximum callers per entry queue for
individual protected entries and entry families. It accepts a single
integer (-1 or more) as a parameter and must appear after the declaration of an
entry.

A value of -1 represents no additional restriction on queue length.

Pragma Modifies
===============
.. index:: Modifies

Syntax:


::

  pragma Modifies (MODIFIES_SPECIFICATION);

  MODIFIES_SPECIFICATION ::=
      MODIFIES_CLAUSE
    | (MODIFIES_CLAUSE {, MODIFIES_CLAUSE});

  MODIFIES_CLAUSE ::= MODIFIED_OBJECTS { when GUARD }

  GUARD ::= boolean_EXPRESSION

  MODIFIED_OBJECTS ::= MODIFIED_OBJECT | (MODIFIED_OBJECT {, MODIFIED_OBJECT})

  MODIFIED_OBJECT ::=
      name
    | MODIFIED_OBJECT . all
    | MODIFIED_OBJECT . component_selector_name
    | MODIFIED_OBJECT (expression {, expression})

The ``Modifies`` pragma is intended to be an exact replacement for the
implementation-defined ``Modifies`` aspect, and shares its restrictions
and semantics.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section TBD.

Pragma No_Body
==============

Syntax:


.. code-block:: ada

  pragma No_Body;


There are a number of cases in which a package spec does not require a body,
and in fact a body is not permitted. GNAT will not permit the spec to be
compiled if there is a body around. The pragma No_Body allows you to provide
a body file, even in a case where no body is allowed. The body file must
contain only comments and a single No_Body pragma. This is recognized by
the compiler as indicating that no body is logically present.

This is particularly useful during maintenance when a package is modified in
such a way that a body needed before is no longer needed. The provision of a
dummy body with a No_Body pragma ensures that there is no interference from
earlier versions of the package body.

.. _Pragma-No_Caching:

Pragma No_Caching
=================

Syntax:

.. code-block:: ada

  pragma No_Caching [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``No_Caching`` in
the SPARK 2014 Reference Manual, section 7.1.2.

Pragma No_Component_Reordering
==============================

Syntax:


::

  pragma No_Component_Reordering [([Entity =>] type_LOCAL_NAME)];


``type_LOCAL_NAME`` must refer to a record type declaration in the current
declarative part. The effect is to preclude any reordering of components
for the layout of the record, i.e. the record is laid out by the compiler
in the order in which the components are declared textually. The form with
no argument is a configuration pragma which applies to all record types
declared in units to which the pragma applies and there is a requirement
that this pragma be used consistently within a partition.

.. _Pragma-No_Elaboration_Code_All:

Pragma No_Elaboration_Code_All
==============================

Syntax:


::

  pragma No_Elaboration_Code_All [(program_unit_NAME)];


This is a program unit pragma (there is also an equivalent aspect of the
same name) that establishes the restriction ``No_Elaboration_Code`` for
the current unit and any extended main source units (body and subunits).
It also has the effect of enforcing a transitive application of this
aspect, so that if any unit is implicitly or explicitly with'ed by the
current unit, it must also have the `No_Elaboration_Code_All` aspect set.
It may be applied to package or subprogram specs or their generic versions.

Pragma No_Heap_Finalization
===========================

Syntax:


::

  pragma No_Heap_Finalization [ (first_subtype_LOCAL_NAME) ];


Pragma ``No_Heap_Finalization`` may be used as a configuration pragma or as a
type-specific pragma.

In its configuration form, the pragma must appear within a configuration file
such as gnat.adc, without an argument. The pragma suppresses the call to
``Finalize`` for heap-allocated objects created through library-level named
access-to-object types in cases where the designated type requires finalization
actions.

In its type-specific form, the argument of the pragma must denote a
library-level named access-to-object type. The pragma suppresses the call to
``Finalize`` for heap-allocated objects created through the specific access type
in cases where the designated type requires finalization actions.

It is still possible to finalize such heap-allocated objects by explicitly
deallocating them.

A library-level named access-to-object type declared within a generic unit will
lose its ``No_Heap_Finalization`` pragma when the corresponding instance does not
appear at the library level.

.. _Pragma-No_Inline:

Pragma No_Inline
================

Syntax:


::

  pragma No_Inline (NAME {, NAME});


This pragma suppresses inlining for the callable entity or the instances of
the generic subprogram designated by ``NAME``, including inlining that
results from the use of pragma ``Inline``.  This pragma is always active,
in particular it is not subject to the use of option *-gnatn* or
*-gnatN*.  It is illegal to specify both pragma ``No_Inline`` and
pragma ``Inline_Always`` for the same ``NAME``.

.. _Pragma-No_Raise:

Pragma No_Raise
===============

Syntax:


::

  pragma No_Raise (subprogram_LOCAL_NAME {, subprogram_LOCAL_NAME});


Each ``subprogram_LOCAL_NAME`` argument must refer to one or more subprogram
declarations in the current declarative part.  A subprogram to which this
pragma is applied may not raise an exception that is not caught within it.
An implementation-defined check named `Raise_Check` is associated with the
pragma, and `Program_Error` is raised upon its failure (see RM 11.5(19/5)).

Pragma No_Return
================

Syntax:


::

  pragma No_Return (procedure_LOCAL_NAME {, procedure_LOCAL_NAME});


Each ``procedure_LOCAL_NAME`` argument must refer to one or more procedure
declarations in the current declarative part.  A procedure to which this
pragma is applied may not contain any explicit ``return`` statements.
In addition, if the procedure contains any implicit returns from falling
off the end of a statement sequence, then execution of that implicit
return will cause Program_Error to be raised.

One use of this pragma is to identify procedures whose only purpose is to raise
an exception. Another use of this pragma is to suppress incorrect warnings
about missing returns in functions, where the last statement of a function
statement sequence is a call to such a procedure.

Note that in Ada 2005 mode, this pragma is part of the language. It is
available in all earlier versions of Ada as an implementation-defined
pragma.

Pragma No_Strict_Aliasing
=========================

Syntax:


::

  pragma No_Strict_Aliasing [([Entity =>] type_LOCAL_NAME)];


``type_LOCAL_NAME`` must refer to an access type
declaration in the current declarative part.  The effect is to inhibit
strict aliasing optimization for the given type.  The form with no
arguments is a configuration pragma which applies to all access types
declared in units to which the pragma applies. For a detailed
description of the strict aliasing optimization, and the situations
in which it must be suppressed, see the section on Optimization and Strict Aliasing
in the :title:`GNAT User's Guide`.

This pragma currently has no effects on access to unconstrained array types.

.. _Pragma-No_Tagged_Streams:

Pragma No_Tagged_Streams
========================

Syntax:


::

  pragma No_Tagged_Streams [([Entity =>] tagged_type_LOCAL_NAME)];


Normally when a tagged type is introduced using a full type declaration,
part of the processing includes generating stream access routines to be
used by stream attributes referencing the type (or one of its subtypes
or derived types). This can involve the generation of significant amounts
of code which is wasted space if stream routines are not needed for the
type in question.

The ``No_Tagged_Streams`` pragma causes the generation of these stream
routines to be skipped, and any attempt to use stream operations on
types subject to this pragma will be statically rejected as illegal.

There are two forms of the pragma. The form with no arguments must appear
in a declarative sequence or in the declarations of a package spec. This
pragma affects all subsequent root tagged types declared in the declaration
sequence, and specifies that no stream routines be generated. The form with
an argument (for which there is also a corresponding aspect) specifies a
single root tagged type for which stream routines are not to be generated.

Once the pragma has been given for a particular root tagged type, all subtypes
and derived types of this type inherit the pragma automatically, so the effect
applies to a complete hierarchy (this is necessary to deal with the class-wide
dispatching versions of the stream routines).

When pragmas ``Discard_Names`` and ``No_Tagged_Streams`` are simultaneously
applied to a tagged type its Expanded_Name and External_Tag are initialized
with empty strings. This is useful to avoid exposing entity names at binary
level but has a negative impact on the debuggability of tagged types.

Pragma Normalize_Scalars
========================

Syntax:


.. code-block:: ada

  pragma Normalize_Scalars;


This is a language defined pragma which is fully implemented in GNAT.  The
effect is to cause all scalar objects that are not otherwise initialized
to be initialized.  The initial values are implementation dependent and
are as follows:



*Standard.Character*
  Objects whose root type is Standard.Character are initialized to
  Character'Last unless the subtype range excludes NUL (in which case
  NUL is used). This choice will always generate an invalid value if
  one exists.


*Standard.Wide_Character*
  Objects whose root type is Standard.Wide_Character are initialized to
  Wide_Character'Last unless the subtype range excludes NUL (in which case
  NUL is used). This choice will always generate an invalid value if
  one exists.


*Standard.Wide_Wide_Character*
  Objects whose root type is Standard.Wide_Wide_Character are initialized to
  the invalid value 16#FFFF_FFFF# unless the subtype range excludes NUL (in
  which case NUL is used). This choice will always generate an invalid value if
  one exists.


*Integer types*
  Objects of an integer type are treated differently depending on whether
  negative values are present in the subtype. If no negative values are
  present, then all one bits is used as the initial value except in the
  special case where zero is excluded from the subtype, in which case
  all zero bits are used. This choice will always generate an invalid
  value if one exists.

  For subtypes with negative values present, the largest negative number
  is used, except in the unusual case where this largest negative number
  is in the subtype, and the largest positive number is not, in which case
  the largest positive value is used. This choice will always generate
  an invalid value if one exists.


*Floating-Point Types*
  Objects of all floating-point types are initialized to all 1-bits. For
  standard IEEE format, this corresponds to a NaN (not a number) which is
  indeed an invalid value.


*Fixed-Point Types*
  Objects of all fixed-point types are treated as described above for integers,
  with the rules applying to the underlying integer value used to represent
  the fixed-point value.


*Modular types*
  Objects of a modular type are initialized to all one bits, except in
  the special case where zero is excluded from the subtype, in which
  case all zero bits are used. This choice will always generate an
  invalid value if one exists.


*Enumeration types*
  Objects of an enumeration type are initialized to all one-bits, i.e., to
  the value ``2 ** typ'Size - 1`` unless the subtype excludes the literal
  whose Pos value is zero, in which case a code of zero is used. This choice
  will always generate an invalid value if one exists.

.. _Pragma_Obsolescent:

Pragma Obsolescent
==================

Syntax:


::

  pragma Obsolescent;

  pragma Obsolescent (
    [Message =>] static_string_EXPRESSION
  [,[Version =>] Ada_05]);

  pragma Obsolescent (
    [Entity  =>] NAME
  [,[Message =>] static_string_EXPRESSION
  [,[Version =>] Ada_05]]);


This pragma can occur immediately following a declaration of an entity,
including the case of a record component. If no Entity argument is present,
then this declaration is the one to which the pragma applies. If an Entity
parameter is present, it must either match the name of the entity in this
declaration, or alternatively, the pragma can immediately follow an enumeration
type declaration, where the Entity argument names one of the enumeration
literals.

This pragma is used to indicate that the named entity
is considered obsolescent and should not be used. Typically this is
used when an API must be modified by eventually removing or modifying
existing subprograms or other entities. The pragma can be used at an
intermediate stage when the entity is still present, but will be
removed later.

The effect of this pragma is to output a warning message on a reference to
an entity thus marked that the subprogram is obsolescent if the appropriate
warning option in the compiler is activated. If the ``Message`` parameter is
present, then a second warning message is given containing this text. In
addition, a reference to the entity is considered to be a violation of pragma
``Restrictions (No_Obsolescent_Features)``.

This pragma can also be used as a program unit pragma for a package,
in which case the entity name is the name of the package, and the
pragma indicates that the entire package is considered
obsolescent. In this case a client ``with``\ ing such a package
violates the restriction, and the ``with`` clause is
flagged with warnings if the warning option is set.

If the ``Version`` parameter is present (which must be exactly
the identifier ``Ada_05``, no other argument is allowed), then the
indication of obsolescence applies only when compiling in Ada 2005
mode. This is primarily intended for dealing with the situations
in the predefined library where subprograms or packages
have become defined as obsolescent in Ada 2005
(e.g., in ``Ada.Characters.Handling``), but may be used anywhere.

The following examples show typical uses of this pragma:


.. code-block:: ada

  package p is
     pragma Obsolescent (p, Message => "use pp instead of p");
  end p;

  package q is
     procedure q2;
     pragma Obsolescent ("use q2new instead");

     type R is new integer;
     pragma Obsolescent
       (Entity  => R,
        Message => "use RR in Ada 2005",
        Version => Ada_05);

     type M is record
        F1 : Integer;
        F2 : Integer;
        pragma Obsolescent;
        F3 : Integer;
     end record;

     type E is (a, bc, 'd', quack);
     pragma Obsolescent (Entity => bc)
     pragma Obsolescent (Entity => 'd')

     function "+"
       (a, b : character) return character;
     pragma Obsolescent (Entity => "+");
  end;


Note that, as for all pragmas, if you use a pragma argument identifier,
then all subsequent parameters must also use a pragma argument identifier.
So if you specify ``Entity =>`` for the ``Entity`` argument, and a ``Message``
argument is present, it must be preceded by ``Message =>``.

Pragma Optimize_Alignment
=========================
.. index:: Alignment, default settings

Syntax:


.. code-block:: ada

  pragma Optimize_Alignment (TIME | SPACE | OFF);


This is a configuration pragma which affects the choice of default alignments
for types and objects where no alignment is explicitly specified. There is a
time/space trade-off in the selection of these values. Large alignments result
in more efficient code, at the expense of larger data space, since sizes have
to be increased to match these alignments. Smaller alignments save space, but
the access code is slower. The normal choice of default alignments for types
and individual alignment promotions for objects (which is what you get if you
do not use this pragma, or if you use an argument of OFF), tries to balance
these two requirements.

Specifying SPACE causes smaller default alignments to be chosen in two cases.
First any packed record is given an alignment of 1. Second, if a size is given
for the type, then the alignment is chosen to avoid increasing this size. For
example, consider:


.. code-block:: ada

     type R is record
        X : Integer;
        Y : Character;
     end record;

     for R'Size use 5*8;


In the default mode, this type gets an alignment of 4, so that access to the
Integer field X are efficient. But this means that objects of the type end up
with a size of 8 bytes. This is a valid choice, since sizes of objects are
allowed to be bigger than the size of the type, but it can waste space if for
example fields of type R appear in an enclosing record. If the above type is
compiled in ``Optimize_Alignment (Space)`` mode, the alignment is set to 1.

However, there is one case in which SPACE is ignored. If a variable length
record (that is a discriminated record with a component which is an array
whose length depends on a discriminant), has a pragma Pack, then it is not
in general possible to set the alignment of such a record to one, so the
pragma is ignored in this case (with a warning).

Specifying SPACE also disables alignment promotions for standalone objects,
which occur when the compiler increases the alignment of a specific object
without changing the alignment of its type.

Specifying SPACE also disables component reordering in unpacked record types,
which can result in larger sizes in order to meet alignment requirements.

Specifying TIME causes larger default alignments to be chosen in the case of
small types with sizes that are not a power of 2. For example, consider:


.. code-block:: ada

     type R is record
        A : Character;
        B : Character;
        C : Boolean;
     end record;

     pragma Pack (R);
     for R'Size use 17;


The default alignment for this record is normally 1, but if this type is
compiled in ``Optimize_Alignment (Time)`` mode, then the alignment is set
to 4, which wastes space for objects of the type, since they are now 4 bytes
long, but results in more efficient access when the whole record is referenced.

As noted above, this is a configuration pragma, and there is a requirement
that all units in a partition be compiled with a consistent setting of the
optimization setting. This would normally be achieved by use of a configuration
pragma file containing the appropriate setting. The exception to this rule is
that units with an explicit configuration pragma in the same file as the source
unit are excluded from the consistency check, as are all predefined units. The
latter are compiled by default in pragma Optimize_Alignment (Off) mode if no
pragma appears at the start of the file.

Pragma Ordered
==============

Syntax:


.. code-block:: ada

  pragma Ordered (enumeration_first_subtype_LOCAL_NAME);


Most enumeration types are from a conceptual point of view unordered.
For example, consider:


.. code-block:: ada

  type Color is (Red, Blue, Green, Yellow);


By Ada semantics ``Blue > Red`` and ``Green > Blue``,
but really these relations make no sense; the enumeration type merely
specifies a set of possible colors, and the order is unimportant.

For unordered enumeration types, it is generally a good idea if
clients avoid comparisons (other than equality or inequality) and
explicit ranges. (A *client* is a unit where the type is referenced,
other than the unit where the type is declared, its body, and its subunits.)
For example, if code buried in some client says:


.. code-block:: ada

  if Current_Color < Yellow then ...
  if Current_Color in Blue .. Green then ...


then the client code is relying on the order, which is undesirable.
It makes the code hard to read and creates maintenance difficulties if
entries have to be added to the enumeration type. Instead,
the code in the client should list the possibilities, or an
appropriate subtype should be declared in the unit that declares
the original enumeration type. E.g., the following subtype could
be declared along with the type ``Color``:


.. code-block:: ada

  subtype RBG is Color range Red .. Green;


and then the client could write:


.. code-block:: ada

  if Current_Color in RBG then ...
  if Current_Color = Blue or Current_Color = Green then ...


However, some enumeration types are legitimately ordered from a conceptual
point of view. For example, if you declare:


.. code-block:: ada

  type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);


then the ordering imposed by the language is reasonable, and
clients can depend on it, writing for example:


.. code-block:: ada

  if D in Mon .. Fri then ...
  if D < Wed then ...


The pragma *Ordered* is provided to mark enumeration types that
are conceptually ordered, alerting the reader that clients may depend
on the ordering. GNAT provides a pragma to mark enumerations as ordered
rather than one to mark them as unordered, since in our experience,
the great majority of enumeration types are conceptually unordered.

The types ``Boolean``, ``Character``, ``Wide_Character``,
and ``Wide_Wide_Character``
are considered to be ordered types, so each is declared with a
pragma ``Ordered`` in package ``Standard``.

Normally pragma ``Ordered`` serves only as documentation and a guide for
coding standards, but GNAT provides a warning switch *-gnatw.u* that
requests warnings for inappropriate uses (comparisons and explicit
subranges) for unordered types. If this switch is used, then any
enumeration type not marked with pragma ``Ordered`` will be considered
as unordered, and will generate warnings for inappropriate uses.

Note that generic types are not considered ordered or unordered (since the
template can be instantiated for both cases), so we never generate warnings
for the case of generic enumerated types.

For additional information please refer to the description of the
*-gnatw.u* switch in the GNAT User's Guide.

Pragma Overflow_Mode
====================

Syntax:


::

  pragma Overflow_Mode
   (  [General    =>] MODE
    [,[Assertions =>] MODE]);

  MODE ::= STRICT | MINIMIZED | ELIMINATED


This pragma sets the current overflow mode to the given setting. For details
of the meaning of these modes, please refer to the
'Overflow Check Handling in GNAT' appendix in the
GNAT User's Guide. If only the ``General`` parameter is present,
the given mode applies to all expressions. If both parameters are present,
the ``General`` mode applies to expressions outside assertions, and
the ``Eliminated`` mode applies to expressions within assertions.

The case of the ``MODE`` parameter is ignored,
so ``MINIMIZED``, ``Minimized`` and
``minimized`` all have the same effect.

The ``Overflow_Mode`` pragma has the same scoping and placement
rules as pragma ``Suppress``, so it can occur either as a
configuration pragma, specifying a default for the whole
program, or in a declarative scope, where it applies to the
remaining declarations and statements in that scope.

The pragma ``Suppress (Overflow_Check)`` suppresses
overflow checking, but does not affect the overflow mode.

The pragma ``Unsuppress (Overflow_Check)`` unsuppresses (enables)
overflow checking, but does not affect the overflow mode.

Pragma Overriding_Renamings
===========================
.. index:: Rational profile

.. index:: Rational compatibility

Syntax:


.. code-block:: ada

  pragma Overriding_Renamings;


This is a GNAT configuration pragma to simplify porting
legacy code accepted by the Rational
Ada compiler. In the presence of this pragma, a renaming declaration that
renames an inherited operation declared in the same scope is legal if selected
notation is used as in:


.. code-block:: ada

  pragma Overriding_Renamings;
  ...
  package R is
    function F (..);
    ...
    function F (..) renames R.F;
  end R;


even though
RM 8.3 (15) stipulates that an overridden operation is not visible within the
declaration of the overriding operation.

.. _Pragma-Part_Of:

Pragma Part_Of
==============

Syntax:

.. code-block:: ada

  pragma Part_Of (ABSTRACT_STATE);

  ABSTRACT_STATE ::= NAME

For the semantics of this pragma, see the entry for aspect ``Part_Of`` in the
SPARK 2014 Reference Manual, section 7.2.6.

Pragma Partition_Elaboration_Policy
===================================

Syntax:


::

  pragma Partition_Elaboration_Policy (POLICY_IDENTIFIER);

  POLICY_IDENTIFIER ::= Concurrent | Sequential


This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

Pragma Passive
==============

Syntax:


::

  pragma Passive [(Semaphore | No)];


Syntax checked, but otherwise ignored by GNAT.  This is recognized for
compatibility with DEC Ada 83 implementations, where it is used within a
task definition to request that a task be made passive.  If the argument
``Semaphore`` is present, or the argument is omitted, then DEC Ada 83
treats the pragma as an assertion that the containing task is passive
and that optimization of context switch with this task is permitted and
desired.  If the argument ``No`` is present, the task must not be
optimized.  GNAT does not attempt to optimize any tasks in this manner
(since protected objects are available in place of passive tasks).

For more information on the subject of passive tasks, see the section
'Passive Task Optimization' in the GNAT Users Guide.

.. _Pragma-Persistent_BSS:

Pragma Persistent_BSS
=====================

Syntax:


::

  pragma Persistent_BSS [(object_LOCAL_NAME)]


This pragma allows selected objects to be placed in the ``.persistent_bss``
section. On some targets the linker and loader provide for special
treatment of this section, allowing a program to be reloaded without
affecting the contents of this data (hence the name persistent).

There are two forms of usage. If an argument is given, it must be the
local name of a library-level object, with no explicit initialization
and whose type is potentially persistent. If no argument is given, then
the pragma is a configuration pragma, and applies to all library-level
objects with no explicit initialization of potentially persistent types.

A potentially persistent type is a scalar type, or an untagged,
non-discriminated record, all of whose components have no explicit
initialization and are themselves of a potentially persistent type,
or an array, all of whose constraints are static, and whose component
type is potentially persistent.

If this pragma is used on a target where this feature is not supported,
then the pragma will be ignored. See also ``pragma Linker_Section``.

Pragma Post
===========
.. index:: Post

.. index:: Checks, postconditions


Syntax:


.. code-block:: ada

  pragma Post (Boolean_Expression);


The ``Post`` pragma is intended to be an exact replacement for
the language-defined
``Post`` aspect, and shares its restrictions and semantics.
It must appear either immediately following the corresponding
subprogram declaration (only other pragmas may intervene), or
if there is no separate subprogram declaration, then it can
appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Postcondition
====================
.. index:: Postcondition

.. index:: Checks, postconditions


Syntax:


::

  pragma Postcondition (
     [Check   =>] Boolean_Expression
   [,[Message =>] String_Expression]);


The ``Postcondition`` pragma allows specification of automatic
postcondition checks for subprograms. These checks are similar to
assertions, but are automatically inserted just prior to the return
statements of the subprogram with which they are associated (including
implicit returns at the end of procedure bodies and associated
exception handlers).

In addition, the boolean expression which is the condition which
must be true may contain references to function'Result in the case
of a function to refer to the returned value.

``Postcondition`` pragmas may appear either immediately following the
(separate) declaration of a subprogram, or at the start of the
declarations of a subprogram body. Only other pragmas may intervene
(that is appear between the subprogram declaration and its
postconditions, or appear before the postcondition in the
declaration sequence in a subprogram body). In the case of a
postcondition appearing after a subprogram declaration, the
formal arguments of the subprogram are visible, and can be
referenced in the postcondition expressions.

The postconditions are collected and automatically tested just
before any return (implicit or explicit) in the subprogram body.
A postcondition is only recognized if postconditions are active
at the time the pragma is encountered. The compiler switch *gnata*
turns on all postconditions by default, and pragma ``Check_Policy``
with an identifier of ``Postcondition`` can also be used to
control whether postconditions are active.

The general approach is that postconditions are placed in the spec
if they represent functional aspects which make sense to the client.
For example we might have:


.. code-block:: ada

     function Direction return Integer;
     pragma Postcondition
      (Direction'Result = +1
         or else
       Direction'Result = -1);


which serves to document that the result must be +1 or -1, and
will test that this is the case at run time if postcondition
checking is active.

Postconditions within the subprogram body can be used to
check that some internal aspect of the implementation,
not visible to the client, is operating as expected.
For instance if a square root routine keeps an internal
counter of the number of times it is called, then we
might have the following postcondition:


.. code-block:: ada

     Sqrt_Calls : Natural := 0;

     function Sqrt (Arg : Float) return Float is
       pragma Postcondition
         (Sqrt_Calls = Sqrt_Calls'Old + 1);
       ...
     end Sqrt


As this example, shows, the use of the ``Old`` attribute
is often useful in postconditions to refer to the state on
entry to the subprogram.

Note that postconditions are only checked on normal returns
from the subprogram. If an abnormal return results from
raising an exception, then the postconditions are not checked.

If a postcondition fails, then the exception
``System.Assertions.Assert_Failure`` is raised. If
a message argument was supplied, then the given string
will be used as the exception message. If no message
argument was supplied, then the default message has
the form "Postcondition failed at file_name:line". The
exception is raised in the context of the subprogram
body, so it is possible to catch postcondition failures
within the subprogram body itself.

Within a package spec, normal visibility rules
in Ada would prevent forward references within a
postcondition pragma to functions defined later in
the same package. This would introduce undesirable
ordering constraints. To avoid this problem, all
postcondition pragmas are analyzed at the end of
the package spec, allowing forward references.

The following example shows that this even allows
mutually recursive postconditions as in:


.. code-block:: ada

  package Parity_Functions is
     function Odd  (X : Natural) return Boolean;
     pragma Postcondition
       (Odd'Result =
          (x = 1
            or else
          (x /= 0 and then Even (X - 1))));

     function Even (X : Natural) return Boolean;
     pragma Postcondition
       (Even'Result =
          (x = 0
            or else
          (x /= 1 and then Odd (X - 1))));

  end Parity_Functions;


There are no restrictions on the complexity or form of
conditions used within ``Postcondition`` pragmas.
The following example shows that it is even possible
to verify performance behavior.


.. code-block:: ada

  package Sort is

     Performance : constant Float;
     --  Performance constant set by implementation
     --  to match target architecture behavior.

     procedure Treesort (Arg : String);
     --  Sorts characters of argument using N*logN sort
     pragma Postcondition
       (Float (Clock - Clock'Old) <=
          Float (Arg'Length) *
          log (Float (Arg'Length)) *
          Performance);
  end Sort;


Note: postcondition pragmas associated with subprograms that are
marked as Inline_Always, or those marked as Inline with front-end
inlining (-gnatN option set) are accepted and legality-checked
by the compiler, but are ignored at run-time even if postcondition
checking is enabled.

Note that pragma ``Postcondition`` differs from the language-defined
``Post`` aspect (and corresponding ``Post`` pragma) in allowing
multiple occurrences, allowing occurrences in the body even if there
is a separate spec, and allowing a second string parameter, and the
use of the pragma identifier ``Check``. Historically, pragma
``Postcondition`` was implemented prior to the development of
Ada 2012, and has been retained in its original form for
compatibility purposes.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Post_Class
=================
.. index:: Post

.. index:: Checks, postconditions


Syntax:


.. code-block:: ada

  pragma Post_Class (Boolean_Expression);


The ``Post_Class`` pragma is intended to be an exact replacement for
the language-defined
``Post'Class`` aspect, and shares its restrictions and semantics.
It must appear either immediately following the corresponding
subprogram declaration (only other pragmas may intervene), or
if there is no separate subprogram declaration, then it can
appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).

Note: This pragma is called ``Post_Class`` rather than
``Post'Class`` because the latter would not be strictly
conforming to the allowed syntax for pragmas. The motivation
for providing pragmas equivalent to the aspects is to allow a program
to be written using the pragmas, and then compiled if necessary
using an Ada compiler that does not recognize the pragmas or
aspects, but is prepared to ignore the pragmas. The assertion
policy that controls this pragma is ``Post'Class``, not
``Post_Class``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Pre
==========
.. index:: Pre

.. index:: Checks, preconditions


Syntax:


.. code-block:: ada

  pragma Pre (Boolean_Expression);


The ``Pre`` pragma is intended to be an exact replacement for
the language-defined
``Pre`` aspect, and shares its restrictions and semantics.
It must appear either immediately following the corresponding
subprogram declaration (only other pragmas may intervene), or
if there is no separate subprogram declaration, then it can
appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Precondition
===================
.. index:: Preconditions

.. index:: Checks, preconditions


Syntax:


::

  pragma Precondition (
     [Check   =>] Boolean_Expression
   [,[Message =>] String_Expression]);


The ``Precondition`` pragma is similar to ``Postcondition``
except that the corresponding checks take place immediately upon
entry to the subprogram, and if a precondition fails, the exception
is raised in the context of the caller, and the attribute 'Result
cannot be used within the precondition expression.

Otherwise, the placement and visibility rules are identical to those
described for postconditions. The following is an example of use
within a package spec:


.. code-block:: ada

  package Math_Functions is
     ...
     function Sqrt (Arg : Float) return Float;
     pragma Precondition (Arg >= 0.0)
     ...
  end Math_Functions;


``Precondition`` pragmas may appear either immediately following the
(separate) declaration of a subprogram, or at the start of the
declarations of a subprogram body. Only other pragmas may intervene
(that is appear between the subprogram declaration and its
postconditions, or appear before the postcondition in the
declaration sequence in a subprogram body).

Note: precondition pragmas associated with subprograms that are
marked as Inline_Always, or those marked as Inline with front-end
inlining (-gnatN option set) are accepted and legality-checked
by the compiler, but are ignored at run-time even if precondition
checking is enabled.

Note that pragma ``Precondition`` differs from the language-defined
``Pre`` aspect (and corresponding ``Pre`` pragma) in allowing
multiple occurrences, allowing occurrences in the body even if there
is a separate spec, and allowing a second string parameter, and the
use of the pragma identifier ``Check``. Historically, pragma
``Precondition`` was implemented prior to the development of
Ada 2012, and has been retained in its original form for
compatibility purposes.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

.. _Pragma-Predicate:

Pragma Predicate
================

Syntax:


::

  pragma Predicate
    ([Entity =>] type_LOCAL_NAME,
     [Check  =>] EXPRESSION);


This pragma (available in all versions of Ada in GNAT) encompasses both
the ``Static_Predicate`` and ``Dynamic_Predicate`` aspects in
Ada 2012. A predicate is regarded as static if it has an allowed form
for ``Static_Predicate`` and is otherwise treated as a
``Dynamic_Predicate``. Otherwise, predicates specified by this
pragma behave exactly as described in the Ada 2012 reference manual.
For example, if we have


.. code-block:: ada

  type R is range 1 .. 10;
  subtype S is R;
  pragma Predicate (Entity => S, Check => S not in 4 .. 6);
  subtype Q is R
  pragma Predicate (Entity => Q, Check => F(Q) or G(Q));


the effect is identical to the following Ada 2012 code:


.. code-block:: ada

  type R is range 1 .. 10;
  subtype S is R with
    Static_Predicate => S not in 4 .. 6;
  subtype Q is R with
    Dynamic_Predicate => F(Q) or G(Q);


Note that there are no pragmas ``Dynamic_Predicate``
or ``Static_Predicate``. That is
because these pragmas would affect legality and semantics of
the program and thus do not have a neutral effect if ignored.
The motivation behind providing pragmas equivalent to
corresponding aspects is to allow a program to be written
using the pragmas, and then compiled with a compiler that
will ignore the pragmas. That doesn't work in the case of
static and dynamic predicates, since if the corresponding
pragmas are ignored, then the behavior of the program is
fundamentally changed (for example a membership test
``A in B`` would not take into account a predicate
defined for subtype B). When following this approach, the
use of predicates should be avoided.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Predicate_Failure
========================

Syntax:


::

  pragma Predicate_Failure
    ([Entity  =>] type_LOCAL_NAME,
     [Message =>] String_Expression);


The ``Predicate_Failure`` pragma is intended to be an exact replacement for
the language-defined
``Predicate_Failure`` aspect, and shares its restrictions and semantics.

Pragma Preelaborable_Initialization
===================================

Syntax:


.. code-block:: ada

  pragma Preelaborable_Initialization (DIRECT_NAME);


This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

Pragma Prefix_Exception_Messages
================================
.. index:: Prefix_Exception_Messages

.. index:: exception

.. index:: Exception_Message


Syntax:


.. code-block:: ada

  pragma Prefix_Exception_Messages;


This is an implementation-defined configuration pragma that affects the
behavior of raise statements with a message given as a static string
constant (typically a string literal). In such cases, the string will
be automatically prefixed by the name of the enclosing entity (giving
the package and subprogram containing the raise statement). This helps
to identify where messages are coming from, and this mode is automatic
for the run-time library.

The pragma has no effect if the message is computed with an expression other
than a static string constant, since the assumption in this case is that
the program computes exactly the string it wants. If you still want the
prefixing in this case, you can always call
``GNAT.Source_Info.Enclosing_Entity`` and prepend the string manually.

Pragma Pre_Class
================
.. index:: Pre_Class

.. index:: Checks, preconditions


Syntax:


.. code-block:: ada

  pragma Pre_Class (Boolean_Expression);


The ``Pre_Class`` pragma is intended to be an exact replacement for
the language-defined
``Pre'Class`` aspect, and shares its restrictions and semantics.
It must appear either immediately following the corresponding
subprogram declaration (only other pragmas may intervene), or
if there is no separate subprogram declaration, then it can
appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).

Note: This pragma is called ``Pre_Class`` rather than
``Pre'Class`` because the latter would not be strictly
conforming to the allowed syntax for pragmas. The motivation
for providing pragmas equivalent to the aspects is to allow a program
to be written using the pragmas, and then compiled if necessary
using an Ada compiler that does not recognize the pragmas or
aspects, but is prepared to ignore the pragmas. The assertion
policy that controls this pragma is ``Pre'Class``, not
``Pre_Class``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Priority_Specific_Dispatching
====================================

Syntax:


::

  pragma Priority_Specific_Dispatching (
     POLICY_IDENTIFIER,
     first_priority_EXPRESSION,
     last_priority_EXPRESSION)

  POLICY_IDENTIFIER ::=
     EDF_Across_Priorities            |
     FIFO_Within_Priorities           |
     Non_Preemptive_Within_Priorities |
     Round_Robin_Within_Priorities


This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

Pragma Profile
==============

Syntax:


.. code-block:: ada

  pragma Profile (Ravenscar | Restricted | Rational | Jorvik |
                  GNAT_Extended_Ravenscar | GNAT_Ravenscar_EDF );


This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma. This is a
configuration pragma that establishes a set of configuration pragmas
that depend on the argument. ``Ravenscar`` is standard in Ada 2005.
``Jorvik`` is standard in Ada 202x.
The other possibilities (``Restricted``, ``Rational``,
``GNAT_Extended_Ravenscar``, ``GNAT_Ravenscar_EDF``)
are implementation-defined.  ``GNAT_Extended_Ravenscar`` is an alias for ``Jorvik``.

The set of configuration pragmas is defined in the following sections.


* Pragma Profile (Ravenscar)

  The ``Ravenscar`` profile is standard in Ada 2005,
  but is available in all earlier
  versions of Ada as an implementation-defined pragma. This profile
  establishes the following set of configuration pragmas:

  * ``Task_Dispatching_Policy (FIFO_Within_Priorities)``

    [RM D.2.2] Tasks are dispatched following a preemptive
    priority-ordered scheduling policy.


  * ``Locking_Policy (Ceiling_Locking)``

    [RM D.3] While tasks and interrupts execute a protected action, they inherit
    the ceiling priority of the corresponding protected object.


  * ``Detect_Blocking``

    This pragma forces the detection of potentially blocking operations within a
    protected operation, and to raise Program_Error if that happens.

  plus the following set of restrictions:

  * ``Max_Entry_Queue_Length => 1``

    No task can be queued on a protected entry.

  * ``Max_Protected_Entries => 1``

  * ``Max_Task_Entries => 0``

    No rendezvous statements are allowed.

  * ``No_Abort_Statements``

  * ``No_Dynamic_Attachment``

  * ``No_Dynamic_Priorities``

  * ``No_Implicit_Heap_Allocations``

  * ``No_Local_Protected_Objects``

  * ``No_Local_Timing_Events``

  * ``No_Protected_Type_Allocators``

  * ``No_Relative_Delay``

  * ``No_Requeue_Statements``

  * ``No_Select_Statements``

  * ``No_Specific_Termination_Handlers``

  * ``No_Task_Allocators``

  * ``No_Task_Hierarchy``

  * ``No_Task_Termination``

  * ``Simple_Barriers``

  The Ravenscar profile also includes the following restrictions that specify
  that there are no semantic dependencies on the corresponding predefined
  packages:

  * ``No_Dependence => Ada.Asynchronous_Task_Control``

  * ``No_Dependence => Ada.Calendar``

  * ``No_Dependence => Ada.Execution_Time.Group_Budget``

  * ``No_Dependence => Ada.Execution_Time.Timers``

  * ``No_Dependence => Ada.Task_Attributes``

  * ``No_Dependence => System.Multiprocessors.Dispatching_Domains``

  This set of configuration pragmas and restrictions correspond to the
  definition of the 'Ravenscar Profile' for limited tasking, devised and
  published by the :title:`International Real-Time Ada Workshop, 1997`.
  A description is also available at
  `http://www-users.cs.york.ac.uk/~burns/ravenscar.ps <http://www-users.cs.york.ac.uk/~burns/ravenscar.ps>`_.

  The original definition of the profile was revised at subsequent IRTAW
  meetings. It has been included in the ISO
  :title:`Guide for the Use of the Ada Programming Language in High Integrity Systems`,
  and was made part of the Ada 2005 standard.
  The formal definition given by
  the Ada Rapporteur Group (ARG) can be found in two Ada Issues (AI-249 and
  AI-305) available at
  `http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00249.txt <http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00249.txt>`_ and
  `http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00305.txt <http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00305.txt>`_.

  The above set is a superset of the restrictions provided by pragma
  ``Profile (Restricted)``, it includes six additional restrictions
  (``Simple_Barriers``, ``No_Select_Statements``,
  ``No_Calendar``, ``No_Implicit_Heap_Allocations``,
  ``No_Relative_Delay`` and ``No_Task_Termination``).  This means
  that pragma ``Profile (Ravenscar)``, like the pragma
  ``Profile (Restricted)``,
  automatically causes the use of a simplified,
  more efficient version of the tasking run-time library.

* Pragma Profile (Jorvik)

  ``Jorvik`` is the new profile added to the Ada 202x draft standard,
  previously implemented under the name ``GNAT_Extended_Ravenscar``.

  The ``No_Implicit_Heap_Allocations`` restriction has been replaced
  by ``No_Implicit_Task_Allocations`` and
  ``No_Implicit_Protected_Object_Allocations``.

  The ``Simple_Barriers`` restriction has been replaced by
  ``Pure_Barriers``.

  The ``Max_Protected_Entries``, ``Max_Entry_Queue_Length``, and
  ``No_Relative_Delay`` restrictions have been removed.

  Details on the rationale for ``Jorvik`` and implications for use may be
  found in :title:`A New Ravenscar-Based Profile` by P. Rogers, J. Ruiz,
  T. Gingold and P. Bernardi, in :title:`Reliable Software Technologies --
  Ada Europe 2017`, Springer-Verlag Lecture Notes in Computer Science,
  Number 10300.


* Pragma Profile (GNAT_Ravenscar_EDF)

  This profile corresponds to the Ravenscar profile but using
  EDF_Across_Priority as the Task_Scheduling_Policy.

* Pragma Profile (Restricted)

  This profile corresponds to the GNAT restricted run time. It
  establishes the following set of restrictions:

  * ``No_Abort_Statements``
  * ``No_Entry_Queue``
  * ``No_Task_Hierarchy``
  * ``No_Task_Allocators``
  * ``No_Dynamic_Priorities``
  * ``No_Terminate_Alternatives``
  * ``No_Dynamic_Attachment``
  * ``No_Protected_Type_Allocators``
  * ``No_Local_Protected_Objects``
  * ``No_Requeue_Statements``
  * ``No_Task_Attributes_Package``
  * ``Max_Asynchronous_Select_Nesting =  0``
  * ``Max_Task_Entries =  0``
  * ``Max_Protected_Entries = 1``
  * ``Max_Select_Alternatives = 0``

  This set of restrictions causes the automatic selection of a simplified
  version of the run time that provides improved performance for the
  limited set of tasking functionality permitted by this set of restrictions.

* Pragma Profile (Rational)

  The Rational profile is intended to facilitate porting legacy code that
  compiles with the Rational APEX compiler, even when the code includes non-
  conforming Ada constructs.  The profile enables the following three pragmas:

  * ``pragma Implicit_Packing``
  * ``pragma Overriding_Renamings``
  * ``pragma Use_VADS_Size``


Pragma Profile_Warnings
=======================

Syntax:


.. code-block:: ada

  pragma Profile_Warnings (Ravenscar | Restricted | Rational);


This is an implementation-defined pragma that is similar in
effect to ``pragma Profile`` except that instead of
generating ``Restrictions`` pragmas, it generates
``Restriction_Warnings`` pragmas. The result is that
violations of the profile generate warning messages instead
of error messages.

.. _Pragma-Program_Exit:

Pragma Program_Exit
===================

Syntax:

.. code-block:: ada

  pragma Program_Exit [ (boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Program_Exit``
in the SPARK 2014 Reference Manual, section 6.1.10.

Pragma Propagate_Exceptions
===========================
.. index:: Interfacing to C++


Syntax:


.. code-block:: ada

  pragma Propagate_Exceptions;


This pragma is now obsolete and, other than generating a warning if warnings
on obsolescent features are enabled, is ignored.
It is retained for compatibility
purposes. It used to be used in connection with optimization of
a now-obsolete mechanism for implementation of exceptions.

Pragma Provide_Shift_Operators
==============================
.. index:: Shift operators


Syntax:


.. code-block:: ada

  pragma Provide_Shift_Operators (integer_first_subtype_LOCAL_NAME);


This pragma can be applied to a first subtype local name that specifies
either an unsigned or signed type. It has the effect of providing the
five shift operators (Shift_Left, Shift_Right, Shift_Right_Arithmetic,
Rotate_Left and Rotate_Right) for the given type. It is similar to
including the function declarations for these five operators, together
with the pragma Import (Intrinsic, ...) statements.

Pragma Psect_Object
===================

Syntax:


::

  pragma Psect_Object (
       [Internal =>] LOCAL_NAME,
    [, [External =>] EXTERNAL_SYMBOL]
    [, [Size     =>] EXTERNAL_SYMBOL]);

  EXTERNAL_SYMBOL ::=
    IDENTIFIER
  | static_string_EXPRESSION


This pragma is identical in effect to pragma ``Common_Object``.

.. _Pragma-Pure_Function:

Pragma Pure_Function
====================

Syntax:


::

  pragma Pure_Function ([Entity =>] function_LOCAL_NAME);


This pragma appears in the same declarative part as a function
declaration (or a set of function declarations if more than one
overloaded declaration exists, in which case the pragma applies
to all entities).  It specifies that the function ``Entity`` is
to be considered pure for the purposes of code generation.  This means
that the compiler can assume that there are no side effects, and
in particular that two identical calls produce the same result in
the same context. It also means that the function can be used in
an address clause.

Note that, quite deliberately, there are no static checks to try
to ensure that this promise is met, so ``Pure_Function`` can be used
with functions that are conceptually pure, even if they do modify
global variables.  For example, a square root function that is
instrumented to count the number of times it is called is still
conceptually pure, and can still be optimized, even though it
modifies a global variable (the count).  Memo functions are another
example (where a table of previous calls is kept and consulted to
avoid re-computation).

Note also that the normal rules excluding optimization of subprograms
in pure units (when parameter types are descended from System.Address,
or when the full view of a parameter type is limited), do not apply
for the Pure_Function case. If you explicitly specify Pure_Function,
the compiler may optimize away calls with identical arguments, and
if that results in unexpected behavior, the proper action is not to
use the pragma for subprograms that are not (conceptually) pure.

Note: Most functions in a ``Pure`` package are automatically pure, and
there is no need to use pragma ``Pure_Function`` for such functions.  One
exception is any function that has at least one formal of type
``System.Address`` or a type derived from it.  Such functions are not
considered pure by default, since the compiler assumes that the
``Address`` parameter may be functioning as a pointer and that the
referenced data may change even if the address value does not.
Similarly, imported functions are not considered to be pure by default,
since there is no way of checking that they are in fact pure.  The use
of pragma ``Pure_Function`` for such a function will override these default
assumption, and cause the compiler to treat a designated subprogram as pure
in these cases.

Note: If pragma ``Pure_Function`` is applied to a renamed function, it
applies to the underlying renamed function.  This can be used to
disambiguate cases of overloading where some but not all functions
in a set of overloaded functions are to be designated as pure.

If pragma ``Pure_Function`` is applied to a library-level function, the
function is also considered pure from an optimization point of view, but the
unit is not a Pure unit in the categorization sense. So for example, a function
thus marked is free to ``with`` non-pure units.

Pragma Rational
===============

Syntax:


.. code-block:: ada

  pragma Rational;


This pragma is considered obsolescent, but is retained for
compatibility purposes. It is equivalent to:


.. code-block:: ada

  pragma Profile (Rational);


Pragma Ravenscar
================

Syntax:


.. code-block:: ada

  pragma Ravenscar;


This pragma is considered obsolescent, but is retained for
compatibility purposes. It is equivalent to:


.. code-block:: ada

  pragma Profile (Ravenscar);


which is the preferred method of setting the ``Ravenscar`` profile.

.. _Pragma-Refined_Depends:

Pragma Refined_Depends
======================

Syntax:

.. code-block:: ada

  pragma Refined_Depends (DEPENDENCY_RELATION);

  DEPENDENCY_RELATION ::=
       null
    | (DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE})

  DEPENDENCY_CLAUSE ::=
      OUTPUT_LIST =>[+] INPUT_LIST
    | NULL_DEPENDENCY_CLAUSE

  NULL_DEPENDENCY_CLAUSE ::= null => INPUT_LIST

  OUTPUT_LIST ::= OUTPUT | (OUTPUT {, OUTPUT})

  INPUT_LIST ::= null | INPUT | (INPUT {, INPUT})

  OUTPUT ::= NAME | FUNCTION_RESULT
  INPUT  ::= NAME

  where FUNCTION_RESULT is a function Result attribute_reference

For the semantics of this pragma, see the entry for aspect ``Refined_Depends`` in
the SPARK 2014 Reference Manual, section 6.1.5.

.. _Pragma-Refined_Global:

Pragma Refined_Global
=====================

Syntax:

.. code-block:: ada

  pragma Refined_Global (GLOBAL_SPECIFICATION);

  GLOBAL_SPECIFICATION ::=
       null
    | (GLOBAL_LIST)
    | (MODED_GLOBAL_LIST {, MODED_GLOBAL_LIST})

  MODED_GLOBAL_LIST ::= MODE_SELECTOR => GLOBAL_LIST

  MODE_SELECTOR ::= In_Out | Input | Output | Proof_In
  GLOBAL_LIST   ::= GLOBAL_ITEM | (GLOBAL_ITEM {, GLOBAL_ITEM})
  GLOBAL_ITEM   ::= NAME

For the semantics of this pragma, see the entry for aspect ``Refined_Global`` in
the SPARK 2014 Reference Manual, section 6.1.4.

.. _Pragma-Refined_Post:

Pragma Refined_Post
===================

Syntax:

.. code-block:: ada

  pragma Refined_Post (boolean_EXPRESSION);

For the semantics of this pragma, see the entry for aspect ``Refined_Post`` in
the SPARK 2014 Reference Manual, section 7.2.7.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

.. _Pragma-Refined_State:

Pragma Refined_State
====================

Syntax:

.. code-block:: ada

  pragma Refined_State (REFINEMENT_LIST);

  REFINEMENT_LIST ::=
    (REFINEMENT_CLAUSE {, REFINEMENT_CLAUSE})

  REFINEMENT_CLAUSE ::= state_NAME => CONSTITUENT_LIST

  CONSTITUENT_LIST ::=
       null
    |  CONSTITUENT
    | (CONSTITUENT {, CONSTITUENT})

  CONSTITUENT ::= object_NAME | state_NAME

For the semantics of this pragma, see the entry for aspect ``Refined_State`` in
the SPARK 2014 Reference Manual, section 7.2.2.

Pragma Relative_Deadline
========================

Syntax:


.. code-block:: ada

  pragma Relative_Deadline (time_span_EXPRESSION);


This pragma is standard in Ada 2005, but is available in all earlier
versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.

.. _Pragma-Remote_Access_Type:

Pragma Remote_Access_Type
=========================

Syntax:


::

  pragma Remote_Access_Type ([Entity =>] formal_access_type_LOCAL_NAME);


This pragma appears in the formal part of a generic declaration.
It specifies an exception to the RM rule from E.2.2(17/2), which forbids
the use of a remote access to class-wide type as actual for a formal
access type.

When this pragma applies to a formal access type ``Entity``, that
type is treated as a remote access to class-wide type in the generic.
It must be a formal general access type, and its designated type must
be the class-wide type of a formal tagged limited private type from the
same generic declaration.

In the generic unit, the formal type is subject to all restrictions
pertaining to remote access to class-wide types. At instantiation, the
actual type must be a remote access to class-wide type.

Pragma Rename_Pragma
============================
.. index:: Pragmas, synonyms

Syntax:


::

  pragma Rename_Pragma (
           [New_Name =>] IDENTIFIER,
           [Renamed  =>] pragma_IDENTIFIER);

This pragma provides a mechanism for supplying new names for existing
pragmas. The ``New_Name`` identifier can subsequently be used as a synonym for
the Renamed pragma. For example, suppose you have code that was originally
developed on a compiler that supports Inline_Only as an implementation defined
pragma. And suppose the semantics of pragma Inline_Only are identical to (or at
least very similar to) the GNAT implementation defined pragma
Inline_Always. You could globally replace Inline_Only with Inline_Always.

However, to avoid that source modification, you could instead add a
configuration pragma:

.. code-block:: ada

  pragma Rename_Pragma (
           New_Name => Inline_Only,
           Renamed  => Inline_Always);


Then GNAT will treat "pragma Inline_Only ..." as if you had written
"pragma Inline_Always ...".

Pragma Inline_Only will not necessarily mean the same thing as the other Ada
compiler; it's up to you to make sure the semantics are close enough.

Pragma Restricted_Run_Time
==========================

Syntax:


.. code-block:: ada

  pragma Restricted_Run_Time;


This pragma is considered obsolescent, but is retained for
compatibility purposes. It is equivalent to:


.. code-block:: ada

  pragma Profile (Restricted);


which is the preferred method of setting the restricted run time
profile.

Pragma Restriction_Warnings
===========================

Syntax:


::

  pragma Restriction_Warnings
    (restriction_IDENTIFIER {, restriction_IDENTIFIER});


This pragma allows a series of restriction identifiers to be
specified (the list of allowed identifiers is the same as for
pragma ``Restrictions``). For each of these identifiers
the compiler checks for violations of the restriction, but
generates a warning message rather than an error message
if the restriction is violated.

One use of this is in situations where you want to know
about violations of a restriction, but you want to ignore some of
these violations. Consider this example, where you want to set
Ada_95 mode and enable style checks, but you want to know about
any other use of implementation pragmas:


.. code-block:: ada

  pragma Restriction_Warnings (No_Implementation_Pragmas);
  pragma Warnings (Off, "violation of No_Implementation_Pragmas");
  pragma Ada_95;
  pragma Style_Checks ("2bfhkM160");
  pragma Warnings (On, "violation of No_Implementation_Pragmas");


By including the above lines in a configuration pragmas file,
the Ada_95 and Style_Checks pragmas are accepted without
generating a warning, but any other use of implementation
defined pragmas will cause a warning to be generated.

Pragma Reviewable
=================

Syntax:


.. code-block:: ada

  pragma Reviewable;


This pragma is an RM-defined standard pragma, but has no effect on the
program being compiled, or on the code generated for the program.

To obtain the required output specified in RM H.3.1, the compiler must be
run with various special switches as follows:

* *Where compiler-generated run-time checks remain*

  The switch *-gnatGL*
  may be used to list the expanded code in pseudo-Ada form.
  Runtime checks show up in the listing either as explicit
  checks or operators marked with {} to indicate a check is present.


* *An identification of known exceptions at compile time*

  If the program is compiled with *-gnatwa*,
  the compiler warning messages will indicate all cases where the compiler
  detects that an exception is certain to occur at run time.


* *Possible reads of uninitialized variables*

  The compiler warns of many such cases, but its output is incomplete.

.. only:: PRO or GPL

  The CodePeer analysis tool
  may be used to obtain a comprehensive list of all
  possible points at which uninitialized data may be read.

.. only:: FSF

  A supplemental static analysis tool
  may be used to obtain a comprehensive list of all
  possible points at which uninitialized data may be read.


* *Where run-time support routines are implicitly invoked*

  In the output from *-gnatGL*,
  run-time calls are explicitly listed as calls to the relevant
  run-time routine.


* *Object code listing*

  This may be obtained either by using the *-S* switch,
  or the objdump utility.


* *Constructs known to be erroneous at compile time*

  These are identified by warnings issued by the compiler (use *-gnatwa*).


* *Stack usage information*

  Static stack usage data (maximum per-subprogram) can be obtained via the
  *-fstack-usage* switch to the compiler.
  Dynamic stack usage data (per task) can be obtained via the *-u* switch
  to gnatbind

.. only:: PRO or GPL

  The gnatstack utility
  can be used to provide additional information on stack usage.


* *Object code listing of entire partition*

  This can be obtained by compiling the partition with *-S*,
  or by applying objdump
  to all the object files that are part of the partition.


* *A description of the run-time model*

  The full sources of the run-time are available, and the documentation of
  these routines describes how these run-time routines interface to the
  underlying operating system facilities.


* *Control and data-flow information*

.. only:: PRO or GPL

  The CodePeer tool
  may be used to obtain complete control and data-flow information, as well as
  comprehensive messages identifying possible problems based on this
  information.

.. only:: FSF

  A supplemental static analysis tool
  may be used to obtain complete control and data-flow information, as well as
  comprehensive messages identifying possible problems based on this
  information.

.. _Pragma-Secondary_Stack_Size:

Pragma Secondary_Stack_Size
===========================

Syntax:

.. code-block:: ada

  pragma Secondary_Stack_Size (integer_EXPRESSION);

This pragma appears within the task definition of a single task declaration
or a task type declaration (like pragma ``Storage_Size``) and applies to all
task objects of that type. The argument specifies the size of the secondary
stack to be used by these task objects, and must be of an integer type. The
secondary stack is used to handle functions that return a variable-sized
result, for example a function returning an unconstrained String.

Note this pragma only applies to targets using fixed secondary stacks, like
VxWorks 653 and bare board targets, where a fixed block for the
secondary stack is allocated from the primary stack of the task. By default,
these targets assign a percentage of the primary stack for the secondary stack,
as defined by ``System.Parameter.Sec_Stack_Percentage``. With this pragma,
an ``integer_EXPRESSION`` of bytes is assigned from the primary stack instead.

For most targets, the pragma does not apply as the secondary stack grows on
demand: allocated as a chain of blocks in the heap. The default size of these
blocks can be modified via the :switch:`-D` binder option as described in
:title:`GNAT User's Guide`.

Note that no check is made to see if the secondary stack can fit inside the
primary stack.

Note the pragma cannot appear when the restriction ``No_Secondary_Stack``
is in effect.

Pragma Share_Generic
====================

Syntax:


::

  pragma Share_Generic (GNAME {, GNAME});

  GNAME ::= generic_unit_NAME | generic_instance_NAME


This pragma is provided for compatibility with Dec Ada 83. It has
no effect in GNAT (which does not implement shared generics), other
than to check that the given names are all names of generic units or
generic instances.

.. _Pragma-Shared:

Pragma Shared
=============

This pragma is provided for compatibility with Ada 83. The syntax and
semantics are identical to pragma Atomic.

Pragma Short_Circuit_And_Or
===========================

Syntax:


.. code-block:: ada

  pragma Short_Circuit_And_Or;


This configuration pragma causes the predefined AND and OR operators of
type Standard.Boolean to have short-circuit semantics. That is, they
behave like AND THEN and OR ELSE; the right-hand side is not evaluated
if the left-hand side determines the result. This may be useful in the
context of certification protocols requiring the use of short-circuited
logical operators.

There is no requirement that all units in a partition use this option.
However, mixing of short-circuit and non-short-circuit semantics can be
confusing. Therefore, the recommended use is to put the pragma in a
configuration file that applies to the whole program. Alternatively, if
you have a legacy library that should not use this pragma, you can put
it in a separate library project that does not use the pragma.
In any case, fine-grained mixing of the different semantics is not
recommended. If pragma ``Short_Circuit_And_Or`` is specified, then it
is illegal to rename the predefined Boolean AND and OR, or to pass
them to generic formal functions; this corresponds to the fact that
AND THEN and OR ELSE cannot be renamed nor passed as generic formal
functions.

Note that this pragma has no effect on other logical operators --
predefined operators of modular types, array-of-boolean types and types
derived from Standard.Boolean, nor user-defined operators.

See also the pragma ``Unevaluated_Use_Of_Old`` and the restriction
``No_Direct_Boolean_Operators``, which may be useful in conjunction
with ``Short_Circuit_And_Or``.

Pragma Short_Descriptors
========================

Syntax:


.. code-block:: ada

  pragma Short_Descriptors;


This pragma is provided for compatibility with other Ada implementations. It
is recognized but ignored by all current versions of GNAT.

.. _Pragma-Side_Effects:

Pragma Side_Effects
===================

Syntax:

.. code-block:: ada

  pragma Side_Effects [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect
``Side_Effects`` in the SPARK Reference Manual, section 6.1.12.

.. _Pragma-Simple_Storage_Pool_Type:

Pragma Simple_Storage_Pool_Type
===============================
.. index:: Storage pool, simple

.. index:: Simple storage pool

Syntax:


.. code-block:: ada

  pragma Simple_Storage_Pool_Type (type_LOCAL_NAME);


A type can be established as a 'simple storage pool type' by applying
the representation pragma ``Simple_Storage_Pool_Type`` to the type.
A type named in the pragma must be a library-level immutably limited record
type or limited tagged type declared immediately within a package declaration.
The type can also be a limited private type whose full type is allowed as
a simple storage pool type.

For a simple storage pool type ``SSP``, nonabstract primitive subprograms
``Allocate``, ``Deallocate``, and ``Storage_Size`` can be declared that
are subtype conformant with the following subprogram declarations:


.. code-block:: ada

  procedure Allocate
    (Pool                     : in out SSP;
     Storage_Address          : out System.Address;
     Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
     Alignment                : System.Storage_Elements.Storage_Count);

  procedure Deallocate
    (Pool : in out SSP;
     Storage_Address          : System.Address;
     Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
     Alignment                : System.Storage_Elements.Storage_Count);

  function Storage_Size (Pool : SSP)
    return System.Storage_Elements.Storage_Count;


Procedure ``Allocate`` must be declared, whereas ``Deallocate`` and
``Storage_Size`` are optional. If ``Deallocate`` is not declared, then
applying an unchecked deallocation has no effect other than to set its actual
parameter to null. If ``Storage_Size`` is not declared, then the
``Storage_Size`` attribute applied to an access type associated with
a pool object of type SSP returns zero. Additional operations can be declared
for a simple storage pool type (such as for supporting a mark/release
storage-management discipline).

An object of a simple storage pool type can be associated with an access
type by specifying the attribute
:ref:`Simple_Storage_Pool <Attribute_Simple_Storage_Pool>`. For example:


.. code-block:: ada

  My_Pool : My_Simple_Storage_Pool_Type;

  type Acc is access My_Data_Type;

  for Acc'Simple_Storage_Pool use My_Pool;



See attribute :ref:`Simple_Storage_Pool <Attribute_Simple_Storage_Pool>`
for further details.

..  _Pragma_Source_File_Name:

Pragma Source_File_Name
=======================

Syntax:


::

  pragma Source_File_Name (
    [Unit_Name     =>] unit_NAME,
    Spec_File_Name =>  STRING_LITERAL,
    [Index => INTEGER_LITERAL]);

  pragma Source_File_Name (
    [Unit_Name     =>] unit_NAME,
    Body_File_Name =>  STRING_LITERAL,
    [Index => INTEGER_LITERAL]);


Use this 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).
``unit_name`` is mapped to ``file_name_literal``.  The identifier for
the second argument is required, and indicates whether this is the file
name for the spec or for the body.

The optional Index argument should be used when a file contains multiple
units, and when you do not want to use ``gnatchop`` to separate then
into multiple files (which is the recommended procedure to limit the
number of recompilations that are needed when some sources change).
For instance, if the source file :file:`source.ada` contains


.. code-block:: ada

  package B is
  ...
  end B;

  with B;
  procedure A is
  begin
     ..
  end A;


you could use the following configuration pragmas:


.. code-block:: ada

  pragma Source_File_Name
    (B, Spec_File_Name => "source.ada", Index => 1);
  pragma Source_File_Name
    (A, Body_File_Name => "source.ada", Index => 2);


Note that the ``gnatname`` utility can also be used to generate those
configuration pragmas.

Another form of the ``Source_File_Name`` pragma allows
the specification of patterns defining alternative file naming schemes
to apply to all files.


::

  pragma Source_File_Name
    (  [Spec_File_Name  =>] STRING_LITERAL
     [,[Casing          =>] CASING_SPEC]
     [,[Dot_Replacement =>] STRING_LITERAL]);

  pragma Source_File_Name
    (  [Body_File_Name  =>] STRING_LITERAL
     [,[Casing          =>] CASING_SPEC]
     [,[Dot_Replacement =>] STRING_LITERAL]);

  pragma Source_File_Name
    (  [Subunit_File_Name =>] STRING_LITERAL
     [,[Casing            =>] CASING_SPEC]
     [,[Dot_Replacement   =>] STRING_LITERAL]);

  CASING_SPEC ::= Lowercase | Uppercase | Mixedcase


The first argument is a pattern that contains a single asterisk indicating
the point at which the unit name is to be inserted in the pattern string
to form the file name.  The second argument is optional.  If present it
specifies the casing of the unit name in the resulting file name string.
The default is lower case.  Finally the third argument allows for systematic
replacement of any dots in the unit name by the specified string literal.

Note that Source_File_Name pragmas should not be used if you are using
project files. The reason for this rule is that the project manager is not
aware of these pragmas, and so other tools that use the project file would not
be aware of the intended naming conventions. If you are using project files,
file naming is controlled by Source_File_Name_Project pragmas, which are
usually supplied automatically by the project manager. A pragma
Source_File_Name cannot appear after a :ref:`Pragma_Source_File_Name_Project`.

For more details on the use of the ``Source_File_Name`` pragma, see the
sections on `Using Other File Names` and `Alternative File Naming Schemes`
in the :title:`GNAT User's Guide`.

..  _Pragma_Source_File_Name_Project:

Pragma Source_File_Name_Project
===============================

This pragma has the same syntax and semantics as pragma Source_File_Name.
It is only allowed as a stand-alone configuration pragma.
It cannot appear after a :ref:`Pragma_Source_File_Name`, and
most importantly, once pragma Source_File_Name_Project appears,
no further Source_File_Name pragmas are allowed.

The intention is that Source_File_Name_Project pragmas are always
generated by the Project Manager in a manner consistent with the naming
specified in a project file, and when naming is controlled in this manner,
it is not permissible to attempt to modify this naming scheme using
Source_File_Name or Source_File_Name_Project pragmas (which would not be
known to the project manager).

Pragma Source_Reference
=======================

Syntax:


.. code-block:: ada

  pragma Source_Reference (INTEGER_LITERAL, STRING_LITERAL);


This pragma must appear as the first line of a source file.
``integer_literal`` is the logical line number of the line following
the pragma line (for use in error messages and debugging
information).  ``string_literal`` is a static string constant that
specifies the file name to be used in error messages and debugging
information.  This is most notably used for the output of ``gnatchop``
with the *-r* switch, to make sure that the original unchopped
source file is the one referred to.

The second argument must be a string literal, it cannot be a static
string expression other than a string literal.  This is because its value
is needed for error messages issued by all phases of the compiler.

.. _Pragma-SPARK_Mode:

Pragma SPARK_Mode
=================

Syntax:


::

  pragma SPARK_Mode [(On | Off)] ;


In general a program can have some parts that are in SPARK 2014 (and
follow all the rules in the SPARK Reference Manual), and some parts
that are full Ada 2012.

The SPARK_Mode pragma is used to identify which parts are in SPARK
2014 (by default programs are in full Ada). The SPARK_Mode pragma can
be used in the following places:


*
  As a configuration pragma, in which case it sets the default mode for
  all units compiled with this pragma.

*
  Immediately following a library-level subprogram spec

*
  Immediately within a library-level package body

*
  Immediately following the ``private`` keyword of a library-level
  package spec

*
  Immediately following the ``begin`` keyword of a library-level
  package body

*
  Immediately within a library-level subprogram body


Normally a subprogram or package spec/body inherits the current mode
that is active at the point it is declared. But this can be overridden
by pragma within the spec or body as above.

The basic consistency rule is that you can't turn SPARK_Mode back
``On``, once you have explicitly (with a pragma) turned if
``Off``. So the following rules apply:

If a subprogram spec has SPARK_Mode ``Off``, then the body must
also have SPARK_Mode ``Off``.

For a package, we have four parts:

*
  the package public declarations
*
  the package private part
*
  the body of the package
*
  the elaboration code after ``begin``

For a package, the rule is that if you explicitly turn SPARK_Mode
``Off`` for any part, then all the following parts must have
SPARK_Mode ``Off``. Note that this may require repeating a pragma
SPARK_Mode (``Off``) in the body. For example, if we have a
configuration pragma SPARK_Mode (``On``) that turns the mode on by
default everywhere, and one particular package spec has pragma
SPARK_Mode (``Off``), then that pragma will need to be repeated in
the package body.

Pragma Static_Elaboration_Desired
=================================

Syntax:


.. code-block:: ada

  pragma Static_Elaboration_Desired;


This pragma is used to indicate that the compiler should attempt to initialize
statically the objects declared in the library unit to which the pragma applies,
when these objects are initialized (explicitly or implicitly) by an aggregate.
In the absence of this pragma, aggregates in object declarations are expanded
into assignments and loops, even when the aggregate components are static
constants. When the aggregate is present the compiler builds a static expression
that requires no run-time code, so that the initialized object can be placed in
read-only data space. If the components are not static, or the aggregate has
more that 100 components, the compiler emits a warning that the pragma cannot
be obeyed. (See also the restriction No_Implicit_Loops, which supports static
construction of larger aggregates with static components that include an others
choice.)

Pragma Stream_Convert
=====================

Syntax:


::

  pragma Stream_Convert (
    [Entity =>] type_LOCAL_NAME,
    [Read   =>] function_NAME,
    [Write  =>] function_NAME);


This pragma provides an efficient way of providing user-defined stream
attributes.  Not only is it simpler to use than specifying the attributes
directly, but more importantly, it allows the specification to be made in such
a way that the predefined unit Ada.Streams is not loaded unless it is actually
needed (i.e. unless the stream attributes are actually used); the use of
the Stream_Convert pragma adds no overhead at all, unless the stream
attributes are actually used on the designated type.

The first argument specifies the type for which stream functions are
provided.  The second parameter provides a function used to read values
of this type.  It must name a function whose argument type may be any
subtype, and whose returned type must be the type given as the first
argument to the pragma.

The meaning of the ``Read`` parameter is that if a stream attribute directly
or indirectly specifies reading of the type given as the first parameter,
then a value of the type given as the argument to the Read function is
read from the stream, and then the Read function is used to convert this
to the required target type.

Similarly the ``Write`` parameter specifies how to treat write attributes
that directly or indirectly apply to the type given as the first parameter.
It must have an input parameter of the type specified by the first parameter,
and the return type must be the same as the input type of the Read function.
The effect is to first call the Write function to convert to the given stream
type, and then write the result type to the stream.

The Read and Write functions must not be overloaded subprograms.  If necessary
renamings can be supplied to meet this requirement.
The usage of this attribute is best illustrated by a simple example, taken
from the GNAT implementation of package Ada.Strings.Unbounded:


.. code-block:: ada

  function To_Unbounded (S : String) return Unbounded_String
    renames To_Unbounded_String;

  pragma Stream_Convert
    (Unbounded_String, To_Unbounded, To_String);


The specifications of the referenced functions, as given in the Ada
Reference Manual are:


.. code-block:: ada

  function To_Unbounded_String (Source : String)
    return Unbounded_String;

  function To_String (Source : Unbounded_String)
    return String;


The effect is that if the value of an unbounded string is written to a stream,
then the representation of the item in the stream is in the same format that
would be used for ``Standard.String'Output``, and this same representation
is expected when a value of this type is read from the stream. Note that the
value written always includes the bounds, even for Unbounded_String'Write,
since Unbounded_String is not an array type.

Note that the ``Stream_Convert`` pragma is not effective in the case of
a derived type of a non-limited tagged type. If such a type is specified then
the pragma is silently ignored, and the default implementation of the stream
attributes is used instead.

Pragma Style_Checks
===================

Syntax:


::

  pragma Style_Checks (string_LITERAL | ALL_CHECKS |
                       On | Off [, LOCAL_NAME]);


This pragma is used in conjunction with compiler switches to control the
built in style checking provided by GNAT.  The compiler switches, if set,
provide an initial setting for the switches, and this pragma may be used
to modify these settings, or the settings may be provided entirely by
the use of the pragma.  This pragma can be used anywhere that a pragma
is legal, including use as a configuration pragma (including use in
the :file:`gnat.adc` file).

The form with a string literal specifies which style options are to be
activated.  These are additive, so they apply in addition to any previously
set style check options.  The codes for the options are the same as those
used in the *-gnaty* switch to *gcc* or *gnatmake*.
For example the following two methods can be used to enable
layout checking and to change the maximum nesting level value:

*

  .. code-block:: ada

    --  switch on layout checks
    pragma Style_Checks ("l");
    --  set the number of maximum allowed nesting levels to 15
    pragma Style_Checks ("L15");

*

  ::

    gcc -c -gnatyl -gnatyL15 ...


The string literal values can be cumulatively switched on and off by prefixing
the value with ``+`` or ``-``, where:

* ``+`` is equivalent to no prefix. It applies the check referenced by the
  literal value;
* ``-`` switches the referenced check off.


.. code-block:: ada
  :linenos:
  :emphasize-lines: 15

  --  allow misaligned block by disabling layout check
  pragma Style_Checks ("-l");
  declare
      msg : constant String := "Hello";
  begin
      Put_Line (msg);
      end;

  --  enable the layout check again
  pragma Style_Checks ("l");
  declare
      msg : constant String := "Hello";
  begin
      Put_Line (msg);
      end;

The code above contains two layout errors, however, only
the last line is picked up by the compiler.

Similarly, the switches containing a numeric value can be applied in sequence.
In the example below, the permitted nesting level is reduced in in the middle
block and the compiler raises a warning on the highlighted line.

.. code-block:: ada
  :linenos:
  :emphasize-lines: 15

  -- Permit 3 levels of nesting
  pragma Style_Checks ("L3");

  procedure Main is
  begin
      if True then
        if True then
            null;
        end if;
      end if;
      --  Reduce permitted nesting levels to 2.
      --  Note that "+L2" and "L2" are equivalent.
      pragma Style_Checks ("+L2");
      if True then
        if True then
            null;
        end if;
      end if;
      --  Disable checking permitted nesting levels.
      --  Note that the number after "-L" is insignificant,
      --  "-L", "-L3" and "-Lx" are all equivalent.
      pragma Style_Checks ("-L3");
      if True then
        if True then
            null;
        end if;
      end if;
  end Main;

The form ``ALL_CHECKS`` activates all standard checks (its use is equivalent
to the use of the :switch:`gnaty` switch with no options.
See the :title:`GNAT User's Guide` for details.)

Note: the behavior is slightly different in GNAT mode (:switch:`-gnatg` used).
In this case, ``ALL_CHECKS`` implies the standard set of GNAT mode style check
options (i.e. equivalent to :switch:`-gnatyg`).

The forms with ``Off`` and ``On``
can be used to temporarily disable style checks
as shown in the following example:

.. code-block:: ada

  pragma Style_Checks ("k"); -- requires keywords in lower case
  pragma Style_Checks (Off); -- turn off style checks
  NULL;                      -- this will not generate an error message
  pragma Style_Checks (On);  -- turn style checks back on
  NULL;                      -- this will generate an error message


Finally the two argument form is allowed only if the first argument is
``On`` or ``Off``.  The effect is to turn of semantic style checks
for the specified entity, as shown in the following example:


.. code-block:: ada

  pragma Style_Checks ("r"); -- require consistency of identifier casing
  Arg : Integer;
  Rf1 : Integer := ARG;      -- incorrect, wrong case
  pragma Style_Checks (Off, Arg);
  Rf2 : Integer := ARG;      -- OK, no error

Pragma Subprogram_Variant
=========================
.. index:: Subprogram_Variant

Syntax:


::

  pragma Subprogram_Variant (SUBPROGRAM_VARIANT_LIST);

  SUBPROGRAM_VARIANT_LIST ::=
    STRUCTURAL_SUBPROGRAM_VARIANT_ITEM
  | NUMERIC_SUBPROGRAM_VARIANT_ITEMS

  NUMERIC_SUBPROGRAM_VARIANT_ITEMS ::=
    NUMERIC_SUBPROGRAM_VARIANT_ITEM {, NUMERIC_SUBPROGRAM_VARIANT_ITEM}

  NUMERIC_SUBPROGRAM_VARIANT_ITEM ::=
    CHANGE_DIRECTION => EXPRESSION

  STRUCTURAL_SUBPROGRAM_VARIANT_ITEM ::=
    STRUCTURAL => EXPRESSION

  CHANGE_DIRECTION ::= Increases | Decreases

The ``Subprogram_Variant`` pragma is intended to be an exact replacement for
the implementation-defined ``Subprogram_Variant`` aspect, and shares its
restrictions and semantics.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section 11.4.2.

Pragma Subtitle
===============

Syntax:


::

  pragma Subtitle ([Subtitle =>] STRING_LITERAL);


This pragma is recognized for compatibility with other Ada compilers
but is ignored by GNAT.

Pragma Suppress
===============

Syntax:


::

  pragma Suppress (Identifier [, [On =>] Name]);


This is a standard pragma, and supports all the check names required in
the RM. It is included here because GNAT recognizes some additional check
names that are implementation defined (as permitted by the RM):


*
  ``Alignment_Check`` can be used to suppress alignment checks on addresses
  used in address clauses. Note that ``Alignment_Check`` is suppressed by
  default on non-strict alignment machines (such as the x86).

*
  ``Atomic_Synchronization`` can be used to suppress the special memory
  synchronization instructions that are normally generated for access to
  ``Atomic`` variables to ensure correct synchronization between tasks
  that use such variables for synchronization purposes.

*
  ``Duplicated_Tag_Check`` Can be used to suppress the check that is generated
  for a duplicated tag value when a tagged type is declared.

*
  ``Container_Checks`` Can be used to suppress all checks within Ada.Containers
  and instances of its children, including Tampering_Check.

*
  ``Tampering_Check`` Can be used to suppress tampering check in the containers.

*
  ``Predicate_Check`` can be used to control whether predicate checks are
  active. It is applicable only to predicates for which the policy is
  ``Check``. Unlike ``Assertion_Policy``, which determines if a given
  predicate is ignored or checked for the whole program, the use of
  ``Suppress`` and ``Unsuppress`` with this check name allows a given
  predicate to be turned on and off at specific points in the program.

*
  ``Validity_Check`` can be used specifically to control validity checks.
  If ``Suppress`` is used to suppress validity checks, then no validity
  checks are performed, including those specified by the appropriate compiler
  switch or the ``Validity_Checks`` pragma.

*
  Additional check names previously introduced by use of the ``Check_Name``
  pragma are also allowed.


Note that pragma Suppress gives the compiler permission to omit
checks, but does not require the compiler to omit checks. The compiler
will generate checks if they are essentially free, even when they are
suppressed. In particular, if the compiler can prove that a certain
check will necessarily fail, it will generate code to do an
unconditional 'raise', even if checks are suppressed. The compiler
warns in this case.

Of course, run-time checks are omitted whenever the compiler can prove
that they will not fail, whether or not checks are suppressed.

Pragma Suppress_All
===================

Syntax:


.. code-block:: ada

  pragma Suppress_All;


This pragma can appear anywhere within a unit.
The effect is to apply ``Suppress (All_Checks)`` to the unit
in which it appears.  This pragma is implemented for compatibility with DEC
Ada 83 usage where it appears at the end of a unit, and for compatibility
with Rational Ada, where it appears as a program unit pragma.
The use of the standard Ada pragma ``Suppress (All_Checks)``
as a normal configuration pragma is the preferred usage in GNAT.

.. _Pragma-Suppress_Debug_Info:

Pragma Suppress_Debug_Info
==========================

Syntax:


::

  pragma Suppress_Debug_Info ([Entity =>] LOCAL_NAME);


This pragma can be used to suppress generation of debug information
for the specified entity. It is intended primarily for use in debugging
the debugger, and navigating around debugger problems.

Pragma Suppress_Exception_Locations
===================================

Syntax:


.. code-block:: ada

  pragma Suppress_Exception_Locations;


In normal mode, a raise statement for an exception by default generates
an exception message giving the file name and line number for the location
of the raise. This is useful for debugging and logging purposes, but this
entails extra space for the strings for the messages. The configuration
pragma ``Suppress_Exception_Locations`` can be used to suppress the
generation of these strings, with the result that space is saved, but the
exception message for such raises is null. This configuration pragma may
appear in a global configuration pragma file, or in a specific unit as
usual. It is not required that this pragma be used consistently within
a partition, so it is fine to have some units within a partition compiled
with this pragma and others compiled in normal mode without it.

.. _Pragma-Suppress_Initialization:

Pragma Suppress_Initialization
==============================
.. index:: Suppressing initialization

.. index:: Initialization, suppression of

Syntax:


::

  pragma Suppress_Initialization ([Entity =>] variable_or_subtype_LOCAL_NAME);


Here variable_or_subtype_LOCAL_NAME is the name introduced by a type
declaration or subtype declaration or the name of a variable introduced by
an object declaration.

In the case of a type or subtype
this pragma suppresses any implicit or explicit initialization
for all variables of the given type or subtype,
including initialization resulting from the use of pragmas
Normalize_Scalars or Initialize_Scalars.

This is considered a representation item, so it cannot be given after
the type is frozen. It applies to all subsequent object declarations,
and also any allocator that creates objects of the type.

If the pragma is given for the first subtype, then it is considered
to apply to the base type and all its subtypes. If the pragma is given
for other than a first subtype, then it applies only to the given subtype.
The pragma may not be given after the type is frozen.

Note that this includes eliminating initialization of discriminants
for discriminated types, and tags for tagged types. In these cases,
you will have to use some non-portable mechanism (e.g. address
overlays or unchecked conversion) to achieve required initialization
of these fields before accessing any object of the corresponding type.

For the variable case, implicit initialization for the named variable
is suppressed, just as though its subtype had been given in a pragma
Suppress_Initialization, as described above.

Pragma Task_Name
================

Syntax


.. code-block:: ada

  pragma Task_Name (string_EXPRESSION);


This pragma appears within a task definition (like pragma
``Priority``) and applies to the task in which it appears.  The
argument must be of type String, and provides a name to be used for
the task instance when the task is created.  Note that this expression
is not required to be static, and in particular, it can contain
references to task discriminants.  This facility can be used to
provide different names for different tasks as they are created,
as illustrated in the example below.

The task name is recorded internally in the run-time structures
and is accessible to tools like the debugger.  In addition the
routine ``Ada.Task_Identification.Image`` will return this
string, with a unique task address appended.


.. code-block:: ada

  --  Example of the use of pragma Task_Name

  with Ada.Task_Identification;
  use Ada.Task_Identification;
  with Text_IO; use Text_IO;
  procedure t3 is

     type Astring is access String;

     task type Task_Typ (Name : access String) is
        pragma Task_Name (Name.all);
     end Task_Typ;

     task body Task_Typ is
        Nam : constant String := Image (Current_Task);
     begin
        Put_Line ("-->" & Nam (1 .. 14) & "<--");
     end Task_Typ;

     type Ptr_Task is access Task_Typ;
     Task_Var : Ptr_Task;

  begin
     Task_Var :=
       new Task_Typ (new String'("This is task 1"));
     Task_Var :=
       new Task_Typ (new String'("This is task 2"));
  end;


Pragma Task_Storage
===================
Syntax:


::

  pragma Task_Storage (
    [Task_Type =>] LOCAL_NAME,
    [Top_Guard =>] static_integer_EXPRESSION);


This pragma specifies the length of the guard area for tasks.  The guard
area is an additional storage area allocated to a task.  A value of zero
means that either no guard area is created or a minimal guard area is
created, depending on the target.  This pragma can appear anywhere a
``Storage_Size`` attribute definition clause is allowed for a task
type.

.. _Pragma-Test_Case:

Pragma Test_Case
================
.. index:: Test cases


Syntax:


::

  pragma Test_Case (
     [Name     =>] static_string_Expression
    ,[Mode     =>] (Nominal | Robustness)
   [, Requires =>  Boolean_Expression]
   [, Ensures  =>  Boolean_Expression]);


The ``Test_Case`` pragma allows defining fine-grain specifications
for use by testing tools.
The compiler checks the validity of the ``Test_Case`` pragma, but its
presence does not lead to any modification of the code generated by the
compiler.

``Test_Case`` pragmas may only appear immediately following the
(separate) declaration of a subprogram in a package declaration, inside
a package spec unit. Only other pragmas may intervene (that is appear
between the subprogram declaration and a test case).

The compiler checks that boolean expressions given in ``Requires`` and
``Ensures`` are valid, where the rules for ``Requires`` are the
same as the rule for an expression in ``Precondition`` and the rules
for ``Ensures`` are the same as the rule for an expression in
``Postcondition``. In particular, attributes ``'Old`` and
``'Result`` can only be used within the ``Ensures``
expression. The following is an example of use within a package spec:


.. code-block:: ada

  package Math_Functions is
     ...
     function Sqrt (Arg : Float) return Float;
     pragma Test_Case (Name     => "Test 1",
                       Mode     => Nominal,
                       Requires => Arg < 10000.0,
                       Ensures  => Sqrt'Result < 10.0);
     ...
  end Math_Functions;


The meaning of a test case is that there is at least one context where
``Requires`` holds such that, if the associated subprogram is executed in
that context, then ``Ensures`` holds when the subprogram returns.
Mode ``Nominal`` indicates that the input context should also satisfy the
precondition of the subprogram, and the output context should also satisfy its
postcondition. Mode ``Robustness`` indicates that the precondition and
postcondition of the subprogram should be ignored for this test case.

.. _Pragma-Thread_Local_Storage:

Pragma Thread_Local_Storage
===========================
.. index:: Task specific storage

.. index:: TLS (Thread Local Storage)

.. index:: Task_Attributes

Syntax:


::

  pragma Thread_Local_Storage ([Entity =>] LOCAL_NAME);


This pragma specifies that the specified entity, which must be
a variable declared in a library-level package, is to be marked as
"Thread Local Storage" (``TLS``). On systems supporting this (which
include Windows, Solaris, GNU/Linux, and VxWorks), this causes each
thread (and hence each Ada task) to see a distinct copy of the variable.

The variable must not have default initialization, and if there is
an explicit initialization, it must be either ``null`` for an
access variable, a static expression for a scalar variable, or a fully
static aggregate for a composite type, that is to say, an aggregate all
of whose components are static, and which does not include packed or
discriminated components.

This provides a low-level mechanism similar to that provided by
the ``Ada.Task_Attributes`` package, but much more efficient
and is also useful in writing interface code that will interact
with foreign threads.

If this pragma is used on a system where ``TLS`` is not supported,
then an error message will be generated and the program will be rejected.

Pragma Time_Slice
=================

Syntax:


.. code-block:: ada

  pragma Time_Slice (static_duration_EXPRESSION);


For implementations of GNAT on operating systems where it is possible
to supply a time slice value, this pragma may be used for this purpose.
It is ignored if it is used in a system that does not allow this control,
or if it appears in other than the main program unit.

Pragma Title
============

Syntax:


::

  pragma Title (TITLING_OPTION [, TITLING OPTION]);

  TITLING_OPTION ::=
    [Title    =>] STRING_LITERAL,
  | [Subtitle =>] STRING_LITERAL


Syntax checked but otherwise ignored by GNAT.  This is a listing control
pragma used in DEC Ada 83 implementations to provide a title and/or
subtitle for the program listing.  The program listing generated by GNAT
does not have titles or subtitles.

Unlike other pragmas, the full flexibility of named notation is allowed
for this pragma, i.e., the parameters may be given in any order if named
notation is used, and named and positional notation can be mixed
following the normal rules for procedure calls in Ada.

Pragma Type_Invariant
=====================

Syntax:


::

  pragma Type_Invariant
    ([Entity =>] type_LOCAL_NAME,
     [Check  =>] EXPRESSION);


The ``Type_Invariant`` pragma is intended to be an exact
replacement for the language-defined ``Type_Invariant``
aspect, and shares its restrictions and semantics. It differs
from the language defined ``Invariant`` pragma in that it
does not permit a string parameter, and it is
controlled by the assertion identifier ``Type_Invariant``
rather than ``Invariant``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

.. _Pragma-Type_Invariant_Class:

Pragma Type_Invariant_Class
===========================

Syntax:


::

  pragma Type_Invariant_Class
    ([Entity =>] type_LOCAL_NAME,
     [Check  =>] EXPRESSION);


The ``Type_Invariant_Class`` pragma is intended to be an exact
replacement for the language-defined ``Type_Invariant'Class``
aspect, and shares its restrictions and semantics.

Note: This pragma is called ``Type_Invariant_Class`` rather than
``Type_Invariant'Class`` because the latter would not be strictly
conforming to the allowed syntax for pragmas. The motivation
for providing pragmas equivalent to the aspects is to allow a program
to be written using the pragmas, and then compiled if necessary
using an Ada compiler that does not recognize the pragmas or
aspects, but is prepared to ignore the pragmas. The assertion
policy that controls this pragma is ``Type_Invariant'Class``,
not ``Type_Invariant_Class``.

This is an assertion kind pragma that can associate a set of its arguments
with an assertion level. See SPARK 2014 Reference Manual, section
11.4.2.

Pragma Unchecked_Union
======================
.. index:: Unions in C


Syntax:


.. code-block:: ada

  pragma Unchecked_Union (first_subtype_LOCAL_NAME);


This pragma is used to specify a representation of a record type that is
equivalent to a C union. It was introduced as a GNAT implementation defined
pragma in the GNAT Ada 95 mode. Ada 2005 includes an extended version of this
pragma, making it language defined, and GNAT fully implements this extended
version in all language modes (Ada 83, Ada 95, and Ada 2005). For full
details, consult the Ada 2012 Reference Manual, section B.3.3.

Pragma Unevaluated_Use_Of_Old
=============================
.. index:: Attribute Old

.. index:: Attribute Loop_Entry

.. index:: Unevaluated_Use_Of_Old


Syntax:


.. code-block:: ada

  pragma Unevaluated_Use_Of_Old (Error | Warn | Allow);


This pragma controls the processing of attributes Old and Loop_Entry.
If either of these attributes is used in a potentially unevaluated
expression  (e.g. the then or else parts of an if expression), then
normally this usage is considered illegal if the prefix of the attribute
is other than an entity name. The language requires this
behavior for Old, and GNAT copies the same rule for Loop_Entry.

The reason for this rule is that otherwise, we can have a situation
where we save the Old value, and this results in an exception, even
though we might not evaluate the attribute. Consider this example:


.. code-block:: ada

  package UnevalOld is
     K : Character;
     procedure U (A : String; C : Boolean)  -- ERROR
       with Post => (if C then A(1)'Old = K else True);
  end;


If procedure U is called with a string with a lower bound of 2, and
C false, then an exception would be raised trying to evaluate A(1)
on entry even though the value would not be actually used.

Although the rule guarantees against this possibility, it is sometimes
too restrictive. For example if we know that the string has a lower
bound of 1, then we will never raise an exception.
The pragma ``Unevaluated_Use_Of_Old`` can be
used to modify this behavior. If the argument is ``Error`` then an
error is given (this is the default RM behavior). If the argument is
``Warn`` then the usage is allowed as legal but with a warning
that an exception might be raised. If the argument is ``Allow``
then the usage is allowed as legal without generating a warning.

This pragma may appear as a configuration pragma, or in a declarative
part or package specification. In the latter case it applies to
uses up to the end of the corresponding statement sequence or
sequence of package declarations.

Pragma User_Aspect_Definition
=============================

Syntax:


.. code-block:: ada

  pragma User_Aspect_Definition
    (Identifier {, Identifier [(Identifier {, Identifier})]});


This configuration pragma defines a new aspect, making it available for
subsequent use in a `User_Aspect` aspect specification. The first identifier
is the name of the new aspect. Any subsequent arguments specify the names
of other aspects. A subsequent name for which no parenthesized arguments
are given shall denote either a Boolean-valued non-representation aspect
or an aspect that has been defined by another `User_Aspect_Definition`
pragma. A name for which one or more arguments are given shall be either
`Annotate` or `Local_Restrictions` (and the arguments shall be appropriate
for the named aspect).

This pragma, together with the `User_Aspect` aspect, provides a mechanism
for avoiding textual duplication if some set of aspect specifications
is needed in multiple places. This is somewhat analogous to how profiles
allow avoiding duplication of `Restrictions` pragmas.

The visibility rules for an aspect defined by a `User_Aspect_Definition`
pragma are the same as for a check name introduced by a `Check_Name`
pragma. If multiple definitions are visible for some aspect at some point,
then the definitions must agree. A predefined aspect cannot be redefined.


Pragma Unimplemented_Unit
=========================

Syntax:


.. code-block:: ada

  pragma Unimplemented_Unit;


If this pragma occurs in a unit that is processed by the compiler, GNAT
aborts with the message :samp:`xxx is not supported in this configuration`,
where ``xxx`` is the name of the current compilation unit.  This pragma
is intended to allow the compiler to handle unimplemented library units in
a clean manner.

The abort only happens if code is being generated.  Thus you can use
specs of unimplemented packages in syntax or semantic checking mode.

.. _Pragma-Universal_Aliasing:

Pragma Universal_Aliasing
=========================

Syntax:


::

  pragma Universal_Aliasing [([Entity =>] type_LOCAL_NAME)];


``type_LOCAL_NAME`` must refer to a type declaration in the current
declarative part.  The effect is to inhibit strict type-based aliasing
optimizations for the given type.  For a detailed description of the
strict type-based aliasing optimizations and the situations in which
they need to be suppressed, see the section on
``Optimization and Strict Aliasing`` in the :title:`GNAT User's Guide`.

.. _Pragma-Unmodified:

Pragma Unmodified
=================
.. index:: Warnings, unmodified

Syntax:


::

  pragma Unmodified (LOCAL_NAME {, LOCAL_NAME});


This pragma signals that the assignable entities (variables,
``out`` parameters, ``in out`` parameters) whose names are listed are
deliberately not assigned in the current source unit. This
suppresses warnings about the
entities being referenced but not assigned, and in addition a warning will be
generated if one of these entities is in fact assigned in the
same unit as the pragma (or in the corresponding body, or one
of its subunits).

This is particularly useful for clearly signaling that a particular
parameter is not modified, even though the spec suggests that it might
be.

For the variable case, warnings are never given for unreferenced variables
whose name contains one of the substrings
``DISCARD, DUMMY, IGNORE, JUNK, UNUSE, TMP, TEMP`` in any casing. Such names
are typically to be used in cases where such warnings are expected.
Thus it is never necessary to use ``pragma Unmodified`` for such
variables, though it is harmless to do so.

.. _Pragma-Unreferenced:

Pragma Unreferenced
===================
.. index:: Warnings, unreferenced

Syntax:


::

  pragma Unreferenced (LOCAL_NAME {, LOCAL_NAME});
  pragma Unreferenced (library_unit_NAME {, library_unit_NAME});


This pragma signals that the entities whose names are listed are
deliberately not referenced in the current source unit after the
occurrence of the pragma. This
suppresses warnings about the
entities being unreferenced, and in addition a warning will be
generated if one of these entities is in fact subsequently referenced in the
same unit as the pragma (or in the corresponding body, or one
of its subunits).

This is particularly useful for clearly signaling that a particular
parameter is not referenced in some particular subprogram implementation
and that this is deliberate. It can also be useful in the case of
objects declared only for their initialization or finalization side
effects.

If ``LOCAL_NAME`` identifies more than one matching homonym in the
current scope, then the entity most recently declared is the one to which
the pragma applies. Note that in the case of accept formals, the pragma
Unreferenced may appear immediately after the keyword ``do`` which
allows the indication of whether or not accept formals are referenced
or not to be given individually for each accept statement.

The left hand side of an assignment does not count as a reference for the
purpose of this pragma. Thus it is fine to assign to an entity for which
pragma Unreferenced is given. However, use of an entity as an actual for
an out parameter does count as a reference unless warnings for unread output
parameters are enabled via :switch:`-gnatw.o`.

Note that if a warning is desired for all calls to a given subprogram,
regardless of whether they occur in the same unit as the subprogram
declaration, then this pragma should not be used (calls from another
unit would not be flagged); pragma Obsolescent can be used instead
for this purpose, see :ref:`Pragma_Obsolescent`.

The second form of pragma ``Unreferenced`` is used within a context
clause. In this case the arguments must be unit names of units previously
mentioned in ``with`` clauses (similar to the usage of pragma
``Elaborate_All``). The effect is to suppress warnings about unreferenced
units and unreferenced entities within these units.

For the variable case, warnings are never given for unreferenced variables
whose name contains one of the substrings
``DISCARD, DUMMY, IGNORE, JUNK, UNUSE, TMP, TEMP`` in any casing. Such names
are typically to be used in cases where such warnings are expected.
Thus it is never necessary to use ``pragma Unreferenced`` for such
variables, though it is harmless to do so.

.. _Pragma-Unreferenced_Objects:

Pragma Unreferenced_Objects
===========================
.. index:: Warnings, unreferenced

Syntax:


::

  pragma Unreferenced_Objects (local_subtype_NAME {, local_subtype_NAME});


This pragma signals that for the types or subtypes whose names are
listed, objects which are declared with one of these types or subtypes may
not be referenced, and if no references appear, no warnings are given.

This is particularly useful for objects which are declared solely for their
initialization and finalization effect. Such variables are sometimes referred
to as RAII variables (Resource Acquisition Is Initialization). Using this
pragma on the relevant type (most typically a limited controlled type), the
compiler will automatically suppress unwanted warnings about these variables
not being referenced.

Pragma Unreserve_All_Interrupts
===============================

Syntax:


.. code-block:: ada

  pragma Unreserve_All_Interrupts;


Normally certain interrupts are reserved to the implementation.  Any attempt
to attach an interrupt causes Program_Error to be raised, as described in
RM C.3.2(22).  A typical example is the ``SIGINT`` interrupt used in
many systems for a :kbd:`Ctrl-C` interrupt.  Normally this interrupt is
reserved to the implementation, so that :kbd:`Ctrl-C` can be used to
interrupt execution.

If the pragma ``Unreserve_All_Interrupts`` appears anywhere in any unit in
a program, then all such interrupts are unreserved.  This allows the
program to handle these interrupts, but disables their standard
functions.  For example, if this pragma is used, then pressing
:kbd:`Ctrl-C` will not automatically interrupt execution.  However,
a program can then handle the ``SIGINT`` interrupt as it chooses.

For a full list of the interrupts handled in a specific implementation,
see the source code for the spec of ``Ada.Interrupts.Names`` in
file :file:`a-intnam.ads`.  This is a target dependent file that contains the
list of interrupts recognized for a given target.  The documentation in
this file also specifies what interrupts are affected by the use of
the ``Unreserve_All_Interrupts`` pragma.

For a more general facility for controlling what interrupts can be
handled, see pragma ``Interrupt_State``, which subsumes the functionality
of the ``Unreserve_All_Interrupts`` pragma.

Pragma Unsuppress
=================

Syntax:


::

  pragma Unsuppress (IDENTIFIER [, [On =>] NAME]);


This pragma undoes the effect of a previous pragma ``Suppress``.  If
there is no corresponding pragma ``Suppress`` in effect, it has no
effect.  The range of the effect is the same as for pragma
``Suppress``.  The meaning of the arguments is identical to that used
in pragma ``Suppress``.

One important application is to ensure that checks are on in cases where
code depends on the checks for its correct functioning, so that the code
will compile correctly even if the compiler switches are set to suppress
checks. For example, in a program that depends on external names of tagged
types and wants to ensure that the duplicated tag check occurs even if all
run-time checks are suppressed by a compiler switch, the following
configuration pragma will ensure this test is not suppressed:


.. code-block:: ada

  pragma Unsuppress (Duplicated_Tag_Check);


This pragma is standard in Ada 2005. It is available in all earlier versions
of Ada as an implementation-defined pragma.

Note that in addition to the checks defined in the Ada RM, GNAT recognizes a
number of implementation-defined check names. See the description of pragma
``Suppress`` for full details.

.. _Pragma-Unused:

Pragma Unused
=============
.. index:: Warnings, unused

Syntax:


::

  pragma Unused (LOCAL_NAME {, LOCAL_NAME});


This pragma signals that the assignable entities (variables,
``out`` parameters, and ``in out`` parameters) whose names are listed
deliberately do not get assigned or referenced in the current source unit
after the occurrence of the pragma in the current source unit. This
suppresses warnings about the entities that are unreferenced and/or not
assigned, and, in addition, a warning will be generated if one of these
entities gets assigned or subsequently referenced in the same unit as the
pragma (in the corresponding body or one of its subunits).

This is particularly useful for clearly signaling that a particular
parameter is not modified or referenced, even though the spec suggests
that it might be.

For the variable case, warnings are never given for unreferenced
variables whose name contains one of the substrings
``DISCARD, DUMMY, IGNORE, JUNK, UNUSE, TMP, TEMP`` in any casing. Such names
are typically to be used in cases where such warnings are expected.
Thus it is never necessary to use ``pragma Unused`` for such
variables, though it is harmless to do so.

Pragma Use_VADS_Size
====================
.. index:: Size, VADS compatibility

.. index:: Rational profile


Syntax:


.. code-block:: ada

  pragma Use_VADS_Size;


This is a configuration pragma.  In a unit to which it applies, any use
of the 'Size attribute is automatically interpreted as a use of the
'VADS_Size attribute.  Note that this may result in incorrect semantic
processing of valid Ada 95 or Ada 2005 programs.  This is intended to aid in
the handling of existing code which depends on the interpretation of Size
as implemented in the VADS compiler.  See description of the VADS_Size
attribute for further details.

Pragma Validity_Checks
======================

Syntax:


.. code-block:: ada

  pragma Validity_Checks (string_LITERAL | ALL_CHECKS | On | Off);


This pragma is used in conjunction with compiler switches to control the
built-in validity checking provided by GNAT.  The compiler switches, if set
provide an initial setting for the switches, and this pragma may be used
to modify these settings, or the settings may be provided entirely by
the use of the pragma.  This pragma can be used anywhere that a pragma
is legal, including use as a configuration pragma (including use in
the :file:`gnat.adc` file).

The form with a string literal specifies which validity options are to be
activated.  The validity checks are first set to include only the default
reference manual settings, and then a string of letters in the string
specifies the exact set of options required.  The form of this string
is exactly as described for the *-gnatVx* compiler switch (see the
GNAT User's Guide for details).  For example the following two
methods can be used to enable validity checking for mode ``in`` and
``in out`` subprogram parameters:

*

  .. code-block:: ada

    pragma Validity_Checks ("im");


*

  .. code-block:: sh

    $ gcc -c -gnatVim ...


The form ALL_CHECKS activates all standard checks (its use is equivalent
to the use of the :switch:`gnatVa` switch).

The forms with ``Off`` and ``On`` can be used to temporarily disable
validity checks as shown in the following example:


.. code-block:: ada

  pragma Validity_Checks ("c"); -- validity checks for copies
  pragma Validity_Checks (Off); -- turn off validity checks
  A := B;                       -- B will not be validity checked
  pragma Validity_Checks (On);  -- turn validity checks back on
  A := C;                       -- C will be validity checked

.. _Pragma-Volatile:

Pragma Volatile
===============

Syntax:


.. code-block:: ada

  pragma Volatile (LOCAL_NAME);


This pragma is defined by the Ada Reference Manual, and the GNAT
implementation is fully conformant with this definition.  The reason it
is mentioned in this section is that a pragma of the same name was supplied
in some Ada 83 compilers, including DEC Ada 83.  The Ada 95 / Ada 2005
implementation of pragma Volatile is upwards compatible with the
implementation in DEC Ada 83.

.. _Pragma-Volatile_Full_Access:

Pragma Volatile_Full_Access
===========================

Syntax:


.. code-block:: ada

  pragma Volatile_Full_Access (LOCAL_NAME);


This is similar in effect to pragma Volatile, except that any reference to the
object is guaranteed to be done only with instructions that read or write all
the bits of the object. Furthermore, if the object is of a composite type,
then any reference to a subcomponent of the object is guaranteed to read
and/or write all the bits of the object.

The intention is that this be suitable for use with memory-mapped I/O devices
on some machines. Note that there are two important respects in which this is
different from ``pragma Atomic``. First a reference to a ``Volatile_Full_Access``
object is not a sequential action in the RM 9.10 sense and, therefore, does
not create a synchronization point. Second, in the case of ``pragma Atomic``,
there is no guarantee that all the bits will be accessed if the reference
is not to the whole object; the compiler is allowed (and generally will)
access only part of the object in this case.

.. _Pragma-Volatile_Function:

Pragma Volatile_Function
========================

Syntax:

.. code-block:: ada

  pragma Volatile_Function [ (static_boolean_EXPRESSION) ];

For the semantics of this pragma, see the entry for aspect ``Volatile_Function``
in the SPARK 2014 Reference Manual, section 7.1.2.

Pragma Warning_As_Error
=======================

Syntax:


.. code-block:: ada

  pragma Warning_As_Error (static_string_EXPRESSION);


This configuration pragma allows the programmer to specify a set
of warnings that will be treated as errors. Any warning that
matches the pattern given by the pragma argument will be treated
as an error. This gives more precise control than -gnatwe,
which treats warnings as errors.

This pragma can apply to regular warnings (messages enabled by -gnatw)
and to style warnings (messages that start with "(style)",
enabled by -gnaty).

The pattern may contain asterisks, which match zero or more characters
in the message. For example, you can use ``pragma Warning_As_Error
("bits of*unused")`` to treat the warning message ``warning: 960 bits of
"a" unused`` as an error. All characters other than asterisk are treated
as literal characters in the match. The match is case insensitive; for
example XYZ matches xyz.

Note that the pattern matches if it occurs anywhere within the warning
message string (it is not necessary to put an asterisk at the start and
the end of the message, since this is implied).

Another possibility for the static_string_EXPRESSION which works whether
or not error tags are enabled (*-gnatw.d*) is to use a single
*-gnatw* tag string, enclosed in brackets,
as shown in the example below, to treat one category of warnings as errors.
Note that if you want to treat multiple categories of warnings as errors,
you can use multiple pragma Warning_As_Error.

The above use of patterns to match the message applies only to warning
messages generated by the front end. This pragma can also be applied to
warnings provided by the back end and mentioned in :ref:`Pragma_Warnings`.
By using a single full *-Wxxx* switch in the pragma, such warnings
can also be treated as errors.

The pragma can appear either in a global configuration pragma file
(e.g. :file:`gnat.adc`), or at the start of a file. Given a global
configuration pragma file containing:


.. code-block:: ada

  pragma Warning_As_Error ("[-gnatwj]");


which will treat all obsolescent feature warnings as errors, the
following program compiles as shown (compile options here are
*-gnatwa.d -gnatl -gnatj55*).


::

       1. pragma Warning_As_Error ("*never assigned*");
       2. function Warnerr return String is
       3.    X : Integer;
             |
          >>> error: variable "X" is never read and
              never assigned [-gnatwv] [warning-as-error]

       4.    Y : Integer;
             |
          >>> warning: variable "Y" is assigned but
              never read [-gnatwu]

       5. begin
       6.    Y := 0;
       7.    return %ABC%;
                    |
          >>> error: use of "%" is an obsolescent
              feature (RM J.2(4)), use """ instead
              [-gnatwj] [warning-as-error]

       8. end;

   8 lines: No errors, 3 warnings (2 treated as errors)


Note that this pragma does not affect the set of warnings issued in
any way, it merely changes the effect of a matching warning if one
is produced as a result of other warnings options. As shown in this
example, if the pragma results in a warning being treated as an error,
the tag is changed from "warning:" to "error:" and the string
"[warning-as-error]" is appended to the end of the message.

.. _Pragma_Warnings:

Pragma Warnings
===============

Syntax:


.. code-block:: ada

  pragma Warnings ([TOOL_NAME,] DETAILS [, REASON]);

  DETAILS ::= On | Off
  DETAILS ::= On | Off, local_NAME
  DETAILS ::= static_string_EXPRESSION
  DETAILS ::= On | Off, static_string_EXPRESSION

  TOOL_NAME ::= GNAT | GNATprove

  REASON ::= Reason => STRING_LITERAL {& STRING_LITERAL}

Note: in Ada 83 mode, a string literal may be used in place of a static string
expression (which does not exist in Ada 83).

Note if the second argument of ``DETAILS`` is a ``local_NAME`` then the
second form is always understood. If the intention is to use
the fourth form, then you can write ``NAME & ""`` to force the
interpretation as a *static_string_EXPRESSION*.

Note: if the first argument is a valid ``TOOL_NAME``, it will be interpreted
that way. The use of the ``TOOL_NAME`` argument is relevant only to users
of SPARK and GNATprove, see last part of this section for details.

Normally warnings are enabled, with the output being controlled by
the command line switch.  Warnings (``Off``) turns off generation of
warnings until a Warnings (``On``) is encountered or the end of the
current unit.  If generation of warnings is turned off using this
pragma, then some or all of the warning messages are suppressed,
regardless of the setting of the command line switches.

The ``Reason`` parameter may optionally appear as the last argument
in any of the forms of this pragma. It is intended purely for the
purposes of documenting the reason for the ``Warnings`` pragma.
The compiler will check that the argument is a static string but
otherwise ignore this argument. Other tools may provide specialized
processing for this string.

The form with a single argument (or two arguments if Reason present),
where the first argument is ``ON`` or ``OFF``
may be used as a configuration pragma.

If the ``LOCAL_NAME`` parameter is present, warnings are suppressed for
the specified entity.  This suppression is effective from the point where
it occurs till the end of the extended scope of the variable (similar to
the scope of ``Suppress``). This form cannot be used as a configuration
pragma.

In the case where the first argument is other than ``ON`` or
``OFF``,
the third form with a single static_string_EXPRESSION argument (and possible
reason) provides more precise
control over which warnings are active. The string is a list of letters
specifying which warnings are to be activated and which deactivated. The
code for these letters is the same as the string used in the command
line switch controlling warnings. For a brief summary, use the gnatmake
command with no arguments, which will generate usage information containing
the list of warnings switches supported. For
full details see the section on ``Warning Message Control`` in the
:title:`GNAT User's Guide`.
This form can also be used as a configuration pragma.

The warnings controlled by the :switch:`-gnatw` switch are generated by the
front end of the compiler. The GCC back end can provide additional warnings
and they are controlled by the :switch:`-W` switch. Such warnings can be
identified by the appearance of a string of the form ``[-W{xxx}]`` in the
message which designates the :switch:`-W{xxx}` switch that controls the message.
The form with a single *static_string_EXPRESSION* argument also works for these
warnings, but the string must be a single full :switch:`-W{xxx}` switch in this
case. The above reference lists a few examples of these additional warnings.

The specified warnings will be in effect until the end of the program
or another pragma ``Warnings`` is encountered. The effect of the pragma is
cumulative. Initially the set of warnings is the standard default set
as possibly modified by compiler switches. Then each pragma Warning
modifies this set of warnings as specified. This form of the pragma may
also be used as a configuration pragma.

The fourth form, with an ``On|Off`` parameter and a string, is used to
control individual messages, based on their text. The string argument
is a pattern that is used to match against the text of individual
warning messages (not including the initial "warning: " tag).

The pattern may contain asterisks, which match zero or more characters in
the message. For example, you can use
``pragma Warnings (Off, "bits of*unused")`` to suppress the warning
message ``warning: 960 bits of "a" unused``. No other regular
expression notations are permitted. All characters other than asterisk in
these three specific cases are treated as literal characters in the match.
The match is case insensitive, for example XYZ matches xyz.

Note that the pattern matches if it occurs anywhere within the warning
message string (it is not necessary to put an asterisk at the start and
the end of the message, since this is implied).

The above use of patterns to match the message applies only to warning
messages generated by the front end. This form of the pragma with a string
argument can also be used to control warnings provided by the back end and
mentioned above. By using a single full :switch:`-W{xxx}` switch in the pragma,
such warnings can be turned on and off.

There are two ways to use the pragma in this form. The OFF form can be used
as a configuration pragma. The effect is to suppress all warnings (if any)
that match the pattern string throughout the compilation (or match the
-W switch in the back end case).

The second usage is to suppress a warning locally, and in this case, two
pragmas must appear in sequence:


.. code-block:: ada

  pragma Warnings (Off, Pattern);
  ... code where given warning is to be suppressed
  pragma Warnings (On, Pattern);


In this usage, the pattern string must match in the Off and On
pragmas, and (if *-gnatw.w* is given) at least one matching
warning must be suppressed.

Note: if the ON form is not found, then the effect of the OFF form extends
until the end of the file (pragma Warnings is purely textual, so its effect
does not stop at the end of the enclosing scope).

Note: to write a string that will match any warning, use the string
``"***"``. It will not work to use a single asterisk or two
asterisks since this looks like an operator name. This form with three
asterisks is similar in effect to specifying ``pragma Warnings (Off)`` except (if :switch:`-gnatw.w` is given) that a matching
``pragma Warnings (On, "***")`` will be required. This can be
helpful in avoiding forgetting to turn warnings back on.

Note: the debug flag :switch:`-gnatd.i` can be
used to cause the compiler to entirely ignore all WARNINGS pragmas. This can
be useful in checking whether obsolete pragmas in existing programs are hiding
real problems.

Note: pragma Warnings does not affect the processing of style messages. See
separate entry for pragma Style_Checks for control of style messages.

Users of the formal verification tool GNATprove for the SPARK subset of Ada may
use the version of the pragma with a ``TOOL_NAME`` parameter.

If present, ``TOOL_NAME`` is the name of a tool, currently either ``GNAT`` for the
compiler or ``GNATprove`` for the formal verification tool. A given tool only
takes into account pragma Warnings that do not specify a tool name, or that
specify the matching tool name. This makes it possible to disable warnings
selectively for each tool, and as a consequence to detect useless pragma
Warnings with switch :switch:`-gnatw.w`.

Pragma Weak_External
====================

Syntax:


.. code-block:: ada

  pragma Weak_External ([Entity =>] LOCAL_NAME);


``LOCAL_NAME`` must refer to an object that is declared at the library
level. This pragma specifies that the given entity should be marked as a
weak symbol for the linker. It is equivalent to ``__attribute__((weak))``
in GNU C and causes ``LOCAL_NAME`` to be emitted as a weak symbol instead
of a regular symbol, that is to say a symbol that does not have to be
resolved by the linker if used in conjunction with a pragma Import.

When a weak symbol is not resolved by the linker, its address is set to
zero. This is useful in writing interfaces to external modules that may
or may not be linked in the final executable, for example depending on
configuration settings.

If a program references at run time an entity to which this pragma has been
applied, and the corresponding symbol was not resolved at link time, then
the execution of the program is erroneous. It is not erroneous to take the
Address of such an entity, for example to guard potential references,
as shown in the example below.

Some file formats do not support weak symbols so not all target machines
support this pragma.


.. code-block:: ada

  --  Example of the use of pragma Weak_External

  package External_Module is
    key : Integer;
    pragma Import (C, key);
    pragma Weak_External (key);
    function Present return boolean;
  end External_Module;

  with System; use System;
  package body External_Module is
    function Present return boolean is
    begin
      return key'Address /= System.Null_Address;
    end Present;
  end External_Module;


Pragma Wide_Character_Encoding
==============================

Syntax:


.. code-block:: ada

  pragma Wide_Character_Encoding (IDENTIFIER | CHARACTER_LITERAL);


This pragma specifies the wide character encoding to be used in program
source text appearing subsequently. It is a configuration pragma, but may
also be used at any point that a pragma is allowed, and it is permissible
to have more than one such pragma in a file, allowing multiple encodings
to appear within the same file.

However, note that the pragma cannot immediately precede the relevant
wide character, because then the previous encoding will still be in
effect, causing "illegal character" errors.

The argument can be an identifier or a character literal. In the identifier
case, it is one of ``HEX``, ``UPPER``, ``SHIFT_JIS``,
``EUC``, ``UTF8``, or ``BRACKETS``. In the character literal
case it is correspondingly one of the characters :kbd:`h`, :kbd:`u`,
:kbd:`s`, :kbd:`e`, :kbd:`8`, or :kbd:`b`.

Note that when the pragma is used within a file, it affects only the
encoding within that file, and does not affect withed units, specs,
or subunits.

---

### Gcc Ada Doc Gnat Rm Implementation Of Ada 2022 Features (`gcc/ada/doc/gnat_rm/implementation_of_ada_2022_features.rst`)

.. _Implementation_of_Ada_2022_Features:

***********************************
Implementation of Ada 2022 Features
***********************************

.. index:: Ada 2022 implementation status

.. index:: -gnat22 option (gcc)

.. index:: pragma Ada_2022

.. index:: configuration pragma Ada_2022

.. index:: Ada_2022 configuration pragma

This chapter contains a complete list of Ada 2022 features that have been
implemented. Generally, these features are only available if the *-gnat22* (Ada 2022 features enabled) option is set, or if the configuration pragma ``Ada_2022`` is used.

However, new pragmas, attributes, and restrictions are unconditionally available, since the Ada standard allows the addition of new pragmas, attributes, and restrictions (there are exceptions, which are
documented in the individual descriptions), and also certain packages
were made available in earlier versions of Ada.

An ISO date (YYYY-MM-DD) appears in parentheses on the description line.
This date shows the implementation date of the feature. Any wavefront
subsequent to this date will contain the indicated feature, as will any
subsequent releases. A date of 0000-00-00 means that GNAT has always
implemented the feature, or implemented it as soon as it appeared as a
binding interpretation.

Each feature corresponds to an Ada Issue ('AI') approved by the Ada
standardization group (ISO/IEC JTC1/SC22/WG9) for inclusion in Ada 2022.

The section "RM references" lists all modified paragraphs in the Ada 2012 reference manual. The details of each modification as well as a complete description of the AIs may be found in
http://www.ada-auth.org/AI12-SUMMARY.HTML.

.. index:: AI12-0001 (Ada 2022 feature)

* *AI12-0001 Independence and Representation clauses for atomic objects (2019-11-27)*

  The compiler accepts packing clauses in all cases, even if they have effectively no influence on the layout. Types, where packing is essentially infeasible are, for instance atomic, aliased and by-reference types.

  RM references: 13.02 (6.1/2) 13.02 (7) 13.02 (8) 13.02 (9/3) C.06 (8.1/3)
  C.06 (10) C.06 (11) C.06 (21) C.06 (24)

.. index:: AI12-0003 (Ada 2022 feature)

* *AI12-0003 Specifying the standard storage pool (2020-06-25)*

  Allows the standard storage pool being specified with a ``Default_Storage_Pool`` pragma or aspect.

  RM references: 8.02 (11) 13.11.03 (1/3) 13.11.03 (3.1/3) 13.11.03 (4/3)
  13.11.03 (4.1/3) 13.11.03 (5/3) 13.11.03 (6.2/3) 13.11.03
  (6.3/3)

.. index:: AI12-0004 (Ada 2022 feature)

* *AI12-0004 Normalization and allowed characters for identifiers (2020-06-11)*

  This AI clarifies that Ada identifiers containing characters which are not
  allowed in Normalization Form KC are illegal.

  RM references: 2.01 (4.1/3) 2.03 (4/3) A.03.02 (4/3) A.03.02 (32.5/3)
  A.03.05 (18/3) A.03.05 (51/3)

.. index:: AI12-0020 (Ada 2022 feature)

* *AI12-0020 'Image for all types (2020-03-30)*

  Put_Image prints out a human-readable representation of an object. The
  functionality in Ada2022 RM is fully implemented except the support for
  types in the ``Remote_Types`` packages.

  RM references: 4.10 (0) 3.05 (27.1/2) 3.05 (27.2/2) 3.05 (27.3/2) 3.05
  (27.4/2) 3.05 (27.5/2) 3.05 (27.6/2) 3.05 (27.7/2) 3.05 (28) 3.05
  (29) 3.05 (30/3) 3.05 (31) 3.05 (32) 3.05 (33/3) 3.05 (37.1/2)
  3.05 (38) 3.05 (39) 3.05 (43/3) 3.05 (55/3) 3.05 (55.1/5) 3.05
  (55.2/4) 3.05 (55.3/4) 3.05 (55.4/4) 3.05 (59) H.04 (23) H.04 (23.8/2)

.. index:: AI12-0022 (Ada 2022 feature)

* *AI12-0022 Raise_Expressions (2013-01-27)*

  This feature allows you to write "raise NAME [with STRING]" in an
  expression to rise given exception. It is particularly useful in the case of
  assertions such as preconditions allowing to specify which exception a
  precondition raises if it fails.

  RM references: 4.04 (3/3) 11.02 (6) 11.03 (2/2) 11.03 (3) 11.03 (3.1/2)
  11.03 (4/2) 11.04.01 (10.1/3)

.. index:: AI12-0027 (Ada 2022 feature)

* *AI12-0027 Access values should never designate unaliased components (2020-06-15)*

  AI12-0027 adds a requirement for a value conversion that converts from an array of unaliased components to an array of aliased components to make a copy. It defines such conversions to have a local accessibility, effectively preventing the possibility of unsafe accesses to unaliased components.

  RM references: 4.06 (24.17/3) 4.06 (24.21/2) 4.06 (58) 6.02 (10/3) 3.10.02 (10/3)

.. index:: AI12-0028 (Ada 2022 feature)

* *AI12-0028 Import of variadic C functions (2020-03-03)*

  Ada programs can now properly call variadic C functions by means of the
  conventions C_Variadic_<n>, for small integer values <n>.

  RM references: B.03 (1/3) B.03 (60.15/3) B.03 (75)

.. index:: AI12-0030 (Ada 2022 feature)

* *AI12-0030 Formal derived types and stream attribute availability (2020-08-21)*

  Corner cases involving streaming operations for formal derived limited types
  that are now defined to raise Program_Error. Before, behavior in these cases
  was undefined. Stream attribute availability is more precisely computed in cases where a derived type declaration occurs ahead of a streaming attribute specification for the parent type.

  RM references: 12.05.01 (21/3) 13.13.02 (49/2)

.. index:: AI12-0031 (Ada 2022 feature)

* *AI12-0031 All_Calls_Remote and indirect calls (0000-00-00)*

  Remote indirect calls (i.e., calls through a remote access-to-subprogram type)
  behave the same as remote direct calls.

  RM references: E.02.03 (19/3)

.. index:: AI12-0032 (Ada 2022 feature)

* *AI12-0032 Questions on 'Old (2020-04-24)*

  AI12-0032 resolves several issues related to the 'Old attribute. The GNAT
  compiler already implemented what the AI requires in most of those cases, but two having to do with static and dynamic checking of the accessibility level of the constant object implicitly declared for an 'Old attribute reference were not yet implemented. Accessibility checking for these constants is now implemented as defined in the AI.

  RM references: 4.01.03 (9/3) 6.01.01 (22/3) 6.01.01 (26/3) 6.01.01 (35/3)

.. index:: AI12-0033 (Ada 2022 feature)

* *AI12-0033 Sets of CPUs when defining dispatching domains (0000-00-00)*

  The set of CPUs associated with a dispatching domain is no longer required
  to be a contiguous range of CPU values.

  RM references: D.16.01 (7/3) D.16.01 (9/3) D.16.01 (20/3) D.16.01 (23/3)
  D.16.01 (24/3) D.16.01 (26/3)

.. index:: AI12-0035 (Ada 2022 feature)

* *AI12-0035 Accessibility checks for indefinite elements of containers (0000-00-00)*

  If the element type for an instance of one of the indefinite container generics has an access discriminant, then accessibility checks (at run-time) prevent inserting a value into a container object if the value's discriminant designates an object that is too short-lived (that is, if the designated object has an accessibility level that is deeper than that of the instance). Without this check, dangling references would be possible. GNAT handled this correctly already before this AI was issued.

  RM references: A.18 (5/3) A.18.11 (8/2) A.18.12 (7/2) A.18.13 (8/2)
  A.18.14 (8/2) A.18.15 (4/2) A.18.16 (4/2) A.18.17 (7/3) A.18.18
  (39/3) A.18.18 (47/3)

.. index:: AI12-0036 (Ada 2022 feature)

* *AI12-0036 The actual for an untagged formal derived type cannot be tagged (2019-10-21)*

  AI12-0036 is a binding interpretation that adds the following legality rule:
  The actual type for a formal derived type shall be tagged if and only if the
  formal derived type is a private extension. The check is implemented for all Ada dialects, not just Ada 2022.

  RM references: 12.05.01 (5.1/3)

.. index:: AI12-0037 (Ada 2022 feature)

* *AI12-0037 New types in Ada.Locales can't be converted to/from strings (2016-09-10)*

  The type definitions for Language_Code and Country_Code are now using dynamic
  predicates.

  RM references: A.19 (4/3)

.. index:: AI12-0039 (Ada 2022 feature)

* *AI12-0039 Ambiguity in syntax for membership expression removed (0000-00-00)*

  An ambiguity in the syntax for membership expressions was resolved. For example, "A in B and C" can be parsed in only one way because of this AI.

  RM references: 4.04 (3/3) 4.04 (3.2/3) 4.05.02 (3.1/3) 4.05.02 (4) 4.05.02
  (4.1/3) 4.05.02 (27/3) 4.05.02 (27.1/3) 4.05.02 (28.1/3) 4.05.02
  (28.2/3) 4.05.02 (29/3) 4.05.02 (30/3) 4.05.02 (30.1/3) 4.05.02
  (30.2/3) 4.05.02 (30.3/3) 4.09 (11/3) 4.09 (32.6/3) 8.06 (27.1/3)
  3.02.04 (17/3)

.. index:: AI12-0040 (Ada 2022 feature)

* *AI12-0040 Resolving the selecting_expression of a case_expression (0000-00-00)*

  The definition of "complete context" is corrected so that selectors of case expressions
  and of case statements are treated uniformly.

  RM references: 8.06 (9)

.. index:: AI12-0041 (Ada 2022 feature)

* *AI12-0041 Type_Invariant'Class for interface types (2016-12-12)*

  Subprogram calls within class-wide type invariant expressions get resolved
  as primitive operations instead of being dynamically dispatched.

  RM references: 7.03.02 (1/3) 7.03.02 (3/3)

.. index:: AI12-0042 (Ada 2022 feature)

* *AI12-0042 Type invariant checking rules (2020-06-05)*

  AI12-0042 adds rules for type invariants.
  Specifically, when inheriting a private dispatching operation when the ancestor operation is visible at the point of the type extension, the operation must be abstract or else overridden. In addition, for a class-wide view conversion from an object of a specific type T to which a type invariant applies, an invariant check is performed when the conversion is within the immediate scope of T.

  RM references: 7.03.02 (6/3) 7.03.02 (17/3) 7.03.02 (18/3) 7.03.02 (19/3)
  7.03.02 (20/3)

.. index:: AI12-0043 (Ada 2022 feature)

* *AI12-0043 Details of the storage pool used when Storage_Size is specified (0000-00-00)*

  Clarify that a Storage_Size specification for an access type specifies both an upper bound and a lower bound (not just a lower bound) of the amount of storage allowed for allocated objects.

  RM references: 13.11 (18)

.. index:: AI12-0044 (Ada 2022 feature)

* *AI12-0044 Calling visible functions from type invariant expressions (2020-05-11)*

  AI05-0289-1 extends invariant checking to `in` parameters. However, this makes
  it impossible to call a public function of the type from an invariant
  expression, as that public function will attempt to check the invariant,
  resulting in an infinite recursion.

  This AI specifies, that type-invariant checking is performed on parameters
  of mode `in` upon return from procedure calls, but not of `in`-mode
  parameters in functions.

  RM references: 7.03.02 (19/3)

.. index:: AI12-0045 (Ada 2022 feature)

* *AI12-0045 Pre- and Postconditions are allowed on generic subprograms (2015-03-17)*

  The SPARK toolset now supports contracts on generic subprograms, packages and
  their respective bodies.

  RM references: 6.01.01 (1/3)

.. index:: AI12-0046 (Ada 2022 feature)

* *AI12-0046 Enforcing legality for anonymous access components in record aggregates (0000-00-00)*

  For a record aggregate of the form (X | Y => ....), any relevant legality rules are checked for both for X and Y.

  For example,

  .. code::

      X : aliased constant String := ... ;
      type R is record
        F1 : access constant String;
        F2 : access String;
      end record;
      Obj : R := (F1 | F2 => X'Access); -- ok for F1, but illegal for F2

  RM references: 4.03.01 (16/3)

.. index:: AI12-0047 (Ada 2022 feature)

* *AI12-0047 Generalized iterators and discriminant-dependent components (0000-00-00)*

  Iterating over the elements of an array is subject to the same legality checks as renaming the array. For example, if an assignment to an enclosing discriminated object could cause an array object to cease to exist then we don't allow renaming the array. So it is similarly not allowed to iterate over the elements of such an array.

  RM references: 5.05.02 (6/3)

.. index:: AI12-0048 (Ada 2022 feature)

* *AI12-0048 Default behavior of tasks on a multiprocessor with a specified dispatching policy (0000-00-00)*

  Clarify that if the user does not impose requirements about what CPUs a given task might execute on, then the implementation does not get to impose such requirements. This avoids potential problems with priority inversion.

  RM references: D.16.01 (30/3)

.. index:: AI12-0049 (Ada 2022 feature)

* *AI12-0049 Invariants need to be checked on the initialization of deferred constants (0000-00-00)*

  Invariant checking for deferred constants (and subcomponents thereof) is performed. Corrects a clear oversight in the previous RM wording.

  RM references: 7.03.02 (10/3)

.. index:: AI12-0050 (Ada 2022 feature)

* *AI12-0050 Conformance of quantified expressions (2016-07-22)*

  Compiler rejects a subprogram body when an expression for a boolean formal
  parameter includes a quantified expression, and the subprogram declaration
  contains a textual copy of the same.

  RM references: 6.03.01 (20) 6.03.01 (21)

.. index:: AI12-0051 (Ada 2022 feature)

* *AI12-0051 The Priority aspect can be specified when Attach_Handler is specified (0000-00-00)*

  Previous RM wording had two contradictory rules for determining (in some cases) the priority of a protected subprogram that is attached to an interrupt. The AI clarifies which one of the rules takes precedence.

  RM references: D.03 (10/3)

.. index:: AI12-0052 (Ada 2022 feature)

* *AI12-0052 Implicit objects are considered overlapping (0000-00-00)*

  Clarify that the rules about unsynchronized concurrent access apply as one would expect in the case of predefined routines that access Text_IO's default input and default output files. There was no compiler changes needed to implement this.

  RM references: A (3/2) A.10.03 (21)

.. index:: AI12-0054-2 (Ada 2022 feature)

* *AI12-0054-2 Aspect Predicate_Failure (0000-00-00)*

  New aspect Predicate_Failure is defined.  A solution for the problem that a predicate like

  ..  code::

    subtype Open_File is File with Dynamic_Predicate =\> Is_Open (Open_File) or else (raise File_Not_Open);

  does the wrong thing in the case of a membership test.

  RM references: 3.02.04 (14/3) 3.02.04 (31/3) 3.02.04 (35/3)

.. index:: AI12-0055 (Ada 2022 feature)

* *AI12-0055 All properties of a usage profile are defined by pragmas (2020-06-09)*

  AI12-0055 allows the use of the No_Dynamic_CPU_Assignment restriction in pragmas Restrictions and Restrictions_Warnings.

  RM references: D.07 (10/3) D.13 (6/3) D.13 (8/3) D.13 (10/3)

.. index:: AI12-0059 (Ada 2022 feature)

* *AI12-0059 Object_Size attribute (2019-12-02)*

  AI12-0059 brings GNAT-defined attribute Object_Size to Ada standard
  and clarifies its semantics. Given that the attribute already existed in
  GNAT compiler, the feature is supported for all language versions.

  RM references: 4.09.01 (2/3) 13.01 (14) 13.01 (23) 13.03 (9/3) 13.03
  (50/2) 13.03 (51) 13.03 (52) 13.03 (58)

.. index:: AI12-0061 (Ada 2022 feature)

* *AI12-0061 Iterated component associations in array aggregates (2016-09-01)*

  Ada issue AI12-061 introduces a new construct in array aggregates allowing
  component associations to be parameterized by a loop variable, for example:

  .. code::

    array (1 .. 10) of Integer :=
      (for I in 1 .. 10 => I ** 2);
    type Matrix is
    array
      (Positive range <>, Positive range <>) of Float;
    G : constant Matrix
    :=
      (for I in 1 .. 4 =>
          (for J in 1 .. 4 =>
              (if I=J then
    1.0 else 0.0))); -- Identity matrix

  The expression in such an association can also be a function that returns a
  limited type, and the range can be specified by the 'others' choice.

  RM references: 4.03.03 (5/2) 4.03.03 (6) 4.03.03 (17/3) 4.03.03 (20)
  4.03.03 (23.1/4) 4.03.03 (32/3) 4.03.03 (43) 3.01 (6/3) 3.03 (6)
  3.03 (18.1/3) 3.03.01 (23/3) 5.05 (6) 8.01 (2.1/4)

.. index:: AI12-0062 (Ada 2022 feature)

* *AI12-0062 Raise exception with failing string function (0000-00-00)*

  Clarify that if raising exception E1 is accompanied with a String-valued
  expression whose evaluation raises exception E2, then E2 is what gets propagated.

  RM references: 11.03 (4/2)

.. index:: AI12-0065 (Ada 2022 feature)

* *AI12-0065 Descendants of incomplete views (0000-00-00)*

  This AI is a clarification of potentially confusing wording.  GNAT correctly handles the example given in AARM 7.3.1(5.b-5.d), which illustrates the topic of this AI.

  RM references: 7.03.01 (5.2/3)

.. index:: AI12-0067 (Ada 2022 feature)

* *AI12-0067 Accessibility level of explicitly aliased parameters of procedures and entries (0000-00-00)*

  The AI fixes a case where the intent was fairly obvious but the RM wording failed to mention a case (with the result that the accessibility level of an explicitly aliased parameter of a procedure or entry was undefined even though the intent was clear).

  RM references: 3.10.02 (7/3)

.. index:: AI12-0068 (Ada 2022 feature)

* *AI12-0068 Predicates and the current instance of a subtype (2020-05-06)*

  AI12-0068 is a binding interpretation that defines the current instance name in a type or subtype aspect to be a value rather than an object. This affects
  attributes whose prefix is a current instance in predicates, type invariants, and ``Default_Initial_Condition`` aspects. In particular, in the case of the ``Constrained`` attribute the value will always be True, and formerly legal attributes that require an object as their prefix (such as ``Size``, ``Access``, ``Address``, etc.) are illegal when applied to a current instance in type and subtype aspects.

  RM references: 8.06 (17/3)

.. index:: AI12-0069 (Ada 2022 feature)

* *AI12-0069 Inconsistency in Tree container definition (0000-00-00)*

  The description of how iteration over a Tree container's elements was contradictory in some cases regarding whether a cursor designating the Root node is included in the iteration. This contradiction was resolved. In the "!ACATS Test" section of the AI, it says that if an implementation were to get this wrong then almost any attempt to iterate over any tree would fail at runtime.

  RM references: A.18.10 (153/3) A.18.10 (155/3) A.18.10 (157/3) A.18.10 (159/3)

.. index:: AI12-0070 (Ada 2022 feature)

* *AI12-0070 9.3(2) does not work for anonymous access types (0000-00-00)*

  The RM contained some old wording about the master of an allocated object that only made sense for named access types. The AI clarifies the wording to clearly state the scope of validity and ensures that the paragraph does not contradict 3.10.2's rules for anonymous access  types.

  RM references: 3.10.02 (13.1/3) 9.03 (2)

.. index:: AI12-0071 (Ada 2022 feature)

* *AI12-0071 Order of evaluation when multiple predicates apply (2015-08-10)*

  AI12-0071 specifies the semantics of multiple/inherited predicates on a
  single subtype.

  RM references: 3.02.04 (4/3) 3.02.04 (6/3) 3.02.04 (30/3) 3.02.04 (31/3)
  3.02.04 (32/3) 3.02.04 (33/3) 3.02.04 (35/3) 3.05.05 (7.1/3)
  3.05.05 (7.2/3) 3.05.05 (7.3/3) 3.08.01 (10.1/3) 3.08.01 (15/3)
  4.05.02 (29/3) 4.05.02 (30/3) 4.06 (51/3) 4.09.01 (10/3) 5.04
  (7/3) 5.05 (9/3) 13.09.02 (3/3) 13.09.02 (12)

.. index:: AI12-0072 (Ada 2022 feature)

* *AI12-0072 Missing rules for Discard_Names aspect (0000-00-00)*

  Clarify that Discard_Names is an aspect, not just a pragma.

  RM references: C.05 (1) C.05 (5) C.05 (7/2) C.05 (8)

.. index:: AI12-0073 (Ada 2022 feature)

* *AI12-0073 Synchronous Barriers are not allowed with Ravenscar (2020-02-24)*

  Ada 2022 adds (as a binding interpretation) a ``No_Dependence =>
  Ada.Synchronous_Barriers`` restriction to the Ravenscar profile.

  RM references: D.13 (6/3)

.. index:: AI12-0074 (Ada 2022 feature)

* *AI12-0074 View conversions and out parameters passed by copy (2020-03-26)*

  This Ada 2022 AI makes illegal some cases of out parameters whose type has a
  ``Default_Value`` aspect.

  RM references: 4.06 (56) 6.04.01 (6.25/3) 6.04.01 (13.1/3)

.. index:: AI12-0075 (Ada 2022 feature)

* *AI12-0075 Static expression functions (2020-04-13)*

  Ada 2022 defines a new aspect ``Static`` that can be specified on expression
  functions. Such an expression function can be called in contexts requiring static expressions when the actual parameters are all static, allowing for greater abstraction in complex static expressions.

  RM references: 4.09 (21) 6.08 (3/4) 6.08 (5/4) 6.08 (6/4) 7.03.02 (8.2/5)
  7.03.02 (15/4) 7.03.02 (16/4) 7.03.02 (17/4) 7.03.02 (19/4)
  7.03.02 (20/5)

.. index:: AI12-0076 (Ada 2022 feature)

* *AI12-0076 Variable state in pure packages (0000-00-00)*

  Defines an obscure constant-modifying construct to be erroneous. The issue is that the current instance of a type is a variable object, so the following is legal:

  .. code::

     type T;
     type T_Ref (Access_To_Variable : access T) is null record;
     type T is limited record
        Self : T_Ref (T'Access);
        Int : Integer;
     end record;

     Obj : constant T := (Self => <>, Int => 123);
   begin
     Obj.Self.Access_To_Variable.Int := 456; -- modifying a component of a constant

  In cases where constancy is really needed (e.g., for an object declared in a Pure context), such a case needs to be erroneous.

  RM references: 10.02.01 (17/3) E.02.02 (17/2)

.. index:: AI12-0077 (Ada 2022 feature)

* *AI12-0077 Has_Same_Storage on objects of size zero (2020-03-30)*

  This binding interpretation requires the Has_Same_Storage attribute
  to return always `false` for objects that have a size of zero.

  RM references: 13.03 (73.4/3)

.. index:: AI12-0078 (Ada 2022 feature)

* *AI12-0078 Definition of node for tree container is confusing (0000-00-00)*

  Clarifies the expected behavior in processing tree containers.

  RM references: A.18.10 (2/3) A.18.10 (3/3)

.. index:: AI12-0081 (Ada 2022 feature)

* *AI12-0081 Real-time aspects need to specify when they are evaluated (0000-00-00)*

  Clarify the point at which Priority and Interrupt_Priority aspect expressions are evaluated.

  RM references: D.01 (17/3) D.16 (9/3)

.. index:: AI12-0084 (Ada 2022 feature)

* *AI12-0084 Box expressions in array aggregates (2014-12-15)*

  This AI addresses an issue where compiler used to fail to initialize
  components of a multidimensional aggregates with box initialization when
  scalar components have a specified default value. The AI clarifies that
  in an array aggregate with box (i.e., ``<>``) component values, the
  ``Default_Component_Value`` of the array type (if any) should not be ignored.

  RM references: 4.03.03 (23.1/2)

.. index:: AI12-0085 (Ada 2022 feature)

* *AI12-0085 Missing aspect cases for Remote_Types (0000-00-00)*

  A distributed systems annex (Annex E) clarification. Aspect specifications
  that are forbidden using attribute definition clause syntax are also forbidden
  using aspect_specification syntax.

  RM references: E.02.02 (17/2)

.. index:: AI12-0086 (Ada 2022 feature)

* *AI12-0086 Aggregates and variant parts (2019-08-14)*

  In Ada 2012, a discriminant value that governs an active variant part in an
  aggregate had to be static. AI12-0086 relaxes this restriction: If the subtype of the discriminant value is a static subtype all of whose values select the same variant, then the expression for the discriminant is allowed to be nonstatic.

  RM references: 4.03.01 (17/3) 4.03.01 (19/3)

.. index:: AI12-0088 (Ada 2022 feature)

* *AI12-0088 UTF_Encoding.Conversions and overlong characters on input (0000-00-00)*

  Clarify that overlong characters are acceptable on input even if we never generate them as output.

  RM references: A.04.11 (54/3) A.04.11 (55/3)

.. index:: AI12-0089 (Ada 2022 feature)

* *AI12-0089 Accessibility rules need to take into account that a generic function is not a (0000-00-00)*

  Fix cases in RM wording where the accessibility rules for a function failed to take into account the fact that a generic function is not a function. For example, a generic function with an explicitly aliased parameter should be able to return references to that parameter in the same ways that a (non-generic) function can. The previous wording did not allow that.

  RM references: 3.10.02 (7/3) 3.10.02 (19.2/3) 3.10.02 (19.3/3) 6.05 (4/3)

.. index:: AI12-0093 (Ada 2022 feature)

* *AI12-0093 Iterator with indefinite cursor (0000-00-00)*

  A clarification that confirms what GNAT is already doing.

  RM references: 5.05.02 (8/3) 5.05.02 (10/3)

.. index:: AI12-0094 (Ada 2022 feature)

* *AI12-0094 An access_definition should be a declarative region (0000-00-00)*

  Fixes wording omission in the RM, confirming that the behaviour of GNAT is
  correct.

  RM references: 8.03 (2) 8.03 (26/3)

.. index:: AI12-0095 (Ada 2022 feature)

* *AI12-0095 Generic formal types and constrained partial views (0000-00-00)*

  Deciding whether an actual parameter corresponding to an explicitly aliased formal parameter is legal depends on (among other things) whether the parameter type has a constrained partial view. The AI clarifies how this compile-time checking works in the case of a generic formal type (assume the best in the spec and recheck each instance, assume the worst in a generic body).

  RM references: 3.10.02 (27.2/3) 4.06 (24.16/2) 6.04.01 (6.2/3) 12.05.01 (15)

.. index:: AI12-0096 (Ada 2022 feature)

* *AI12-0096 The exception raised when a subtype conversion fails a predicate check (0000-00-00)*

  Clarify that the Predicate_Failure aspect works the same in a subtype conversion as in any other context.

  RM references: 4.06 (57/3)

.. index:: AI12-0097 (Ada 2022 feature)

* *AI12-0097 Tag of the return object of a simple return expression (0000-00-00)*

  Clarify wording about the tag of a function result in the case of a simple (i.e. not extended) return statement in a function with a class-wide result type.

  RM references: 6.05 (8/3)

.. index:: AI12-0098 (Ada 2022 feature)

* *AI12-0098 Problematic examples for ATC (0000-00-00)*

  The AI clarifies reference manual examples, there is no compiler impact.

  RM references: 9.07.04 (13)

.. index:: AI12-0099 (Ada 2022 feature)

* *AI12-0099 Wording problems with predicates (2020-05-04)*

  When extending a task or protected type from an ancestor interface subtype with  a predicate, a link error can occur due to the compiler failing to generate the predicate-checking function. This AI clarifies the requirement for such predicate inheritance for concurrent types.

  RM references: 3.02.04 (4/4) 3.02.04 (12/3) 3.02.04 (20/3)

.. index:: AI12-0100 (Ada 2022 feature)

* *AI12-0100 A qualified expression makes a predicate check (2020-02-17)*

  The compiler now enforces predicate checks on qualified expressions when the
  qualifying subtype imposes a predicate.

  RM references: 4.07 (4)

.. index:: AI12-0101 (Ada 2022 feature)

* *AI12-0101 Incompatibility of hidden untagged record equality (2019-10-31)*

  AI12-0101 is a binding interpretation that removes a legality rule that
  prohibited the declaration of a primitive equality function for a private type in the private part of its enclosing package (either before or after the completion of the type) when the type is completed as an untagged record type. Such declarations are now accepted in Ada 2012 and later Ada versions.

  As a consequence of this work, some cases where the implementation of AI05-0123 was incomplete were corrected.
  More specifically, if a user-defined equality operator is present for an untagged record type in an Ada 2012 program, that user-defined equality operator will be (correctly) executed in some difficult-to-characterize cases where the predefined component-by-component comparison was previously being (incorrectly) executed. This can arise, for example, in the case of the predefined equality operation for an enclosing composite type that has a component of the user-defined primitive equality op's operand type.
  This correction means that the impact of this change is not limited solely to code that was previously rejected at compile time.

  RM references: 4.05.02 (9.8/3)

.. index:: AI12-0102 (Ada 2022 feature)

* *AI12-0102 Stream_IO.File_Type has Preelaborable_Initialization (0000-00-00)*

  Modifies the declaration of one type in a predefined package. GNAT's version of ``Ada.Streams.Stream_IO`` already had this modification (the ``Preelaborable__Initialization`` pragma).

  RM references: A.12.01 (5)

.. index:: AI12-0103 (Ada 2022 feature)

* *AI12-0103 Expression functions that are completions in package specifications (0000-00-00)*

  Clarifies that expression functions that are completions do not cause "general"  freeze-everybody-in-sight freezing like a subprogram body.

  RM references: 13.14 (3/3) 13.14 (5/3)

.. index:: AI12-0104 (Ada 2022 feature)

* *AI12-0104 Overriding an aspect is undefined (0000-00-00)*

  A clarification of the wording in RM, no compiler impact.

  RM references: 4.01.06 (4/3) 4.01.06 (17/3)

.. index:: AI12-0105 (Ada 2022 feature)

* *AI12-0105 Pre and Post are not allowed on any subprogram completion (0000-00-00)*

  Language-defined aspects (e.g., ``Post``) cannot be specified as part of the completion of  a subprogram declaration. Fix a hole in the RM wording to clarify that this general rule applies even in the special cases where the completion is either an expression function or a null procedure.

  RM references: 13.01.01 (18/3)

.. index:: AI12-0106 (Ada 2022 feature)

* *AI12-0106 Write'Class aspect (0000-00-00)*

  Clarify that the syntax used in an ACATS test BDD2005 for specifying a class-wide streaming aspect is correct.

  RM references: 13.01.01 (28/3) 13.13.02 (38/3)

.. index:: AI12-0107 (Ada 2022 feature)

* *AI12-0107 A prefixed view of a By_Protected_Procedure interface has convention protected (2020-06-05)*

  A prefixed view of a subprogram with aspect Synchronization set to
  By_Protected_Procedure has convention protected.

  RM references: 6.03.01 (10.1/2) 6.03.01 (12) 6.03.01 (13)

.. index:: AI12-0109 (Ada 2022 feature)

* *AI12-0109 Representation of untagged derived types (2019-11-12)*

  Ada disallows a nonconforming specification of a type-related representation
  aspect of an untagged by-reference type. The motivation for this rule is to ensure that a parent type and a later type derived from the parent agree with respect to such aspects. AI12-0109 disallows a construct that otherwise could be used to get around this rule: an aspect specification for the parent type that occurs after the declaration of the derived type.

  RM references: 13.01 (10/3)

.. index:: AI12-0110 (Ada 2022 feature)

* *AI12-0110 Tampering checks are performed first (2020-04-14)*

  AI12-0110 requires tampering checks in the containers library to be
  performed first, before any other checks.

  RM references: A.18.02 (97.1/3) A.18.03 (69.1/3) A.18.04 (15.1/3) A.18.07
  (14.1/3) A.18.10 (90/3) A.18.18 (35/3)

.. index:: AI12-0112 (Ada 2022 feature)

* *AI12-0112 Contracts for container operations (0000-00-00)*

  A representation change replacing english descriptions of contracts for
  operations on predefined container types with pre/post-conditions. No compiler
  impact.

  RM references: A.18.02 (99/3) 11.04.02 (23.1/3) 11.05 (23) 11.05 (26) A
  (4) A.18 (10)

.. index:: AI12-0114 (Ada 2022 feature)

* *AI12-0114 Overlapping objects designated by access parameters are not thread-safe (0000-00-00)*

  There are rules saying that concurrent calls to predefined subprograms don't interfere with each other unless actual parameters overlap. The AI clarifies that such an interference is also possible if overlapping objects are reachable via access dereferencing from actual parameters of the two calls.

  RM references: A (3/2)

.. index:: AI12-0116 (Ada 2022 feature)

* *AI12-0116 Private types and predicates (0000-00-00)*

  Clarify that the same aspect cannot be specified twice for the same type. ``Dynamic_Predicate``, for example, can be specified on either the partial view of a type or on the completion in the private part, but not on both.

  RM references: 13.01 (9/3) 13.01 (9.1/3)

.. index:: AI12-0117 (Ada 2022 feature)

* *AI12-0117 Restriction No_Tasks_Unassigned_To_CPU (2020-06-12)*

  This AI adds a restriction No_Tasks_Unassigned_To_CPU to provide safe
  use of Ravenscar.

  The CPU aspect is specified for the environment task. No CPU aspect is
  specified to be statically equal to ``Not_A_Specific_CPU``. If aspect CPU
  is specified (dynamically) to the value ``Not_A_Specific_CPU``, then
  Program_Error is raised. If Set_CPU or ``Delay_Until_And_Set_CPU`` are called
  with the CPU parameter equal to ``Not_A_Specific_CPU``, then ``Program_Error`` is raised.

  RM references: D.07 (10.8/3)

.. index:: AI12-0120 (Ada 2022 feature)

* *AI12-0120 Legality and exceptions of generalized loop iteration (0000-00-00)*

  Clarify that the expansion-based definition of generalized loop iteration
  includes legality checking. If the expansion would be illegal (for example,
  because of passing a constant actual parameter in a call when the mode of
  the corresponding formal parameter is in-out), then the loop is illegal too.

  RM references: 5.05.02 (6.1/4) 5.05.02 (10/3) 5.05.02 (13/3)

.. index:: AI12-0121 (Ada 2022 feature)

* *AI12-0121 Stream-oriented aspects (0000-00-00)*

  Clarify that streaming-oriented aspects (e.g., Read) can be specified using
  aspect_specification syntax, not just via an attribute definition clause.

  RM references: 13.13.02 (38/3)

.. index:: AI12-0124 (Ada 2022 feature)

* *AI12-0124 Add Object'Image (2017-03-24)*

  The corrigendum of Ada 2012 extends attribute ``'Image following`` the syntax for the GNAT ``'Img`` attribute. This AI fixes a gap in the earlier implementation, which did not recognize function calls and attributes that are functions as valid object prefixes.

  RM references: 3.05 (55/3)

.. index:: AI12-0125-3 (Ada 2022 feature)

* *AI12-0125-3 Add @ as an abbreviation for the LHS of an assignment (2016-11-11)*

  This AI introduces the use of the character '@' as an abbreviation for the left-hand side of an assignment statement, usable anywhere within the expression on the right-hand side. To use this feature the compilation flag -gnat2022 must be specified.

  RM references: 5.02.01 (0) 2.02 (9) 3.03 (21.1/3) 4.01 (2/3) 8.06 (9/4)

.. index:: AI12-0127 (Ada 2022 feature)

* *AI12-0127 Partial aggregate notation (2016-10-12)*

  This AI describes a new constructor for aggregates, in terms of an existing record or array object, and a series of component-wise modifications of its value, given by named associations for the modified components. To use this feature the compilation flag ``-gnat2022`` must be specified.

  RM references: 4.03 (2) 4.03 (3/2) 4.03 (4) 4.03.01 (9) 4.03.01 (15/3)
  4.03.01 (16/4) 4.03.01 (17/5) 4.03.01 (17.1/2) 4.03.03 (4) 4.03.03
  (14) 4.03.03 (17/5) 4.03.04 (0) 7.05 (2.6/2)

.. index:: AI12-0128 (Ada 2022 feature)

* *AI12-0128 Exact size access to parts of composite atomic objects (2019-11-24)*

  According to this AI, the compiler generates full access to atomic composite objects even if the access is only partial in the source code. To use this feature the compilation flag ``-gnat2022`` must be specified.

  RM references: C.06 (13.2/3) C.06 (19) C.06 (20) C.06 (22/2) C.06 (25/4)

.. index:: AI12-0129 (Ada 2022 feature)

* *AI12-0129 Make protected objects more protecting (2020-07-01)*

  A new aspect Exclusive_Functions has been added to the language to force the
  use of read/write locks on protected functions when needed.

  RM references: 9.05.01 (2) 9.05.01 (4) 9.05.01 (5) 9.05.01 (7) 9.05.03
  (15) 9.05.03 (23)

.. index:: AI12-0130 (Ada 2022 feature)

* *AI12-0130 All I/O packages should have Flush (2016-07-03)*

  The Flush routine has been added for the ``Sequential_IO`` and ``Direct_IO`` standard packages in the Ada 2012 COR.1:2016. The Flush routine here is equivalent to the one found in ``Text_IO``. The ``Flush`` procedure synchronizes the external file with the internal file (by flushing any internal buffers) without closing the file.

  RM references: A.08.01 (10) A.08.02 (28/3) A.08.04 (10) A.10.03 (21)
  A.12.01 (28/2) A.12.01 (28.6/1)

.. index:: AI12-0131 (Ada 2022 feature)

* *AI12-0131 Inherited Pre'Class when unspecified on initial subprogram (0000-00-00)*

  If T1 is a tagged type with a primitive P that has no class-wide precondition,
  and if T2 is an extension of T1 which overrides the inherited primitive P, then that overriding P is not allowed to have a class-wide precondition. Allowing it would be ineffective except in corner cases where it would be confusing.

  RM references: 6.01.01 (17/3) 6.01.01 (18/3)

.. index:: AI12-0132 (Ada 2022 feature)

* *AI12-0132 Freezing of renames-as-body (2020-06-13)*

  This AI clarifies that a renames-as-body freezes the expression of any
  expression function that it renames.

  RM references: 13.14 (5/3)

.. index:: AI12-0133 (Ada 2022 feature)

* *AI12-0133 Type invariants and default initialized objects (0000-00-00)*

  Clarify that invariant checking for a default-initialized object is performed regardless of where the object is declared (in particular, even when the full view of the type is visible).

  RM references: 7.03.02 (10.3/3)

.. index:: AI12-0135 (Ada 2022 feature)

* *AI12-0135 Enumeration types should be eligible for convention C (0000-00-00)*

  Ada previously allowed but did not require supporting specifying convention C for an enumeration type. Now it is required that an implementation shall support it.

  RM references: B.01 (14/3) B.01 (41/3) B.03 (65)

.. index:: AI12-0136 (Ada 2022 feature)

* *AI12-0136 Language-defined packages and aspect Default_Storage_Pool (0000-00-00)*

  Clarify that the effect of specifying Default_Storage_Pool for an instance of a predefined generic is implementation-defined. No compiler impact.

  RM references: 13.11.03 (5/3)

.. index:: AI12-0137 (Ada 2022 feature)

* *AI12-0137 Incomplete views and access to class-wide types (0000-00-00)*

  If the designated type of an access type is incomplete when the access type is declared, then we have rules about whether we get a complete view when a value of the access type is dereferenced. Clarify that analogous rules apply if the designated type is class-wide.

  RM references: 3.10.01 (2.1/2)

.. index:: AI12-0138 (Ada 2022 feature)

* *AI12-0138 Iterators of formal derived types (2021-02-11)*

  AI12-0138 specifies the legality rules for confirming specifications of
  nonoverridable aspects. This completes the legality checks for aspect ``Implicit_Dereference`` and simplifies the checks for those aspects that are inherited operations.

  RM references: 13.01.01 (18/4) 13.01.01 (34/3) 4.01.05 (6/3) 4.01.06 (5/3)
  4.01.06 (6/3) 4.01.06 (7/3) 4.01.06 (8/3) 4.01.06 (9/3) 5.05.01 (11/3)

.. index:: AI12-0140 (Ada 2022 feature)

* *AI12-0140 Access to unconstrained partial view when full view is constrained (0000-00-00)*

  Clarify some confusion about about whether what matters when checking whether designated subtypes statically match is the view of the designated type that is currently available v.s. the view that was available when the access type was declared.

  RM references: 3.02 (7/2) 7.03.01 (5/1)

.. index:: AI12-0143 (Ada 2022 feature)

* *AI12-0143 Using an entry index of a family in a precondition (2022-04-05)*

  Ada 2022 adds the ``Index`` attribute, which allows the use of the entry family index of an entry call within preconditions and post-conditions.

  RM references: 6.01.01 (30/3) 9.05.04 (5/3)

.. index:: AI12-0144 (Ada 2022 feature)

* *AI12-0144 Make Discrete_Random more flexible (2020-01-31)*

  A new function Random with First/Last parameters is provided in the
  ``Ada.Numerics.Discrete_Random`` package.

  RM references: A.05.02 (20) A.05.02 (32) A.05.02 (41) A.05.02 (42)

.. index:: AI12-0145 (Ada 2022 feature)

* *AI12-0145 Pool_of_Subpool returns null when called too early (0000-00-00)*

  Clarify that if you ask for the pool of a subpool (by calling ``Pool_Of_Subpool``) before ``Set_Pool_of_Subpool`` is called, then the result is null.

  RM references: 13.11.04 (20/3)

.. index:: AI12-0147 (Ada 2022 feature)

* *AI12-0147 Expression functions and null procedures can be declared in a protected_body (2015-03-05)*

  AI12-0147 specifies that null procedures and expression functions are now
  allowed in protected bodies.

  RM references: 9.04 (8/1)

.. index:: AI12-0149 (Ada 2022 feature)

* *AI12-0149 Type invariants are checked for functions returning access-to-type (0000-00-00)*

  Extend the rule saying that ``Type_Invariant`` checks are performed for access-to-T parameters (where T has a specified ``Type_Invariant``) so that the rule also applies to function results.

  RM references: 7.03.02 (19.3/4)

.. index:: AI12-0150 (Ada 2022 feature)

* *AI12-0150 Class-wide type invariants and statically bound calls (0000-00-00)*

  The same approach used in AI12-0113 to ensure that contract-related calls associated with a call to a subprogram "match" with respect to dispatching also applies to ``Type_Invariant`` checking.

  RM references: 7.03.02 (3/3) 7.03.02 (5/3) 7.03.02 (9/3) 7.03.02 (22/3)

.. index:: AI12-0154 (Ada 2022 feature)

* *AI12-0154 Aspects of library units (0000-00-00)*

  Clarify that an aspect_specification for a library unit is equivalent to a corresponding aspect-specifying pragma.

  RM references: 13.01.01 (32/3)

.. index:: AI12-0156 (Ada 2022 feature)

* *AI12-0156 Use subtype_indication in generalized iterators (0000-00-00)*

  For iterating over an array, we already allow (but do not require) explicitly providing a subtype indication in an iterator_specification. Tee AI generalizes this to handle the case where the element type of the array is of an anonymous access type. This also allows (but does not require) explicitly naming the cursor subtype in a generalized iterator.
  The main motivation for allowing these new cases is improving readability by making it easy to infer the (sub)type of the iteration object just by looking at the loop.

  RM references: 5.05.02 (2/3) 5.05.02 (5/4) 5.05.02 (7/3) 3.10.02 (11.1/2)

.. index:: AI12-0157 (Ada 2022 feature)

* *AI12-0157 Missing rules for expression functions (0000-00-00)*

  Clarify that an expression function behaves like a single-return-statement
  function in more cases: it can return an aggregate without extra parens, the expression has an applicable index constraint, and the same accessibility rules apply in both cases.

  For instance, the code below is legal:

  .. code::

    subtype S is String (1 .. 10);
    function f return S is (others => '?');

  RM references: 3.10.02 (19.2/4) 3.10.02 (19.3/4) 4.03.03 (11/2) 6.08 (2/3)
  6.08 (3/3) 6.08 (5/3) 6.08 (6/3) 6.08 (7/3) 7.05 (2.9/3) 13.14
  (5.1/4) 13.14 (5.2/4) 13.14 (8/3) 13.14 (10.1/3) 13.14 (10.2/3)
  13.14 (10.3/3)

.. index:: AI12-0160 (Ada 2022 feature)

* *AI12-0160 Adding an indexing aspect to an indexable container type (0000-00-00)*

  If the parent type of a derived type has exactly one of the two indexing aspects (that is, constant_indexing and variable_indexing) specified, then the derived type cannot have a specification for the other one.

  RM references: 4.01.06 (6/4) 4.01.06 (9/4) 3.06 (22.2/3)

.. index:: AI12-0162 (Ada 2022 feature)

* *AI12-0162 Memberships and Unchecked_Unions (0000-00-00)*

  Clarify that membership tests for unchecked_union types work consistently when
  testing membership in more than one subtype (X in AA | BB | CC)  as when
  testing for one.

  RM references: B.03.03 (25/2)

.. index:: AI12-0164 (Ada 2022 feature)

* *AI12-0164 Max_Entry_Queue_Length aspect for entries (2019-06-11)*

  AI12-0164 defines pragma and aspect ``Max_Entry_Queue_Length`` in addition
  to the GNAT-specific equivalents ``Max_Queue_Length`` and ``Max_Entry_Queue_Depth``.

  RM references: D.04 (16)

.. index:: AI12-0165 (Ada 2022 feature)

* *AI12-0165 Operations of class-wide types and formal abstract subprograms (2021-10-19)*

  Ada 2022 specifies that when the controlling type of a formal abstract
  subprogram declaration is a formal type, and the actual type is a class-wide type T'Class, the actual subprogram can be an implicitly declared subprogram corresponding to a primitive operation of type T.

  RM references: 12.06 (8.5/2)

.. index:: AI12-0166 (Ada 2022 feature)

* *AI12-0166 External calls to protected functions that appear to be internal calls (2016-11-15)*

  According to this AI, the compiler rejects a call to a protected operation when the call appears within a precondition for another protected operation.

  RM references: 6.01.01 (34/3) 9.05 (3/3) 9.05 (7.1/3)

.. index:: AI12-0167 (Ada 2022 feature)

* *AI12-0167 Type_Invariants and tagged-type View Conversions (0000-00-00)*

  This AI clarifies that no invariant check is performed in a case where an invariant-violating value is assigned to a component. This confirms the current compiler behavior.

  RM references: 7.03.02 (9/4)

.. index:: AI12-0168 (Ada 2022 feature)

* *AI12-0168 Freezing of generic instantiations of generics with bodies (0000-00-00)*

  Adjust freezing rules to be compatible with AI12-0103-1. The change confirms the current compiler behavior.

  RM references: 13.14 (3/4)

.. index:: AI12-0169 (Ada 2022 feature)

* *AI12-0169 Aspect specifications for entry bodies (0000-00-00)*

  Change syntax to allow aspect specifications for implementation-defined aspects on entry bodies. The change doesn't influence any of the language-defined aspects and is solely required for SPARK.

  RM references: 9.05.02 (5)

.. index:: AI12-0170 (Ada 2022 feature)

* *AI12-0170 Abstract subprogram calls in class-wide precondition expressions (2020-07-06)*

  This AI specifies rules for calls to abstract functions within class-wide preconditions and postconditions.

  RM references: 3.09.03 (7) 6.01.01 (7/4) 6.01.01 (18/4) 6.01.01 (18.2/4)

.. index:: AI12-0172 (Ada 2022 feature)

* *AI12-0172 Raise expressions in limited contexts (2019-07-29)*

  The compiler has been enhanced to support the use of raise expressions in
  limited contexts.

  RM references: 7.05 (2.1/3)

.. index:: AI12-0173 (Ada 2022 feature)

* *AI12-0173 Expression of an extended return statement (0000-00-00)*

  Fix the wording related to expression of an extended return statement that was made ambiguous by changes of syntax in other AI's. No compiler changes involved.

  RM references: 6.05 (3/2) 6.05 (5/3)

.. index:: AI12-0174 (Ada 2022 feature)

* *AI12-0174 Aggregates of Unchecked_Unions using named notation (0000-00-00)*

  In many cases, it is illegal to name a discriminant of an unchecked_union type.  Relax this rule to allow the use of named notation in an aggregate of an unchecked_union type.

  RM references: B.03.03 (9/3)

.. index:: AI12-0175 (Ada 2022 feature)

* *AI12-0175 Preelaborable packages with address clauses (2020-03-20)*

  The compiler nows accepts calls to certain functions that are essentially unchecked conversions in preelaborated library units. To use this feature the compilation flag ``-gnat2022`` must be specified.

  RM references: 10.02.01 (7)

.. index:: AI12-0179 (Ada 2022 feature)

* *AI12-0179 Failure of postconditions of language-defined units (0000-00-00)*

  A clarification that expressing postconditions for predefined units via RM wording or via ``Post`` aspect specifications are equivalent. In particular, the expression in such a ``Post`` aspect specification should not yield False. No implementation changes needed.

  RM references: 1.01.03 (17/3) 11.04.02 (23.1/3)

.. index:: AI12-0180 (Ada 2022 feature)

* *AI12-0180 Using protected subprograms and entries within an invariant (2020-06-22)*

  AI12-0180 makes entries and protected subprograms directly visible within Invariant aspects of a task or protected type.

  RM references: 13.01.01 (12/3)

.. index:: AI12-0181 (Ada 2022 feature)

* *AI12-0181 Self-referencing representation aspects (0000-00-00)*

  Clarify that a name or expression which freezes an entity cannot occur in an aspect specification for that entity.

  RM references: 13.01 (9/4) 13.01 (9.1/4) 13.14 (19)

.. index:: AI12-0182 (Ada 2022 feature)

* *AI12-0182 Pre'Class and protected operations (0000-00-00)*

  Confirm that Pre'Class and Post'Class cannot be specified for a protected operation. No language change.

  RM references: 13.01.01 (16/3)

.. index:: AI12-0184 (Ada 2022 feature)

* *AI12-0184 Long Long C Data Types (2020-01-30)*

  Two new types ``long_long`` and ``unsigned_long_long`` are introduced in the package ``Interfaces.C``.

  RM references: B.03 (71.3/3)

.. index:: AI12-0185 (Ada 2022 feature)

* *AI12-0185 Resolution of postcondition-specific attributes (0000-00-00)*

  Clarify resolution rules for ``'Old`` and ``'Result`` attribute references to match original intent.

  RM references: 6.01.01 (7/4) 6.01.01 (8/3) 6.01.01 (26.10/4) 6.01.01 (29/3)

.. index:: AI12-0186 (Ada 2022 feature)

* *AI12-0186 Profile freezing for the Access attribute (0000-00-00)*

  Clarify that the use of Some_Subprogram'Access does not freeze the profile of Some_Subprogram.

  RM references: 13.14 (15)

.. index:: AI12-0187 (Ada 2022 feature)

* *AI12-0187 Stable properties of abstract data types (2020-11-04)*

  Ada 2022 defines a new aspect, ``Stable_Properties``, for use in
  generating additional postcondition checks for subprograms.

  RM references: 7.03.04 (0) 13.01.01 (4/3)

.. index:: AI12-0191 (Ada 2022 feature)

* *AI12-0191 Clarify "part" for type invariants (0000-00-00)*

  Clarify that for purposes of determining whether an invariant check is required for a "part" of an object, we do not look at "parts" which do not correspond to "parts" of the nominal type of the object. For example, if we have a parameter Param of a tagged type T1 (or equivalently of type T1'Class), and type T2 is an extension of T1 which declares a component Foo, and T1'Class (Param)'Tag = T2'Tag, then no invariant check is performed for Param's Foo component (or any subcomponent thereof).

  RM references: 3.03 (23/5) 3.09.01 (4.1/2) 6.08 (5.8/5) 7.03.02 (8.3/5)
  7.03.02 (8.4/5) 7.03.02 (8.5/5) 7.03.02 (8.6/5) 7.03.02 (8.7/5)
  7.03.02 (8.8/5) 7.03.02 (8.9/5) 7.03.02 (8.10/5) 7.03.02 (8.11/5)
  7.03.02 (8.12/5) 7.03.02 (10.1/4) 7.03.02 (15/5) 7.03.02 (17/4)
  7.03.02 (18/4) 7.03.02 (19/4) 13.13.02 (9/3)

.. index:: AI12-0192 (Ada 2022 feature)

* *AI12-0192 "requires late initialization" and protected types (2020-03-11)*

  This AI clarifies that components of a protected type require late initialization when their initialization references (implicitly) the current instance of the type.

  RM references: 3.03.01 (8.1/2)

.. index:: AI12-0194 (Ada 2022 feature)

* *AI12-0194 Language-defined aspects and entry bodies (0000-00-00)*

  The AI Includes entry bodies on the list of bodies for which no language-defined aspects can be specified (although specifying an implementation-defined aspect may be allowed).

  A wording change, no implementation impact.

  RM references: 13.01.01 (17/3)

.. index:: AI12-0195 (Ada 2022 feature)

* *AI12-0195 Inheriting body but overriding precondition or postcondition (2021-08-11)*

  Ada 2022 specifies that if a primitive with a class-wide precondition or
  postcondition is inherited, and some primitive function called in the class-wide precondition or postcondition is overridden, then a dispatching call to the first primitive with a controlling operand that has the tag of the overriding type is required to check both the interpretation using the overriding function and the interpretation using the original overridden function.

  RM references: 6.01.01 (38/4)

.. index:: AI12-0196 (Ada 2022 feature)

* *AI12-0196 Concurrent access to Ada container libraries (0000-00-00)*

  Clarify that parallel execution of operations which use cursors to refer to different elements of the same container does not violate the rules about erroneous concurrent access in some cases. That is, if C1 and C2 are cursors that refer to different elements of some container, then it is ok to concurrently execute an operation that is passed C1 and which accesses one element of the container, with another operation (perhaps the same operation, perhaps not) that is passed C2 and which accesses another element of the container.

  RM references: A.18 (2/2) A.18.02 (125/2) A.18.02 (133/3) A.18.02 (135/3)
  A.18.03 (81/3) A.18.04 (36/3) A.18.07 (34/2) A.18.10 (116/3)

.. index:: AI12-0198 (Ada 2022 feature)

* *AI12-0198 Potentially unevaluated components of array aggregates (2020-05-13)*

  Ada 2022 enforces the detection of components that belong to a nonstatic or
  null range of index values of an array aggregate.

  RM references: 6.01.01 (22.1/4)

.. index:: AI12-0199 (Ada 2022 feature)

* *AI12-0199 Abstract subprogram calls in class-wide invariant expressions (0000-00-00)*

  Class-wide type invariants do not apply to abstract types, to avoid various
  problems. Define the notion of a "corresponding expression" for a class-wide
  type invariant, replacing references to components as appropriate, taking into
  account rules for corresponding and specified discriminants when applying them
  to a nonabstract descendant.

  RM references: 7.03.02 (5/4) 7.03.02 (8/3)

.. index:: AI12-0201 (Ada 2022 feature)

* *AI12-0201 Missing operations of static string types (2020-02-25)*

  Relational operators and type conversions of static string types are now static in Ada 2022.

  RM references: 4.09 (9) 4.09 (19) 4.09 (20) 4.09 (24)

.. index:: AI12-0203 (Ada 2022 feature)

* *AI12-0203 Overriding a nonoverridable aspect (0000-00-00)*

  A corner case wording clarification that has no impact on compilers.

  RM references: 4.01.05 (5.1/4) 4.01.05 (7/3)

.. index:: AI12-0204 (Ada 2022 feature)

* *AI12-0204 Renaming of a prefixed view (2020-02-24)*

  AI12-0204 clarifies that the prefix of a prefixed view that is renamed or
  passed as a formal subprogram must be renameable as an object.

  RM references: 8.05.04 (5.2/2) 12.06 (8.3/2) 4.01.03 (13.1/2) 4.01.06 (9/5)

.. index:: AI12-0205 (Ada 2022 feature)

* *AI12-0205 Defaults for generic formal types (2021-04-01)*

  AI12-0205 specifies syntax and semantics that provide defaults for formal types of generic units. The legality rules guarantee that the default subtype_mark that is specified for a formal type would be a legal actual in any instantiation of the generic unit.

  RM references: 12.03 (7/3) 12.03 (10) 12.05 (2.1/3) 12.05 (2.2/3) 12.05 (7/2)

.. index:: AI12-0206 (Ada 2022 feature)

* *AI12-0206 Nonoverridable should allow arbitrary kinds of aspects (0000-00-00)*

  A non-overridable aspect can have a value other than a name; for example, ``Max_Entry_Queue_Length`` is non-overridable and it has a scalar value.
  Part of adding support for ``Max_Entry_Queue_Length`` (which is already supported by GNAT).

  RM references: 13.01.01 (18.2/4) 13.01.01 (18.3/4) 13.01.01 (18.6/4)

.. index:: AI12-0207 (Ada 2022 feature)

* *AI12-0207 Convention of anonymous access types (2020-02-01)*

  The convention of anonymous access elements of arrays now have the same convention as the array instead of convention Ada.

  RM references: 6.03.01 (13.1/3) B.01 (19) B.01 (21/3)

.. index:: AI12-0208 (Ada 2022 feature)

* *AI12-0208 Predefined Big numbers support (0000-00-00)*

  Add predefined package ``Ada.Numerics.Big_Numbers``.

  RM references: A.05.05 (0) A.05.06 (0) A.05.07 (0)

.. index:: AI12-0211 (Ada 2022 feature)

* *AI12-0211 Interface types and inherited nonoverridable aspects (2020-08-24)*

  AI12-0211 introduces two new legality rules for Ada 2022. The first says that
  if a nonoverridable aspect is explicitly specified for a type that also inherits that aspect from another type (an ancestor or a progenitor), then the explicit aspect specification shall be confirming. The second says that if a type inherits a nonoverridable aspect from two different sources (this can only occur if at least one of the two is an interface type), then the two sources shall agree with respect to the given aspect. This AI is a binding interpretation, so these checks are performed even for earlier Ada versions. Because of compatibility concerns, an escape mechanism for suppressing these legality checks is provided: these new checks always pass if the ``-gnatd.M`` switch (relaxed RM semantics) is specified.

  RM references: 13.01.01 (18.3/5) 13.01.01 (18.4/4)

.. index:: AI12-0212 (Ada 2022 feature)

* *AI12-0212 Container aggregates; generalized array aggregates (0000-00-00)*

  The AI defines a new feature: generalized array aggregates that already exists in GNAT.

  RM references: 4.03.05 (0) 1.01.04 (12) 1.01.04 (13) 2.01 (15) 2.02 (9/5)
  3.07.01 (3) 3.08.01 (4) 4.03 (2/5) 4.03 (3/5) 4.03.01 (5) 4.03.03
  (3/2) 4.03.03 (4/5) 4.03.03 (5.1/5) 4.03.03 (9) 4.03.03 (17/5)
  4.03.03 (21) 4.03.03 (23.2/5) 4.03.03 (26) 4.03.03 (27) 4.03.03
  (31) 4.03.04 (4/5) 4.04 (3.1/3) 11.02 (3) 13.01.01 (5/3)
  13.01.01 (7/3) A.18.02 (8/3) A.18.02 (14/2) A.18.02 (47/2) A.18.02
  (175/2) A.18.03 (6/3) A.18.05 (3/3) A.18.06 (4/3) A.18.08 (3/3)
  A.18.09 (4/3)

.. index:: AI12-0216 (Ada 2022 feature)

* *AI12-0216 6.4.1(6.16-17/3) should never apply to composite objects (0000-00-00)*

  Fix wording so that parameter passing cases where there isn't really any aliasing problems or evaluation order dependency are classified as acceptable.

  No compiler impact.

  RM references: 6.04.01 (6.17/3)

.. index:: AI12-0217 (Ada 2022 feature)

* *AI12-0217 Rules regarding restrictions on the use of the Old attribute are too strict (2020-03-25)*

  AI12-0217 loosens the rules regarding what is allowed as the prefix of a 'Old
  attribute reference. In particular, a prefix is now only required to "statically name" (as opposed to the previous "statically denote") an object. This means that components of composite objects that previously would have been illegal are now legal prefixes.

  RM references: 6.01.01 (24/3) 6.01.01 (27/3)

.. index:: AI12-0220 (Ada 2022 feature)

* *AI12-0220 Pre/Post for access-to-subprogram types (2020-04-14)*

  Contract aspects can now be specified for access-to-subprogram types, as
  defined for Ada 2022 in this AI.

  RM references: 6.01.01 (1/4) 6.01.01 (2/3) 6.01.01 (4/3) 6.01.01 (19/3)
  6.01.01 (28/3) 6.01.01 (29/3) 6.01.01 (39/3) 13.01.01 (12/5)

.. index:: AI12-0222 (Ada 2022 feature)

* *AI12-0222 Representation aspects and private types (0000-00-00)*

  Clarify that the rule against specifying a representation aspect for a type before the type is completely defined also applies in the case where aspect_specification syntax is used (not just in the case where a pragma or some other kind of representation item is used).

  GNAT already implements this.

  RM references: 13.01 (9/5) 13.01 (9.1/4) 13.01 (9.2/5)

.. index:: AI12-0225 (Ada 2022 feature)

* *AI12-0225 Prefix of Obj'Image (0000-00-00)*

  Clarify some Object vs. Value corner cases to allow names that do not denote objects in more contexts, such as a qualified expression as a prefix of an Image attribute.

  RM references: 3.05 (55.1/4)

.. index:: AI12-0226 (Ada 2022 feature)

* *AI12-0226 Make objects more consistent (0000-00-00)*

  Allow value conversions as objects. For instance this example becomes legal: ``Long_Integer (Duration'Last)'Image``.

  RM references: 3.03 (11.1/3) 3.03 (21.1/3) 3.03 (23.8/5) 4.06 (58.1/4)
  4.06 (58.3/4)

.. index:: AI12-0227 (Ada 2022 feature)

* *AI12-0227 Evaluation of nonstatic universal expressions when no operators are involved (0000-00-00)*

  Nonstatic universal integer expressions are always evaluated at runtime as values of type root_integer; similarly, nonstatic universal real expressions are always evaluated at runtime as values of type root_real.
  This AI corrects a wording oversight. Previously, the above was only true if a call to operator was involved. With this change it is true in all cases.

  No compiler impact.

  RM references: 4.04 (10) 8.06 (29)

.. index:: AI12-0228 (Ada 2022 feature)

* *AI12-0228 Properties of qualified expressions used as names (2020-02-19)*

  This AI clarifies that properties of a qualified object pass through a
  qualified expression used as a name. Specifically, "aliased" and "known to be
  constrained" are not changed by a qualified expression.

  RM references: 3.03 (23.7/3) 3.10 (9/3)

.. index:: AI12-0231 (Ada 2022 feature)

* *AI12-0231 Null_Task_Id and Activation_Is_Complete (0000-00-00)*

  Add ``Activation_Is_Complete`` to the list of functions that raise P_E if passed ``Null_Task_Id``, correcting an oversight.

  RM references: C.07.01 (15)

.. index:: AI12-0232 (Ada 2022 feature)

* *AI12-0232 Rules for pure generic bodies (0000-00-00)*

  Clarify the rules for a generic body nested in a pure library unit.

  RM references: 10.02.01 (9/3) 10.02.01 (15.1/3) 10.02.01 (15.5/3)

.. index:: AI12-0233 (Ada 2022 feature)

* *AI12-0233 Pre'Class for hidden operations of private types (0000-00-00)*

  Clarify how ``Pre'Class`` checking interacts with private-part overriding of inherited subprograms. A class-wide precondition can be checked at runtime even if it is specified in a private part that the caller cannot see into.

  RM references: 6.01.01 (38/4)

.. index:: AI12-0234 (Ada 2022 feature)

* *AI12-0234 Compare-and-swap for atomic objects (0000-00-00)*

  New predefined units for atomic operations (``System.Atomic_Operations`` and child units thereof).

  RM references: C.06.01 (0) C.06.02 (0)

.. index:: AI12-0235 (Ada 2022 feature)

* *AI12-0235 System.Storage_Pools should be pure (0000-00-00)*

  Change the predefined package System.Storage_Pools from preelaborated to pure.

  RM references: 13.11 (5)

.. index:: AI12-0236 (Ada 2022 feature)

* *AI12-0236 declare expressions (2020-04-08)*

  A ``declare expression`` allows constant objects and renamings to be
  declared within an expression.

  RM references: 2.08 (6) 3.09.02 (3) 3.10.02 (9.1/3) 3.10.02 (16.1/3)
  3.10.02 (32.2/3) 4.03.02 (5.4/3) 4.03.03 (15.1/3) 4.04 (7/3)
  4.05.09 (0) 6.02 (10/4) 7.05 (2.1/5) 8.01 (2.1/4)

.. index:: AI12-0237 (Ada 2022 feature)

* *AI12-0237 Getting the representation of an enumeration value (2020-01-31)*

  The GNAT-specific attributes ``Enum_Rep`` and ``Enum_Val`` have been standardized and are now also supported as Ada 2022 attributes.

  RM references: 13.04 (10) 13.04 (11/3)

.. index:: AI12-0242 (Ada 2022 feature)

* *AI12-0242 Shorthand Reduction Expressions for Objects (0000-00-00)*

  Allow reduction expressions to iterate over an an array or an iterable object without having to explicitly create a value sequence.

  This allows, for instance, writing ``A'Reduce("+", 0)`` instead of the equivalent (but more verbose) ``[for Value of A => Value]'Reduce("+", 0);``.

  RM references: 4.05.10 (0) 4.01.04 (6)

.. index:: AI12-0247 (Ada 2022 feature)

* *AI12-0247 Potentially Blocking goes too far for Detect_Blocking (0000-00-00)*

  During a protected action, a call on a subprogram that contains a potentially blocking operation is considered a bounded error (so raising P_E is optional).
  This rule imposed an unreasonable implementation burden.
  The new rule introduced by this AI allows ignoring (i.e., not detecting) the problem until execution of a potentially blocking operation is actually attempted.

  RM references: 9.05 (55/5) 9.05 (56/5) 9.05.01 (18/5) H.05 (5/2)

.. index:: AI12-0249 (Ada 2022 feature)

* *AI12-0249 User-defined numeric literals (2020-04-07)*

  Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for  ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined
  aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types.

  RM references: 4.02 (9) 4.02.01 (0) 4.09 (3)

.. index:: AI12-0250 (Ada 2022 feature)

* *AI12-0250 Iterator Filters (2020-05-19)*

  This AI defines Ada 2022 feature of iterator filters, which can be
  applied to loop parameter specifications and iterator specifications.

  RM references: 4.03.03 (21) 4.03.03 (26) 4.03.03 (31) 4.03.05 (0) 4.05.10
  (0) 5.05 (4) 5.05 (7) 5.05 (9/4) 5.05 (9.1/4) 5.05 (10)
  5.05.02 (2/3) 5.05.02 (10/3) 5.05.02 (11/3)

.. index:: AI12-0252 (Ada 2022 feature)

* *AI12-0252 Duplicate interrupt handlers under Ravenscar (2018-07-05)*

  Ada Issue AI12-0252 requires that the runtime shall terminate with a
  Program_Error when more than one interrupt handler is attached to the same interrupt and the restriction No_Dynamic_Attachment is in effect.

  RM references: C.03.01 (13)

.. index:: AI12-0254 (Ada 2022 feature)

* *AI12-0254 Bounded_Indefinite_Holders (2025-12-15)*

  This AI defines a new package ``Ada.Containers.Indefinite_Holders`` which
  is fully implemented by GNAT.

  RM references: A.18.32 (0)

.. index:: AI12-0256 (Ada 2022 feature)

* *AI12-0256 Aspect No_Controlled_Parts (2021-01-26)*

  The compiler now supports the Ada 2022 aspect No_Controlled_Parts (see
  AI12-0256). When specified for a type, this aspect requires that the type and any of its ancestors must not have any controlled parts.

  RM references: H.04.01 (0) 13.01.01 (18.7/5)

.. index:: AI12-0258 (Ada 2022 feature)

* *AI12-0258 Containers and controlled element types (0000-00-00)*

  Most predefined containers are allowed to defer finalization of container elements until the finalization of the container. This allows implementation flexibility  but  causes problems in some cases. AI12-0258 tightens up the rules for the indefinite containers to say that finalization happens earlier - if a client needs the tighter finalization guarantees, then it can use the indefinite containers (even if the element subtype in question is definite). Other solutions involving the holder generic are also possible.

  GNAT implements these tighter element finalization requirements for instances of the indefinite container generics.

  RM references: A.18 (10/4)

.. index:: AI12-0259 (Ada 2022 feature)

* *AI12-0259 Lower bound of strings returned from Ada.Command_Line (0000-00-00)*

  Specify that the low-bound of a couple of predefined String-valued functions will always be one.

  RM references: A.15 (14) A.15 (16/3)

.. index:: AI12-0260 (Ada 2022 feature)

* *AI12-0260 Functions Is_Basic and To_Basic in Wide_Characters.Handling (2020-04-01)*

  AI12-0260 is implemented for Ada 2022, providing the new functions ``Is_Basic`` and ``To_Basic`` in package ``Ada.Wide_Characters.Handling``.

  RM references: 1.02 (8/3) A.03.05 (8/3) A.03.05 (20/3) A.03.05 (21/3)
  A.03.05 (33/3) A.03.05 (61/3)

.. index:: AI12-0261 (Ada 2022 feature)

* *AI12-0261 Conflict in "private with" rules (0000-00-00)*

  If a library unit is only visible at some point because of a "private with", there are legality rules about a name denoting that entity. The AI cleans up the wording so that it captures the intent in a corner case involving a private-child library-unit subprogram. The previous wording incorrectly caused this case to be illegal.

  RM references: 10.01.02 (12/3) 10.01.02 (13/2) 10.01.02 (14/2) 10.01.02
  (15/2) 10.01.02 (16/2)

.. index:: AI12-0262 (Ada 2022 feature)

* *AI12-0262 Map-Reduce attribute (0000-00-00)*

  The AI defines Reduction Expressions to allow the programmer to apply the
  Map-Reduce paradigm to map/transform a set of values to a new set of values,
  and then summarize/reduce the transformed values into a single result value.

  RM references: 4.01.04 (1) 4.01.04 (6) 4.01.04 (11) 4.05.10 (0)

.. index:: AI12-0263 (Ada 2022 feature)

* *AI12-0263 Update references to ISO/IEC 10646 (0000-00-00)*

  Change RM references to ISO/IEC 10646:2011 to instead refer to ISO/IEC 10646:2017. No compiler impact.

  RM references: 1.01.04 (14.2/3) 2.01 (1/3) 2.01 (3.1/3) 2.01 (4/3) 2.01
  (4.1/5) 2.01 (5/3) 2.01 (15/3) 2.01 (4.1/5) 2.01 (5/3) 2.03
  (4.1/5) 2.03 (5/3) 3.05.02 (2/3) 3.05.02 (3/3) 3.05.02 (4/3) A.01
  (36.1/3) A.01 (36.2/3) A.03.02 (32.6/5) A.03.05 (51.2/5) A.03.05
  (55/3) A.03.05 (59/3) A.04.10 (3/3) B.05 (21/5)

.. index:: AI12-0264 (Ada 2022 feature)

* *AI12-0264 Overshifting and overrotating (0000-00-00)*

  Clarify Shift and Rotate op behavior with large shift/rotate amounts.

  RM references: B.02 (9)

.. index:: AI12-0265 (Ada 2022 feature)

* *AI12-0265 Default_Initial_Condition for types (2020-11-13)*

  The aspect ``Default_Initial_Condition``, originally proposed by SPARK and
  supported in GNAT, is now also included in Ada 2022. One change from the
  original implementation is that when the aspect is specified on ancestor types of a derived type, the ancestors' check expressions also apply to the derived type.
  ``Default_Initial_Condition`` checks are also now applied in cases of default
  initialization of components, allocators, ancestor parts of extension aggregates, and box associations of aggregates.

  RM references: 7.03.03 (0) 1.01.03 (17.1/5) 11.04.02 (23.2/5) 11.04.02 (23.3/5)

.. index:: AI12-0269 (Ada 2022 feature)

* *AI12-0269 Aspect No_Return for functions reprise (2020-03-19)*

  This amendment has been implemented under the ``-gnat2022`` switch, and the
  compiler now accepts the aspect/pragma No_Return for functions and generic
  functions.

  RM references: 6.05.01 (0) 6.05.01 (1/3) 6.05.01 (3.1/3) 6.05.01 (3.4/3)
  6.05.01 (5/2) 6.05.01 (6/2) 6.05.01 (7/2) J.15.02 (2/3) J.15.02
  (3/3) J.15.02 (4/3)

.. index:: AI12-0272 (Ada 2022 feature)

* *AI12-0272 (part 1) Pre/Postconditions for formal subprograms (0000-00-00)*

  Pre and Post aspects can be specified for a generic formal subprogram. ``Default_Initial_Condition`` can be specified for a generic formal private type.

  GNAT implements this with an exception of the part related to ``Default_Initial_Condition``.

  RM references: 6.01.01 (1/5) 6.01.01 (39/5) 7.03.03 (1/5) 7.03.03 (2/5)
  7.03.03 (8/5) 7.03.04 (5/5) F.01 (1)

.. index:: AI12-0275 (Ada 2022 feature)

* *AI12-0275 Make subtype_mark optional in object renames (2020-01-28)*

  AI12-0275 allows object renamings to be declared without an explicit
  subtype_mark or access_definition. This feature can be used by compiling
  with the switch ``-gnat2022``.

  RM references: 8.05.01 (2/3) 8.05.01 (3/2)

.. index:: AI12-0277 (Ada 2022 feature)

* *AI12-0277 The meaning of "accessibility level of the body of F" (2020-09-09)*

  Clarify that the only time that an explicitly aliased formal parameter has different accessibility properties than an aliased part of a "normal" parameter is for the accessibility checking associated with a return statement.

  RM references: 3.10.02 (19.2/4)

.. index:: AI12-0278 (Ada 2022 feature)

* *AI12-0278 Implicit conversions of anonymous return types (0000-00-00)*

  If a call to a function with an anonymous-access-type result is converted to a named access type, it doesn't matter whether the conversion is implicit or explicit. the AI fixes hole where the previous rules didn't cover the implicit conversion case.

  RM references: 3.10.02 (10.3/3)

.. index:: AI12-0279 (Ada 2022 feature)

* *AI12-0279 Nonpreemptive dispatching needs more dispatching points (2020-04-17)*

  Ada 2022 defines a new aspect `Yield` that can be specified in the declaration of a noninstance subprogram (including a generic formal subprogram), a generic subprogram, or an entry, to ensure that the associated subprogram has at least one task dispatching point during each invocation.

  RM references: D.02.01 (1.5/2) D.02.01 (7/5)

.. index:: AI12-0280-2 (Ada 2022 feature)

* *AI12-0280-2 Making 'Old more flexible (2020-07-24)*

  For Ada 2022, AI12-0280-2 relaxes Ada's restrictions on 'Old attribute
  references whose attribute prefix does not statically name an entity. Previously, it was required that such an attribute reference must be unconditionally evaluated when the postcondition is evaluated; with the new rule, conditional evaluation is permitted if the relevant conditions can be evaluated upon entry to the subprogram with the same results as evaluation at the time of the postcondition's evaluation. In this case, the 'Old attribute prefix is evaluated conditionally (more specifically, the prefix is evaluated only if the result of that evaluation is going to be referenced later when the
  postcondition is evaluated).

  RM references: 6.01.01 (20/3) 6.01.01 (21/3) 6.01.01 (22/3) 6.01.01
  (22.1/4) 6.01.01 (22.2/5) 6.01.01 (23/3) 6.01.01 (24/3) 6.01.01
  (26/4) 6.01.01 (27/5) 6.01.01 (39/5)

.. index:: AI12-0282 (Ada 2022 feature)

* *AI12-0282 Atomic, Volatile, and Independent generic formal types (0000-00-00)*

  The AI specifies that the aspects ``Atomic``, ``Volatile``, ``Independent``, ``Atomic_Components``, ``Volatile_Components``, and ``Independent_Components`` are specifiable for generic formal types. The actual type must have a matching specification.

  RM references: C.06 (6.1/3) C.06 (6.3/3) C.06 (6.5/3) C.06 (6.8/3) C.06
  (12/3) C.06 (12.1/3) C.06 (21/4)

.. index:: AI12-0285 (Ada 2022 feature)

* *AI12-0285 Syntax for Stable_Properties aspects (0000-00-00)*

  The AI establishes the required named notation for a Stable_Properties aspect specification in order to avoid syntactic ambiguities.

  With the old syntax, an example like

  .. code::

     type Ugh is ...
        with Stable_Properties =\> Foo, Bar, Nonblocking, Pack;

  was problematic; ``Nonblocking`` and ``Pack`` are other aspects, while ``Foo`` and ``Bar`` are ``Stable_Properties`` functions. With the clarified syntax, the example above shall be written as:

  .. code::

      type Ugh is ...
        with Stable_Properties => (Foo, Bar), Nonblocking, Pack;

  RM references: 7.03.04 (2/5) 7.03.04 (3/5) 7.03.04 (4/5) 7.03.04 (6/5)
  7.03.04 (7/5) 7.03.04 (9/5) 7.03.04 (10/5) 7.03.04 (14/5) 13.01.01 (4/5)

.. index:: AI12-0287 (Ada 2022 feature)

* *AI12-0287 Legality Rules for null exclusions in renaming are too fierce (2020-02-17)*

  The null exclusion legality rules for generic formal object matching and object renaming now only apply to generic formal objects with mode in out.

  RM references: 8.05.01 (4.4/2) 8.05.01 (4.5/2) 8.05.01 (4.6/2) 8.05.04
  (4.2/2) 12.04 (8.3/2) 12.04 (8.4/2) 12.04 (8.5/2) 12.04 (8.2/5)
  12.06 (8.2/5)

.. index:: AI12-0289 (Ada 2022 feature)

* *AI12-0289 Implicitly null excluding anonymous access types and conformance (2020-06-09)*

  AI12-0289 is implemented for Ada 2022, allowing safer use of access parameters
  when the partial view of the designated type is untagged, but the full view is
  tagged.

  RM references: 3.10 (26)

.. index:: AI12-0290 (Ada 2022 feature)

* *AI12-0290 Restriction Pure_Barriers (2020-02-18)*

  The GNAT implementation of the Pure_Barriers restriction has
  been updated to match the Ada RM's definition as specified
  in this AI. Some constructs that were accepted by the previous
  implementation are now rejected, and vice versa. In
  particular, the use of a component of a component of a
  protected record in a barrier expression, as in "when
  Some_Component.Another_Component =>", formerly was (at least
  in some cases) not considered to be a violation of the
  Pure_Barriers restriction; that is no longer the case.

  RM references: D.07 (2) D.07 (10.10/4)

.. index:: AI12-0291 (Ada 2022 feature)

* *AI12-0291 Jorvik Profile (2020-02-19)*

  The Jorvik profile is now implemented, as defined in this AI.
  For Ada 2012 and earlier versions of Ada, Jorvik is an implementation-defined
  profile whose definition matches its Ada 2022 definition.

  RM references: D.13 (0) D.13 (1/3) D.13 (4/3) D.13 (6/4) D.13 (9/3) D.13
  (10/3) D.13 (11/4) D.13 (12/4)

.. index:: AI12-0293 (Ada 2022 feature)

* *AI12-0293 Add predefined FIFO_Streams packages (0000-00-00)*

  The AI adds ``Ada.Streams.Storage`` and its two subunits ``Bounded`` and ``Unbounded``.

  RM references: 13.13.01 (1) 13.13.01 (9) 13.13.01 (9.1/1)

.. index:: AI12-0295 (Ada 2022 feature)

* *AI12-0295 User-defined string  (2020-04-07)*

  Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types.

  RM references: 4.02 (6) 4.02 (10) 4.02 (11) 3.06.03 (1) 4.02.01 (0) 4.09 (26/3)

.. index:: AI12-0301 (Ada 2022 feature)

* *AI12-0301 Predicates should be checked like constraints for types with Default_Value (2020-02-25)*

  This AI clarifies that predicate checks apply for objects that are initialized
  by default and that are of a type that has any components whose subtypes specify ``Default_Value`` or ``Default_Component_Value``.

  RM references: 3.02.04 (31/4)

.. index:: AI12-0304 (Ada 2022 feature)

* *AI12-0304 Image attributes of language-defined types (2020-07-07)*

  According to this AI, ``Put_Image`` (and therefore ``'Image``) is provided for
  the containers and for unbounded strings.

  RM references: 4.10 (0)

.. index:: AI12-0306 (Ada 2022 feature)

* *AI12-0306 Split null array aggregates from positional array aggregates (0000-00-00)*

  The AI clarifies the wording of the references RM paragraphs without introducing any language changes.

  RM references: 4.03.03 (2) 4.03.03 (3/2) 4.03.03 (9/5) 4.03.03 (26/5)
  4.03.03 (26.1/5) 4.03.03 (33/3) 4.03.03 (38) 4.03.03 (39) 4.03.03 (42)

.. index:: AI12-0307 (Ada 2022 feature)

* *AI12-0307 Resolution of aggregates (2020-08-13)*

  The proposed new syntax for aggregates in Ada 2022 uses square brackets as
  delimiters, and in particular allows ``[]`` as a notation for empty array and container aggregates. This syntax is currently available as an experimental feature under the ``-gnatX`` flag.

  RM references: 4.03 (3/5)

.. index:: AI12-0309 (Ada 2022 feature)

* *AI12-0309 Missing checks for pragma Suppress (0000-00-00)*

  The AI includes some previously overlooked run-time checks in the list of checks that are potentially suppressed via a pragma ``Suppress``. For example, AI12-0251-1 adds a check that the number of chunks in a chunk_specification is not zero or negative. Clarify that suppressing ``Program_Error_Check`` suppresses that check too.

  RM references: 11.05 (10) 11.05 (19) 11.05 (20) 11.05 (22) 11.05 (24)

.. index:: AI12-0311 (Ada 2022 feature)

* *AI12-0311 Suppressing client-side assertions for language-defined units (0000-00-00)*

  The AI defines some new assertion policies that can be given as arguments in a Suppress pragma (e.g., Calendar_Assertion_Check). GNAT recognizes and ignores those new policies, the checks are not implemented.

  RM references: 11.04.02 (23.5/5) 11.05 (23) 11.05 (26)

.. index:: AI12-0315 (Ada 2022 feature)

* *AI12-0315 Image Attributes subclause improvements (0000-00-00)*

  Clarify that a named number or similar can be the prefix of an Image attribute reference.

  RM references: 4.10 (0)

.. index:: AI12-0318 (Ada 2022 feature)

* *AI12-0318 No_IO should apply to Ada.Directories (2020-01-31)*

  The restriction No_IO now applies to and prevents the use of the
  ``Ada.Directories package``.

  RM references: H.04 (20/2) H.04 (24/3)

.. index:: AI12-0321 (Ada 2022 feature)

* *AI12-0321 Support for Arithmetic Atomic Operations and Test and Set (0000-00-00)*

  The AI adds some predefined atomic operations, e.g. package System.``Atomic_Operations.Test_And_Set``.

  RM references: C.06.03 (0) C.06.04 (0)

.. index:: AI12-0325 (Ada 2022 feature)

* *AI12-0325 Various issues with user-defined literals (2020-04-07)*

  Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``, and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types.

  RM references: 4.02 (6) 4.02 (10) 4.02 (11) 4.02.01 (0)

.. index:: AI12-0329 (Ada 2022 feature)

* *AI12-0329 Naming of FIFO_Streams packages (0000-00-00)*

  The AI changes the name of predefined package ``Ada.Streams.FIFO_Streams`` to ``Ada.Streams.Storage``.

  RM references: 13.13.01 (9/5) 13.13.01 (9.1/5)

.. index:: AI12-0331 (Ada 2022 feature)

* *AI12-0331 Order of finalization of a subpool (0000-00-00)*

  Clarify that when a subpool is being finalized, objects allocated from that subpool are finalized before (not after) they cease to exist (i.e. object's storage has been reclaimed).

  RM references: 13.11.05 (5/3) 13.11.05 (6/3) 13.11.05 (7/3) 13.11.05
  (7.1/4) 13.11.05 (8/3) 13.11.05 (9/3)

.. index:: AI12-0333 (Ada 2022 feature)

* *AI12-0333 Predicate checks on out parameters (0000-00-00)*

  If a view conversion is passed as an actual parameter corresponding to an out-mode formal parameter, and if the subtype of the formal parameter has a predicate, then no predicate check associated with the conversion is performed.

  RM references: 3.02.04 (31/5) 4.06 (51/4) 6.04.01 (14)

.. index:: AI12-0335 (Ada 2022 feature)

* *AI12-0335 Dynamic accessibility check needed for some requeue targets (0000-00-00)*

  Define a new runtime accessibility check for a corner case involving requeue statements.

  RM references: 9.05.04 (7/4)

.. index:: AI12-0336 (Ada 2022 feature)

* *AI12-0336 Meaning of Time_Offset (0000-00-00)*

  The AI introduces changes to the predefined package ``Ada.Calendar.Time_Zones``.

  RM references: 9.06.01 (6/2) 9.06.01 (35/2) 9.06.01 (40/2) 9.06.01 (41/2)
  9.06.01 (42/3) 9.06.01 (90/2) 9.06.01 (91/2)

.. index:: AI12-0337 (Ada 2022 feature)

* *AI12-0337 Simple_Name("/") in Ada.Directories (0000-00-00)*

  Clarify behavior of subprograms in the predefined package ``Ada.Directories``. In particular, Simple_Name ("/") should return "/" on Unix-like systems.

  RM references: A.16 (47/2) A.16 (74/2) A.16 (82/3)

.. index:: AI12-0338 (Ada 2022 feature)

* *AI12-0338 Type invariant checking and incomplete types (0000-00-00)*

  Clarify that type invariants for type T are not checked for incomplete types whose completion is not available, even if that completion has components of type T.

  RM references: 7.03.02 (20/5)

.. index:: AI12-0339 (Ada 2022 feature)

* *AI12-0339 Empty function for Container aggregates (2020-08-06)*

  To provide uniform support for container aggregates, all standard container
  libraries have been enhanced with a function Empty, to be used when initializing an aggregate prior to inserting the specified elements in the object being constructed. All products have been updated to remove the ambiguities that may have arisen from previous uses of entities named Empty in our sources, and the expansion of container aggregates uses Empty wherever needed.

  RM references: A.18.02 (8/5) A.18.02 (12.3/5) A.18.02 (78.2/5) A.18.02
  (98.6/5) A.18.03 (6/5) A.18.03 (10.2/5) A.18.03 (50.2/5) A.18.05
  (3/5) A.18.05 (7.2/5) A.18.05 (37.3/5) A.18.05 (46/2) A.18.06
  (4/5) A.18.06 (8.2/5) A.18.06 (51.4/5) A.18.08 (3/5) A.18.08
  (8.1/5) A.18.08 (59.2/5) A.18.08 (68/2) A.18.09 (4/5) A.18.09
  (9.1/5) A.18.09 (74.2/5) A.18.10 (15.2/5) A.18.18 (8.1/5) A.18.19
  (6.1/5) A.18.20 (6/3) A.18.21 (6/3) A.18.22 (6/3) A.18.23 (6/3)
  A.18.24 (6/3) A.18.25 (8/3)

.. index:: AI12-0340 (Ada 2022 feature)

* *AI12-0340 Put_Image should use a Text_Buffer (0000-00-00)*

  Add a new predefined package Ada.Strings.Text_Buffers (along with child units) and change the definition of Put_Image attribute to refer to it.

  RM references: A.04.12 (0) 4.10 (3.1/5) 4.10 (3.2/5) 4.10 (6/5) 4.10
  (25.2/5) 4.10 (28/5) 4.10 (31/5) 4.10 (41/5) H.04 (23.2/5) H.04 (23.11/5)

.. index:: AI12-0342 (Ada 2022 feature)

* *AI12-0342 Various issues with user-defined literals (part 2) (2020-04-07)*

  Compiler support is added for three new aspects (``Integer_Literal``, ``Real_Literal``,  and ``String_Literal``) as described in AI12-0249 (for ``Integer_Literal`` and ``Real_Literal``), AI12-0295 (for ``String_Literal``), and in two follow-up AIs (AI12-0325 and AI12-0342). For pre-Ada 2022 versions of Ada, these are treated as implementation-defined aspects. Some implementation work remains, particularly in the interactions between these aspects and tagged types.

  RM references: 4.02.01 (0) 3.09.02 (1/2) 6.03.01 (22)

.. index:: AI12-0343 (Ada 2022 feature)

* *AI12-0343 Return Statement Checks (2020-04-02)*

  This binding interpretation has been implemented and the accessibility,
  predicate, and tag checks prescribed by RM 6.5 are now performed at the appropriate points, as required by this AI.

  RM references: 6.05 (5.12/5) 6.05 (8/4) 6.05 (8.1/3) 6.05 (21/3)

.. index:: AI12-0345 (Ada 2022 feature)

* *AI12-0345 Dynamic accessibility of explicitly aliased parameters (2020-09-09)*

  Further clarify (after AI12-0277) accessibility rules for explicitly aliased parameters.

  RM references: 3.10.02 (5) 3.10.02 (7/4) 3.10.02 (10.5/3) 3.10.02 (13.4/4)
  3.10.02 (19.2/5) 3.10.02 (21)

.. index:: AI12-0350 (Ada 2022 feature)

* *AI12-0350 Swap for Indefinite_Holders (2025-12-15)*

  Package ``Ada.Containers.Indefinite_Holders`` is implemented in GNAT, comprising the support for ``Swap`` as specified by this AI.

  RM references: A.18.18 (22/5) A.18.18 (67/5) A.18.18 (73/3) A.18.32 (13/5)

.. index:: AI12-0351 (Ada 2022 feature)

* *AI12-0351 Matching for actuals for formal derived types (2020-04-03)*

  This binding interpretation requires the compiler to checks
  that an actual subtype in a generic parameter association of an instantiation is statically compatible (even when the actual is unconstrained) with the ancestor of an associated nondiscriminated generic formal derived type.

  RM references: 12.05.01 (7) 12.05.01 (8)

.. index:: AI12-0352 (Ada 2022 feature)

* *AI12-0352 Early derivation and equality of untagged types (2020-07-09)*

  AI12-0352 clarifies that declaring a user-defined primitive equality operation for a record type T is illegal if it occurs after a type has been derived from T.

  RM references: 4.05.02 (9.8/4)

.. index:: AI12-0356 (Ada 2022 feature)

* *AI12-0356 Root_Storage_Pool_With_Subpools should have Preelaborable_Initialization (0000-00-00)*

  Add Preelaborable_Initialization pragmas for predefined types ``Root_Storage_Pool_With_Subpools`` and ``Root_Subpool``.

  RM references: 13.11.04 (4/3) 13.11.04 (5/3)

.. index:: AI12-0363 (Ada 2022 feature)

* *AI12-0363 Fixes for Atomic and Volatile (2020-09-08)*

  This amendment has been implemented under the ``-gnat2022`` switch and the compiler now supports the ``Full_Access_Only`` aspect, which is mostly equivalent to GNAT's ``Volatile_Full_Access``.

  RM references: 3.10.02 (26/3) 9.10 (1/5) C.06 (6.4/3) C.06 (6.10/3) C.06
  (8.1/4) C.06 (12/5) C.06 (12.1/5) C.06 (13.3/5) C.06 (19.1/5)

.. index:: AI12-0364 (Ada 2022 feature)

* *AI12-0364 Add a modular atomic arithmetic package (0000-00-00)*

  Generalize support for atomic integer operations to extend to modular types. Add new predefined generic package,
  ``System.Atomic_Operations.Modular_Arithmetic``.

  RM references: C.06.05 (0) C.06.04 (1/5) C.06.04 (2/5) C.06.04 (3/5)
  C.06.04 (9/5)

.. index:: AI12-0366 (Ada 2022 feature)

* *AI12-0366 Changes to Big_Integer and Big_Real (0000-00-00)*

  Simplify ``Big_Integer ``and ``Big_Real`` specs by eliminating explicit support for creating "invalid" values. No more
  ``Optional_Big_[Integer,Real]`` types.

  RM references: A.05.06 (0) A.05.07 (0)

.. index:: AI12-0367 (Ada 2022 feature)

* *AI12-0367 Glitches in aspect specifications (0000-00-00)*

  The AI clarifies a few wording omissions. For example, a specified Small value for a fixed point type has to be positive.

  RM references: 3.05.09 (8/2) 3.05.10 (2/1) 13.01 (9.1/5) 13.14 (10)

.. index:: AI12-0368 (Ada 2022 feature)

* *AI12-0368 Declare expressions can be static (2020-05-30)*

  AI12-0368 allows declare expressions to be static in Ada 2022.

  RM references: 4.09 (8) 4.09 (12.1/3) 4.09 (17) 6.01.01 (24.2/5) 6.01.01
  (24.3/5) 6.01.01 (24.4/5) 6.01.01 (24.5/5) C.04 (9)

.. index:: AI12-0369 (Ada 2022 feature)

* *AI12-0369 Relaxing barrier restrictions (2020-03-25)*

  The definitions of the ``Simple_Barriers`` and ``Pure_Barriers`` restrictions were modified by this AI, replacing uses of "statically denotes" with "statically names". This means that in many cases (but not all) a barrier expression that references a subcomponent of a component of the protected type while subject to either of the two restrictions is now allowed; with the previous restriction definitions, such a barrier expression would not have been legal.

  RM references: D.07 (1.3/5) D.07 (10.12/5)

.. index:: AI12-0372 (Ada 2022 feature)

* *AI12-0372 Static accessibility of "master of the call" (2020-09-09)*

  Add an extra compile-time accessibility check for explicitly aliased parameters needed to prevent dangling references.

  RM references: 3.10.02 (10.5/5) 3.10.02 (19.3/4) 6.04.01 (6.4/3)

.. index:: AI12-0373 (Ada 2022 feature)

* *AI12-0373 Bunch of fixes (0000-00-00)*

  Small clarifications to various RM entries with minor impact on compiler implementation.

  RM references: 3.01 (1) 4.02 (4) 4.02 (8/2) 4.02.01 (3/5) 4.02.01 (4/5)
  4.02.01 (5/5) 4.09 (17.3/5) 6.01.01 (41/5) 8.05.04 (4/3) 13.01.01
  (4/3) 13.01.01 (11/3) 13.14 (3/5)

.. index:: AI12-0376 (Ada 2022 feature)

* *AI12-0376 Representation changes finally allowed for untagged derived types (0000-00-00)*

  A change of representation for a derived type is allowed in some previously-illegal cases where a change of representation is required to implement a call to a derived subprogram.

  RM references: 13.01 (10/4)

.. index:: AI12-0377 (Ada 2022 feature)

* *AI12-0377 View conversions and out parameters of types with Default_Value revisited (2020-06-17)*

  This AI clarifies that an actual of an out parameter that is a view conversion
  is illegal if either the target or operand type has Default_Value specified while the other does not.

  RM references: 6.04.01 (5.1/4) 6.04.01 (5.2/4) 6.04.01 (5.3/4) 6.04.01
  (13.1/4) 6.04.01 (13.2/4) 6.04.01 (13.3/4) 6.04.01 (13.4/4) 6.04.01 (15/3)

.. index:: AI12-0381 (Ada 2022 feature)

* *AI12-0381 Tag of a delta aggregate (0000-00-00)*

  In the case of a delta aggregate of a specific tagged type, the tag of the aggregate comes from the specific type (as opposed to somehow from the base object).

  RM references: 4.03.04 (14/5)

.. index:: AI12-0382 (Ada 2022 feature)

* *AI12-0382 Loosen type-invariant overriding requirement of AI12-0042-1 (0000-00-00)*

  The AI relaxes some corner-case legality rules about type invariants that were added by AI12-0042-1.

  RM references: 7.3.2(6.1/4)

.. index:: AI12-0383 (Ada 2022 feature)

* *AI12-0383 Renaming values (2020-06-17)*

  This AI allow names that denote values rather than objects to nevertheless be
  renamed using an object renaming.

  RM references: 8.05.01 (1) 8.05.01 (4) 8.05.01 (4.1/2) 8.05.01 (6/2) 8.05.01 (8)

.. index:: AI12-0384-2 (Ada 2022 feature)

* *AI12-0384-2 Fixups for Put_Image and Text_Buffers (2021-04-29)*

  In GNAT's initial implementation of the Ada 2022 ``Put_Image`` aspect and
  attribute, buffering was performed using a GNAT-defined package,
  ``Ada.Strings.Text_Output``. Ada 2022 requires a different package, Ada.``Strings.Text_Buffers``, for this role, and that package is now provided, and the older package is eliminated.

  RM references: 4.10 (0) A.04.12 (0)

.. index:: AI12-0385 (Ada 2022 feature)

* *AI12-0385 Predefined shifts and rotates should be static (0000-00-00)*

  This AI allows Shift and Rotate operations in static expressions. GNAT implements this AI partially.

  RM references: 4.09 (20)

.. index:: AI12-0389 (Ada 2022 feature)

* *AI12-0389 Ignoring unrecognized aspects (2020-10-08)*

  Two new restrictions, ``No_Unrecognized_Aspects`` and ``No_Unrecognized_Pragmas``, are available to make the compiler emit error messages on unrecognized pragmas and aspects.

  RM references: 13.01.01 (38/3) 13.12.01 (6.3/3)

.. index:: AI12-0394 (Ada 2022 feature)

* *AI12-0394 Named Numbers and User-Defined Numeric Literals (2020-10-05)*

  Ada 2022 allows using integer named numbers with types that have an
  ``Integer_Literal`` aspect. Similarly, real named numbers may now be used with types that have a ``Real_Literal`` aspect with an overloading that takes two strings, to be used in particular  with
  ``Ada.Numerics.Big_Numbers.Big_Reals``.

  RM references: 3.03.02 (3) 4.02.01 (4/5) 4.02.01 (8/5) 4.02.01 (12/5)
  4.02.01 (13/5) 4.09 (5)

.. index:: AI12-0395 (Ada 2022 feature)

* *AI12-0395 Allow aspect_specifications on formal parameters (0000-00-00)*

  Change syntax rules to allow aspect_specifications on formal parameters, if an implementation if an implementation wants to define one. Currently, GNAT doesn't define any such aspect_specifications.

  RM references: 6.01 (15/3)

.. index:: AI12-0397 (Ada 2022 feature)

* *AI12-0397 Default_Initial_Condition applied to derived type (2020-12-09)*

  The compiler now implements the rules for resolving ``Default_Initial_Condition``
  expressions that involve references to the current instance of types with the aspect, as specified by this AI. The type of the current instance is defined to be like a formal derived type, so for a derived type that inherits the aspect, a call passing the current instance to a primitive means that the call will resolve to invoke the corresponding primitive of the descendant type. This also now permits calls to abstract primitives to occur within the aspect expression of an abstract type.

  RM references: 7.03.03 (3/5) 7.03.03 (6/5) 7.03.03 (8/5)

.. index:: AI12-0398 (Ada 2022 feature)

* *AI12-0398 Most declarations should have aspect specifications (2020-11-19)*

  It is now possible to specify aspects for discriminant specifications, extended return object declarations, and entry index specifications. This is an extension added for Ada 2022 by this AI.

  RM references: 3.07 (5/2) 6.03.01 (25) 6.05 (2.1/3) 9.05.02 (8)

.. index:: AI12-0399 (Ada 2022 feature)

* *AI12-0399 Aspect specification for Preelaborable_Initialization (0000-00-00)*

  Semantics-preserving presentation change. Replace ``Preelaborable_Initialization`` pragmas with equivalent aspect specs in the listed predefined packages. GNAT follows the guidance of this AI partially.

  RM references: 9.05 (53/5) 3.09 (6/5) 7.06 (5/2) 7.06 (7/2) 11.04.01 (2/5)
  11.04.01 (3/2) 13.11 (6/2) 13.11.04 (4/5) 13.11.04 (5/5) 13.13.01
  (3/2) A.04.02 (4/2) A.04.02 (20/2) A.04.05 (4/2) A.04.07 (4/2)
  A.04.07 (20/2) A.04.08 (4/2) A.04.08 (20/2) A.12.01 (5/4) A.18.02
  (8/5) A.18.02 (9/2) A.18.02 (79.2/5) A.18.02 (79.3/5) A.18.03
  (6/5) A.18.03 (7/2) A.18.03 (50.2/5) A.18.03 (50.3/5) A.18.05
  (3/5) A.18.05 (4/2) A.18.05 (37.3/5) A.18.05 (37.4/5) A.18.06
  (4/5) A.18.06 (5/2) A.18.06 (51.4/5) A.18.06 (51.5/5) A.18.08
  (3/5) A.18.08 (4/2) A.18.08 (58.2/5) A.18.08 (58.3/5) A.18.09
  (4/5) A.18.09 (5/2) A.18.09 (74.2/5) A.18.09 (74.3/5) A.18.10
  (8/5) A.18.10 (9/3) A.18.10 (70.2/5) A.18.10 (70.3/5) A.18.18
  (6/5) B.03.01 (5/2) C.07.01 (2/5) G.01.01 (4/2)

.. index:: AI12-0400 (Ada 2022 feature)

* *AI12-0400 Ambiguities associated with Vector Append and container aggregates (0000-00-00)*

  Change the names of subprograms in the predefined Vector containers from ``Append`` to ``Append_Vector`` and from ``Prepend`` to ``Prepend_Vector`` in order to resolve some ambiguity problems. GNAT adds the subprograms with new names but also keeps the old ones for backward compatibility.

  RM references: A.18.02 (8/5) A.18.02 (36/5) A.18.02 (37/5) A.18.02 (38/5)
  A.18.02 (44/5) A.18.02 (46/5) A.18.02 (47/5) A.18.02 (58/5)
  A.18.02 (79.2/5) A.18.02 (150/5) A.18.02 (151/5) A.18.02 (152/5)
  A.18.02 (153/5) A.18.02 (154/5) A.18.02 (155/5) A.18.02 (156/5)
  A.18.02 (168/5) A.18.02 (169/5) A.18.02 (172/5) A.18.02 (173/5)
  A.18.02 (174/5) A.18.02 (175.1/5) A.18.03 (23/5) A.18.03 (23.1/5)
  A.18.03 (58.2/5) A.18.03 (96/5) A.18.03 (97.1/5)

.. index:: AI12-0401 (Ada 2022 feature)

* *AI12-0401 Renaming of qualified expression of variable (2020-10-31)*

  Ada 2022 AI12-0401 restricts renaming of a qualified expression to cases where
  the operand is a constant, or the target subtype statically matches the nominal subtype of the operand, or is unconstrained with no predicates, to prevent setting variables to values outside their range or constraints.

  RM references: 3.03 (23.2/3) 8.05.01 (4.7/5) 8.05.01 (5/3)

.. index:: AI12-0402 (Ada 2022 feature)

* *AI12-0402 Master of a function call with elementary result type (2026-01-07)*

  This AI restricts the rule that makes the master of a function call, which
  is used to directly initialize part of an object, that of the object being
  initialized, to the case where the result type of the function is composite.

  RM references: 3.10.2 (10.2/5)

.. index:: AI12-0409 (Ada 2022 feature)

* *AI12-0409 Preelaborable_Initialization and bounded containers (2021-06-23)*

  As defined by this AI, the ``Preelaborable_Initializatio`` aspect now has a
  corresponding attribute of the same name. Types declared within a generic package specification are permitted to specify the expression of a ``Prelaborable_Initialization`` aspect by including one or more references to the attribute applied to a formal private or formal derived type conjoined by ``and`` operators. This permits the full type of a private type with such an aspect expression to have components of the named formal types, and such a type will have preelaborable initialization in an instance when the
  actual types for all referenced formal types have preelaborable initialization.

  RM references: 10.02.01 (4.1/2) 10.02.01 (4.2/2) 10.02.01 (11.1/2)
  10.02.01 (11.2/2) 10.02.01 (11.6/2) 10.02.01 (11.7/2) 10.02.01
  (11.8/2) 13.01 (11/3) A.18.19 (5/5) A.18.20 (5/5) A.18.21 (5/5)
  A.18.22 (5/5) A.18.23 (5/5) A.18.24 (5/5) A.18.25 (5/5) A.18.32
  (6/5) J.15.14 (0)

.. index:: AI12-0411 (Ada 2022 feature)

* *AI12-0411 Add "bool" to Interfaces.C (0000-00-00)*

  RM references: B.03 (13) B.03 (43/2) B.03 (65.1/4)

.. index:: AI12-0412 (Ada 2022 feature)

* *AI12-0412 Abstract Pre/Post'Class on primitive of abstract type (2021-05-19)*

  In Ada 2022, by AI12-0412, it's legal to specify Pre'Class and Post'Class
  aspects on nonabstract primitive subprograms of an abstract type, but if the
  expression of such an aspect is nonstatic, then it's illegal to make a nondispatching call to such a primitive, to apply ``'Access`` to it, or to pass such a primitive as an actual subprogram for a concrete formal subprogram in a generic instantiation.

  RM references: 6.01.01 (18.2/4)

.. index:: AI12-0413 (Ada 2022 feature)

* *AI12-0413 Reemergence of "=" when defined to be abstract (0000-00-00)*

  The AI clarifies rules about operator reemergence in instances, and nondispatching calls to abstract subprograms.

  RM references: 3.09.03 (7) 4.05.02 (14.1/3) 4.05.02 (24.1/3) 12.05 (8/3)

.. index:: AI12-0423 (Ada 2022 feature)

* *AI12-0423 Aspect inheritance fixups (0000-00-00)*

  Clarify that the No_Return aspect behaves as one would expect for an inherited subprogram and that inheritance works as one would expect for a multi-part aspect whose value is specified via an aggregate (e.g., the Aggregate aspect).

  RM references: 6.05.01 (3.3/3) 13.01 (15.7/5) 13.01 (15.8/5)

.. index:: AI12-0432 (Ada 2022 feature)

* *AI12-0432 View conversions of assignments and predicate checks (2021-05-05)*

  When a predicate applies to a tagged type, a view conversion to that type
  normally requires a predicate check. However, as specified by AI12-0432, when the view conversion appears as the target of an assignment, a predicate check is not applied to the object in the conversion.

  RM references: 3.02.04 (31/5) 4.06 (51.1/5)

---

### Gcc Ada Doc Gnat Rm Implementation Of Specific Ada Features (`gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst`)

.. _Implementation_of_Specific_Ada_Features:

***************************************
Implementation of Specific Ada Features
***************************************

This chapter describes the GNAT implementation of several Ada language
facilities.

.. _Machine_Code_Insertions:

Machine Code Insertions
=======================

.. index:: Machine Code insertions

Package ``Machine_Code`` provides machine code support as described
in the Ada Reference Manual 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 are closely related to the mechanism
provided by the asm instruction in the GNU C compiler.  Full understanding
and use of the facilities in this package requires understanding the asm
instruction, see the section on Extended Asm in
:title:`Using_the_GNU_Compiler_Collection_(GCC)`.

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.

Consider this C ``asm`` instruction:

::

     asm ("fsinx %1 %0" : "=f" (result) : "f" (angle));


The equivalent can be written for GNAT as:

.. code-block:: ada

  Asm ("fsinx %1 %0",
       My_Float'Asm_Output ("=f", result),
       My_Float'Asm_Input  ("f",  angle));


The first argument to ``Asm`` is the assembler template, and is
identical to what is used in GNU C.  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 (see the section on Constraints in
:title:`Using_the_GNU_Compiler_Collection_(GCC)`)
for the parameter; e.g., what kind of register is required.  The second
argument is the variable to be written or 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``.
No support is provided for GNU C's symbolic names for output parameters.

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
constraint are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
No support is provided for GNU C's symbolic names for input parameters.

If there are no input operands, 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.
In addition to registers, the special clobbers ``memory`` and
``cc`` as described in the GNU C docs are both supported.

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 in particular an instruction that has outputs
will still be generated, even if none of the outputs are
used.  See :title:`Using_the_GNU_Compiler_Collection_(GCC)`
for the full description.
Generally it is strongly advisable to use Volatile for any ASM statement
that is missing either input or output operands or to avoid unwanted
optimizations. A warning is generated if this advice is not followed.

No support is provided for GNU C's ``asm goto`` feature.

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:

.. code-block:: ada

  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``. As usual, 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 ::=
    [PREFIX.]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 ::=
    [PREFIX.]No_Input_Operands
  | INPUT_OPERAND_ATTRIBUTE
  | (INPUT_OPERAND_ATTRIBUTE {,INPUT_OPERAND_ATTRIBUTE})

  INPUT_OPERAND_ATTRIBUTE ::=
    SUBTYPE_MARK'Asm_Input (static_string_EXPRESSION, EXPRESSION)

The identifiers ``No_Input_Operands`` and ``No_Output_Operands``
are declared in the package ``Machine_Code`` and must be referenced
according to normal visibility rules. In particular if there is no
``use`` clause for this package, then appropriate package name
qualification is required.

.. _GNAT_Implementation_of_Tasking:

GNAT Implementation of Tasking
==============================

This chapter outlines the basic GNAT approach to tasking (in particular,
a multi-layered library for portability) and discusses issues related
to compliance with the Real-Time Systems Annex.

.. _Mapping_Ada_Tasks_onto_the_Underlying_Kernel_Threads:

Mapping Ada Tasks onto the Underlying Kernel Threads
----------------------------------------------------

GNAT's run-time support comprises two layers:

* GNARL (GNAT Run-time Layer)
* GNULL (GNAT Low-level Library)

In GNAT, Ada's tasking services rely on a platform and OS independent
layer known as GNARL.  This code is responsible for implementing the
correct semantics of Ada's task creation, rendezvous, protected
operations etc.

GNARL decomposes Ada's tasking semantics into simpler lower level
operations such as create a thread, set the priority of a thread,
yield, create a lock, lock/unlock, etc.  The spec for these low-level
operations constitutes GNULLI, the GNULL Interface.  This interface is
directly inspired from the POSIX real-time API.

If the underlying executive or OS implements the POSIX standard
faithfully, the GNULL Interface maps as is to the services offered by
the underlying kernel.  Otherwise, some target dependent glue code maps
the services offered by the underlying kernel to the semantics expected
by GNARL.

Whatever the underlying OS (VxWorks, UNIX, Windows, etc.) the
key point is that each Ada task is mapped on a thread in the underlying
kernel.  For example, in the case of VxWorks, one Ada task = one VxWorks task.

In addition Ada task priorities map onto the underlying thread priorities.
Mapping Ada tasks onto the underlying kernel threads has several advantages:

*
  The underlying scheduler is used to schedule the Ada tasks.  This
  makes Ada tasks as efficient as kernel threads from a scheduling
  standpoint.

*
  Interaction with code written in C containing threads is eased
  since at the lowest level Ada tasks and C threads map onto the same
  underlying kernel concept.

*
  When an Ada task is blocked during I/O the remaining Ada tasks are
  able to proceed.

*
  On multiprocessor systems Ada tasks can execute in parallel.

Some threads libraries offer a mechanism to fork a new process, with the
child process duplicating the threads from the parent.
GNAT does not
support this functionality when the parent contains more than one task.

.. index:: Forking a new process

.. _Ensuring_Compliance_with_the_Real-Time_Annex:

Ensuring Compliance with the Real-Time Annex
--------------------------------------------

.. index:: Real-Time Systems Annex compliance

Although mapping Ada tasks onto
the underlying threads has significant advantages, it does create some
complications when it comes to respecting the scheduling semantics
specified in the real-time annex (Annex D).

For instance the Annex D requirement for the ``FIFO_Within_Priorities``
scheduling policy states:

  *When the active priority of a ready task that is not running
  changes, or the setting of its base priority takes effect, the
  task is removed from the ready queue for its old active priority
  and is added at the tail of the ready queue for its new active
  priority, except in the case where the active priority is lowered
  due to the loss of inherited priority, in which case the task is
  added at the head of the ready queue for its new active priority.*

While most kernels do put tasks at the end of the priority queue when
a task changes its priority, (which respects the main
FIFO_Within_Priorities requirement), almost none keep a thread at the
beginning of its priority queue when its priority drops from the loss
of inherited priority.

As a result most vendors have provided incomplete Annex D implementations.

The GNAT run-time, has a nice cooperative solution to this problem
which ensures that accurate FIFO_Within_Priorities semantics are
respected.

The principle is as follows.  When an Ada task T is about to start
running, it checks whether some other Ada task R with the same
priority as T has been suspended due to the loss of priority
inheritance.  If this is the case, T yields and is placed at the end of
its priority queue.  When R arrives at the front of the queue it
executes.

Note that this simple scheme preserves the relative order of the tasks
that were ready to execute in the priority queue where R has been
placed at the end.

.. Support_for_Locking_Policies

Support for Locking Policies
----------------------------

This section specifies which policies specified by pragma Locking_Policy
are supported on which platforms.

GNAT supports the standard ``Ceiling_Locking`` policy, and the
implementation defined ``Inheritance_Locking`` and
``Concurrent_Readers_Locking`` policies.

``Ceiling_Locking`` is supported on all platforms if the operating system
supports it. In particular, ``Ceiling_Locking`` is not supported on
VxWorks.
``Inheritance_Locking`` is supported on
Linux,
Darwin (Mac OS X),
LynxOS 178,
and VxWorks.
``Concurrent_Readers_Locking`` is supported on Linux.

Notes about ``Ceiling_Locking`` on Linux:
If the process is running as 'root', ceiling locking is used.
If the capabilities facility is installed
("sudo apt-get --assume-yes install libcap-dev" on Ubuntu,
for example),
and the program is linked against that library
("-largs -lcap"),
and the executable file has the cap_sys_nice capability
("sudo /sbin/setcap cap_sys_nice=ep executable_file_name"),
then ceiling locking is used.
Otherwise, the ``Ceiling_Locking`` policy is ignored.

.. _GNAT_Implementation_of_Shared_Passive_Packages:

GNAT Implementation of Shared Passive Packages
==============================================

.. index:: Shared passive packages

GNAT fully implements the :index:`pragma <pragma Shared_Passive>`
``Shared_Passive`` for
the purpose of designating shared passive packages.
This allows the use of passive partitions in the
context described in the Ada Reference Manual; i.e., for communication
between separate partitions of a distributed application using the
features in Annex E.

.. index:: Annex E

.. index:: Distribution Systems Annex

However, the implementation approach used by GNAT provides for more
extensive usage as follows:

*Communication between separate programs*
  This allows separate programs to access the data in passive
  partitions, using protected objects for synchronization where
  needed. The only requirement is that the two programs have a
  common shared file system. It is even possible for programs
  running on different machines with different architectures
  (e.g., different endianness) to communicate via the data in
  a passive partition.

*Persistence between program runs*
  The data in a passive package can persist from one run of a
  program to another, so that a later program sees the final
  values stored by a previous run of the same program.

The implementation approach used is to store the data in files. A
separate stream file is created for each object in the package, and
an access to an object causes the corresponding file to be read or
written.

.. index:: SHARED_MEMORY_DIRECTORY environment variable

The environment variable ``SHARED_MEMORY_DIRECTORY`` should be
set to the directory to be used for these files.
The files in this directory
have names that correspond to their fully qualified names. For
example, if we have the package

.. code-block:: ada

  package X is
    pragma Shared_Passive (X);
    Y : Integer;
    Z : Float;
  end X;

and the environment variable is set to ``/stemp/``, then the files created
will have the names:

::

  /stemp/x.y
  /stemp/x.z


These files are created when a value is initially written to the object, and
the files are retained until manually deleted. This provides the persistence
semantics. If no file exists, it means that no partition has assigned a value
to the variable; in this case the initial value declared in the package
will be used. This model ensures that there are no issues in synchronizing
the elaboration process, since elaboration of passive packages elaborates the
initial values, but does not create the files.

The files are written using normal ``Stream_IO`` access.
If you want to be able
to communicate between programs or partitions running on different
architectures, then you should use the XDR versions of the stream attribute
routines, since these are architecture independent.

If active synchronization is required for access to the variables in the
shared passive package, then as described in the Ada Reference Manual, the
package may contain protected objects used for this purpose. In this case
a lock file (whose name is :file:`___lock`, with three underscores)
is created in the shared memory directory.

.. index:: ___lock file (for shared passive packages)

This is used to provide the required locking
semantics for proper protected object synchronization.

.. _Code_Generation_for_Array_Aggregates:

Code Generation for Array Aggregates
====================================

Aggregates have a rich syntax and allow the user to specify the values of
complex data structures by means of a single construct.  As a result, the
code generated for aggregates can be quite complex and involve loops, case
statements and multiple assignments.  In the simplest cases, however, the
compiler will recognize aggregates whose components and constraints are
fully static, and in those cases the compiler will generate little or no
executable code.  The following is an outline of the code that GNAT generates
for various aggregate constructs.  For further details, you will find it
useful to examine the output produced by the -gnatG flag to see the expanded
source that is input to the code generator.  You may also want to examine
the assembly code generated at various levels of optimization.

The code generated for aggregates depends on the context, the component values,
and the type.  In the context of an object declaration the code generated is
generally simpler than in the case of an assignment.  As a general rule, static
component values and static subtypes also lead to simpler code.

.. _Static_constant_aggregates_with_static_bounds:

Static constant aggregates with static bounds
---------------------------------------------

For the declarations:

.. code-block:: ada

      type One_Dim is array (1..10) of integer;
      ar0 : constant One_Dim := (1, 2, 3, 4, 5, 6, 7, 8, 9, 0);


GNAT generates no executable code: the constant ar0 is placed in static memory.
The same is true for constant aggregates with named associations:


.. code-block:: ada

      Cr1 : constant One_Dim := (4 => 16, 2 => 4, 3 => 9, 1 => 1, 5 .. 10 => 0);
      Cr3 : constant One_Dim := (others => 7777);


The same is true for multidimensional constant arrays such as:

.. code-block:: ada

      type two_dim is array (1..3, 1..3) of integer;
      Unit : constant two_dim := ( (1,0,0), (0,1,0), (0,0,1));


The same is true for arrays of one-dimensional arrays: the following are
static:


.. code-block:: ada

  type ar1b  is array (1..3) of boolean;
  type ar_ar is array (1..3) of ar1b;
  None  : constant ar1b := (others => false);     --  fully static
  None2 : constant ar_ar := (1..3 => None);       --  fully static


However, for multidimensional aggregates with named associations, GNAT will
generate assignments and loops, even if all associations are static.  The
following two declarations generate a loop for the first dimension, and
individual component assignments for the second dimension:


.. code-block:: ada

  Zero1: constant two_dim := (1..3 => (1..3 => 0));
  Zero2: constant two_dim := (others => (others => 0));


.. _Constant_aggregates_with_unconstrained_nominal_types:

Constant aggregates with unconstrained nominal types
----------------------------------------------------

In such cases the aggregate itself establishes the subtype, so that
associations with ``others`` cannot be used.  GNAT determines the
bounds for the actual subtype of the aggregate, and allocates the
aggregate statically as well.  No code is generated for the following:


.. code-block:: ada

      type One_Unc is array (natural range <>) of integer;
      Cr_Unc : constant One_Unc := (12,24,36);


.. _Aggregates_with_static_bounds:

Aggregates with static bounds
-----------------------------

In all previous examples the aggregate was the initial (and immutable) value
of a constant.  If the aggregate initializes a variable, then code is generated
for it as a combination of individual assignments and loops over the target
object.  The declarations


.. code-block:: ada

         Cr_Var1 : One_Dim := (2, 5, 7, 11, 0, 0, 0, 0, 0, 0);
         Cr_Var2 : One_Dim := (others > -1);


generate the equivalent of


.. code-block:: ada

         Cr_Var1 (1) := 2;
         Cr_Var1 (2) := 3;
         Cr_Var1 (3) := 5;
         Cr_Var1 (4) := 11;

         for I in Cr_Var2'range loop
            Cr_Var2 (I) := -1;
         end loop;


.. _Aggregates_with_nonstatic_bounds:

Aggregates with nonstatic bounds
---------------------------------

If the bounds of the aggregate are not statically compatible with the bounds
of the nominal subtype  of the target, then constraint checks have to be
generated on the bounds.  For a multidimensional array, constraint checks may
have to be applied to sub-arrays individually, if they do not have statically
compatible subtypes.

.. _Aggregates_in_assignment_statements:

Aggregates in assignment statements
-----------------------------------

In general, aggregate assignment requires the construction of a temporary,
and a copy from the temporary to the target of the assignment.  This is because
it is not always possible to convert the assignment into a series of individual
component assignments.  For example, consider the simple case:


.. code-block:: ada

          A := (A(2), A(1));


This cannot be converted into:


.. code-block:: ada

          A(1) := A(2);
          A(2) := A(1);


So the aggregate has to be built first in a separate location, and then
copied into the target.  GNAT recognizes simple cases where this intermediate
step is not required, and the assignments can be performed in place, directly
into the target.  The following sufficient criteria are applied:

*
  The bounds of the aggregate are static, and the associations are static.
*
  The components of the aggregate are static constants, names of
  simple variables that are not renamings, or expressions not involving
  indexed components whose operands obey these rules.

If any of these conditions are violated, the aggregate will be built in
a temporary (created either by the front-end or the code generator) and then
that temporary will be copied onto the target.

.. _The_Size_of_Discriminated_Records_with_Default_Discriminants:

The Size of Discriminated Records with Default Discriminants
============================================================

If a discriminated type ``T`` has discriminants with default values, it is
possible to declare an object of this type without providing an explicit
constraint:


.. code-block:: ada

  type Size is range 1..100;

  type Rec (D : Size := 15) is record
     Name : String (1..D);
  end T;

  Word : Rec;


Such an object is said to be *unconstrained*.
The discriminant of the object
can be modified by a full assignment to the object, as long as it preserves the
relation between the value of the discriminant, and the value of the components
that depend on it:


.. code-block:: ada

  Word := (3, "yes");

  Word := (5, "maybe");

  Word := (5, "no"); -- raises Constraint_Error

In order to support this behavior efficiently, an unconstrained object is
given the maximum size that any value of the type requires. In the case
above, ``Word`` has storage for the discriminant and for
a ``String`` of length 100.
It is important to note that unconstrained objects do not require dynamic
allocation. It would be an improper implementation to place on the heap those
components whose size depends on discriminants. (This improper implementation
was used by some Ada83 compilers, where the ``Name`` component above
would have
been stored as a pointer to a dynamic string). Following the principle that
dynamic storage management should never be introduced implicitly,
an Ada compiler should reserve the full size for an unconstrained declared
object, and place it on the stack.

This maximum size approach
has been a source of surprise to some users, who expect the default
values of the discriminants to determine the size reserved for an
unconstrained object: "If the default is 15, why should the object occupy
a larger size?"
The answer, of course, is that the discriminant may be later modified,
and its full range of values must be taken into account. This is why the
declaration:


.. code-block:: ada

  type Rec (D : Positive := 15) is record
     Name : String (1..D);
  end record;

  Too_Large : Rec;

is flagged by the compiler with a warning:
an attempt to create ``Too_Large`` will raise ``Storage_Error``,
because the required size includes ``Positive'Last``
bytes. As the first example indicates, the proper approach is to declare an
index type of 'reasonable' range so that unconstrained objects are not too
large.

One final wrinkle: if the object is declared to be ``aliased``, or if it is
created in the heap by means of an allocator, then it is *not*
unconstrained:
it is constrained by the default values of the discriminants, and those values
cannot be modified by full assignment. This is because in the presence of
aliasing all views of the object (which may be manipulated by different tasks,
say) must be consistent, so it is imperative that the object, once created,
remain invariant.

.. _Image_Values_For_Nonscalar_Types:

Image Values For Nonscalar Types
================================

Ada 2022 defines the Image, Wide_Image, and Wide_Wide image attributes
for nonscalar types; earlier Ada versions defined these attributes only
for scalar types. Ada RM 4.10 provides some general guidance regarding
the default implementation of these attributes and the GNAT compiler
follows that guidance. However, beyond that the precise details of the
image text generated in these cases are deliberately not documented and are
subject to change. In particular, users should not rely on formatting details
(such as spaces or line breaking), record field order, image values for access
types, image values for types that have ancestor or subcomponent types
declared in non-Ada2022 code, image values for predefined types, or the
compiler's choices regarding the implementation permissions described in
Ada RM 4.10. This list is not intended to be exhaustive. If more precise
control of image text is required for some type T, then T'Put_Image should be
explicitly specified.

.. _Strict_Conformance_to_the_Ada_Reference_Manual:

Strict Conformance to the Ada Reference Manual
==============================================

The dynamic semantics defined by the Ada Reference Manual impose a set of
run-time checks to be generated. By default, the GNAT compiler will insert many
run-time checks into the compiled code, including most of those required by the
Ada Reference Manual. However, there are two checks that are not enabled in
the default mode for efficiency reasons: checks for access before elaboration
on subprogram calls, and stack overflow checking (most operating systems do not
perform this check by default).

Strict conformance to the Ada Reference Manual can be achieved by adding two
compiler options for dynamic checks for access-before-elaboration on subprogram
calls and generic instantiations (*-gnatE*), and stack overflow checking
(*-fstack-check*).

Note that the result of a floating point arithmetic operation in overflow and
invalid situations, when the ``Machine_Overflows`` attribute of the result
type is ``False``, is to generate IEEE NaN and infinite values. This is the
case for machines compliant with the IEEE floating-point standard, but on
machines that are not fully compliant with this standard, such as Alpha, the
*-mieee* compiler flag must be used for achieving IEEE confirming
behavior (although at the cost of a significant performance penalty), so
infinite and NaN values are properly generated.

---

### Gcc Ada Doc Gnat Rm Interfacing To Other Languages (`gcc/ada/doc/gnat_rm/interfacing_to_other_languages.rst`)

.. _Interfacing_to_Other_Languages:

******************************
Interfacing to Other Languages
******************************

The facilities in Annex B of the Ada Reference Manual are fully
implemented in GNAT, and in addition, a full interface to C++ is
provided.

.. _Interfacing_to_C:

Interfacing to C
================

Interfacing to C with GNAT can use one of two approaches:

*
  The types in the package ``Interfaces.C`` may be used.
*
  Standard Ada types may be used directly.  This may be less portable to
  other compilers, but will work on all GNAT compilers, which guarantee
  correspondence between the C and Ada types.

Pragma ``Convention C`` may be applied to Ada types, but mostly has no
effect, since this is the default.  The following table shows the
correspondence between Ada scalar types and the corresponding C types.


======================== ==================================================================
Ada Type                 C Type
======================== ==================================================================
``Integer``              ``int``
``Short_Integer``        ``short``
``Short_Short_Integer``  ``signed char``
``Long_Integer``         ``long``
``Long_Long_Integer``    ``long long``
``Short_Float``          ``float``
``Float``                ``float``
``Long_Float``           ``double``
``Long_Long_Float``      This is the longest floating-point type supported by the hardware.
======================== ==================================================================

Additionally, there are the following general correspondences between Ada
and C types:

*
  Ada enumeration types map to C enumeration types directly if pragma
  ``Convention C`` is specified, which causes them to have a length of
  32 bits, except for boolean types which map to C99 ``bool`` and for
  which the length is 8 bits.
  Without pragma ``Convention C``, Ada enumeration types map to
  8, 16, or 32 bits (i.e., C types ``signed char``, ``short``,
  ``int``, respectively) depending on the number of values passed.
  This is the only case in which pragma ``Convention C`` affects the
  representation of an Ada type.

*
  Ada access types map to C pointers, except for the case of pointers to
  unconstrained types in Ada, which have no direct C equivalent.

*
  Ada arrays map directly to C arrays.

*
  Ada records map directly to C structures.

*
  Packed Ada records map to C structures where all members are bit fields
  of the length corresponding to the ``type'Size`` value in Ada.

.. _Interfacing_to_C++:

Interfacing to C++
==================

The interface to C++ makes use of the following pragmas, which are
primarily intended to be constructed automatically using a binding generator
tool, although it is possible to construct them by hand.

Using these pragmas it is possible to achieve complete
inter-operability between Ada tagged types and C++ class definitions.
See :ref:`Implementation_Defined_Pragmas`, for more details.

:samp:`pragma CPP_Class ([Entity =>] {LOCAL_NAME})`
  The argument denotes an entity in the current declarative region that is
  declared as a tagged or untagged record type. It indicates that the type
  corresponds to an externally declared C++ class type, and is to be laid
  out the same way that C++ would lay out the type.

  Note: Pragma ``CPP_Class`` is currently obsolete. It is supported
  for backward compatibility but its functionality is available
  using pragma ``Import`` with ``Convention`` = ``CPP``.


:samp:`pragma CPP_Constructor ([Entity =>] {LOCAL_NAME})`
  This pragma identifies an imported function (imported in the usual way
  with pragma ``Import``) as corresponding to a C++ constructor.

A few restrictions are placed on the use of the ``Access`` attribute
in conjunction with subprograms subject to convention ``CPP``: the
attribute may be used neither on primitive operations of a tagged
record type with convention ``CPP``, imported or not, nor on
subprograms imported with pragma ``CPP_Constructor``.

In addition, C++ exceptions are propagated and can be handled in an
``others`` choice of an exception handler. The corresponding Ada
occurrence has no message, and the simple name of the exception identity
contains ``Foreign_Exception``. Finalization and awaiting dependent
tasks works properly when such foreign exceptions are propagated.

It is also possible to import a C++ exception using the following syntax:


::

  LOCAL_NAME : exception;
  pragma Import (Cpp,
    [Entity =>] LOCAL_NAME,
    [External_Name =>] static_string_EXPRESSION);


The ``External_Name`` is the name of the C++ RTTI symbol. You can then
cover a specific C++ exception in an exception handler. If the string
ends with "'Class", as if referencing the Class attribute of the C++
type, that enables "class-wide" type matching, i.e., instances of C++
classes derived from the one denoted by the RTTI symbol, that would be
caught by C++ handlers for that type, will also be caught by Ada
handlers for ``Entity``. For non-class-wide RTTI symbols imported from
C++, only exact type matches will be handled. C++ rethrown (dependent)
exceptions are not distinguishable from the corresponding primary
exceptions: they are handled exactly as if the primary exception had
been raised.

With imported exceptions, especially with base-type matching, a single
handled_sequence_of_statements may have exception handlers with
choices that cover the same C++ types in ways that GNAT cannot detect.
For example, C++ classes ``base`` and ``derived`` may be imported as
exceptions with base-type matching, but GNAT does not know that they
are related by inheritance, only the runtime will know it. Given:

::

   exception
     when Derived_Exception => null;
     when Base_Exception => null;
     when others => null;

the earliest handler that matches the type of the raised object will
be selected. If an instance of ``derived`` or a further derived type
is raised, the first handler will be used; if an instance of ``base``
that is not an instance of ``derived`` is raised, the second handler
will be used; raised objects that are not instances of ``base`` will
be handled by the ``others`` handler. However, if the handlers were
reordered (``others`` must remain last), the ``Derived_Exception``
handler would never be used, because ``Base_Exception`` would match
any instances of ``derived`` before ``Derived_Exception`` or
``others`` handlers were considered. Mixing exact-type and base-type
matching exceptions may also involve overlapping handlers that GNAT
will not reject: an exact-type ``Base_Only_Exception`` handler placed
before ``Base_Exception`` will handle instances of ``base``, whereas
instances of derived types will be handled by
``Base_Exception``. Swapping them will cause ``Base_Exception`` to
handle all instances of ``base`` and derived types, so that a
subsequent handler for ``Base_Only_Exception`` will never be selected.

The C++ object associated with a C++ ``Exception_Occurrence`` may be
obtained by calling the ``GNAT.CPP_Exceptions.Get_Object_Address``
function. There are convenience generic wrappers named ``Get_Object``,
``Get_Access_To_Object``, and ``Get_Access_To_Tagged_Object``,
parameterized on the expected Ada type. Note that, for exceptions
imported from C++, the address of the object is that of the subobject
of the type associated with the exception, which may have a different
address from that of the full object; for C++ exceptions handled by
``others`` handlers, however, the address of the full object is
returned.

E.g., if the imported exception uses the RTTI symbol for the base
class, followed by "'Class", and the C++ code raises (throws) an
instance of a derived class, a handler for that imported exception
will catch this ``Exception_Occurrence``, and ``Get_Object_Address``
will return the address of the base subobject of the raised derived
object; ``Get_Object``, ``Get_Access_To_Object`` and
``Get_Access_To_Tagged_Object`` only convert that address to the
parameterized type, so the specified type ought to be a type that
imports the C++ type whose RTTI symbol was named in the declared
exception, i.e., base, not derived or any other type. GNAT cannot
detect or report if a type is named that does not match the handler's
RTTI-specified type.

For ``others`` handlers, and for exact type matches, the full object
is obtained. The ``Get_Type_Info`` function that takes an
``Exception_Occurrence`` argument can be used to verify the type of
the C++ object raised as an exception. The other ``Get_Type_Info``
function, that takes an ``Exception_Id``, obtains the type expected by
the handler, and no such type exists for ``others`` handlers.
``GNAT.CPP.Std.Name`` can then convert the opaque
``GNAT.CPP.Std.Type_Info_Ptr`` access to ``std::type_info`` objects,
returned by either ``Get_Type_Info`` function, to a C++ mangled type
name.

If an ``Exception_Occurrence`` was raised from C++, or following C++
conventions, ``GNAT.Exception_Actions.Exception_Language`` will return
``EL_Cpp``, whether the exception handler is an imported C++ exception
or ``others``. ``GNAT.Exception_Actions.Is_Foreign_Exception`` returns
True for all of these, as well as for any case in which
``Exception_Language`` is not ``EL_Ada``.

::

    --  Given the following partial package specification:

      Base_Exception : exception;
      pragma Import (Cpp, Base_Exception, "_ZTI4base'Class");
      --  Handle instances of base, and of subclasses.

      type Base is limited tagged record
	[...]
      end record;
      pragma Import (Cpp, Base);

      type Derived is limited tagged record
	[...]
      end record;
      pragma Import (Cpp, Derived);

      type Unrelated is access procedure (B : Boolean);

      function Get_Base_Obj_Acc is
	new Get_Access_To_Tagged_Object (Base);
      function Get_Derived_Obj_Acc is
	new Get_Access_To_Tagged_Object (Derived);
      function Get_Unrelated_Obj_Acc is
	new Get_Access_To_Object (Unrelated);

      procedure Raise_Derived;
      --  Raises an instance of derived (with a base subobject).


    --  The comments next to each statement indicate the behavior of
    --  the following pseudocode blocks:

    begin
      Raise_Derived;
    exception
      when BEx : Base_Exception =>
	?? := Is_Foreign_Exception (BEx);  --  True
	?? := Exception_Language (BEx);    --  EL_Cpp
	?? := Name (Get_Type_Info (BEx));  --  "7derived"
	?? := Name (Get_Type_Info (Exception_Identity (BEx)));  --  "4base"
	?? := Get_Object_Address (BEx);    --  base subobject in derived object
	?? := Get_Base_Obj_Acc (BEx):      --  ditto, as access to Base
	?? := Get_Derived_Obj_Acc (BEx):   --  ditto, NO ERROR DETECTED!
	?? := Get_Unrelated_Obj_Acc (BEx): --  ditto, NO ERROR DETECTED!
    end;


    begin
      Raise_Derived;
    exception
      when BEx : others =>
	?? := Is_Foreign_Exception (BEx);  --  True
	?? := Exception_Language (BEx);    --  EL_Cpp
	?? := Name (Get_Type_Info (BEx));  --  "7derived"
	?? := Get_Type_Info (Exception_Identity (BEx));  --  null
	?? := Get_Object_Address (BEx);    --  full derived object
	?? := Get_Derived_Obj_Acc (BEx):   --  ditto, as access to Derived
	?? := Get_Base_Obj_Acc (BEx):      --  ditto, NO ERROR DETECTED!
	?? := Get_Unrelated_Obj_Acc (BEx): --  ditto, NO ERROR DETECTED!
    end;

The calls marked with ``NO ERROR DETECTED!`` will compile successfully,
even though the types specified in the specializations of the generic
function do not match the type of the exception object that the
function is expected to return. Mismatches between derived and base
types are particularly relevant because they will appear to work as
long as there isn't any offset between pointers to these types. This
may hold in many cases, but is subject to change with various possible
changes to the derived class.

The ``GNAT.CPP.Std`` package offers interfaces corresponding to the
C++ standard type ``std::type_info``. Function ``To_Type_Info_Ptr``
builds an opaque ``Type_Info_Ptr`` to reference a ``std::type_info``
object at a given ``System.Address``.


.. _Interfacing_to_COBOL:

Interfacing to COBOL
====================

Interfacing to COBOL is achieved as described in section B.4 of
the Ada Reference Manual.

.. _Interfacing_to_Fortran:

Interfacing to Fortran
======================

Interfacing to Fortran is achieved as described in section B.5 of the
Ada Reference Manual.  The pragma ``Convention Fortran``, applied to a
multi-dimensional array causes the array to be stored in column-major
order as required for convenient interface to Fortran.

.. _Interfacing_to_non-GNAT_Ada_code:

Interfacing to non-GNAT Ada code
================================

It is possible to specify the convention ``Ada`` in a pragma
``Import`` or pragma ``Export``.  However this refers to
the calling conventions used by GNAT, which may or may not be
similar enough to those used by some other Ada 83 / Ada 95 / Ada 2005
compiler to allow interoperation.

If arguments types are kept simple, and if the foreign compiler generally
follows system calling conventions, then it may be possible to integrate
files compiled by other Ada compilers, provided that the elaboration
issues are adequately addressed (for example by eliminating the
need for any load time elaboration).

In particular, GNAT running on VMS is designed to
be highly compatible with the DEC Ada 83 compiler, so this is one
case in which it is possible to import foreign units of this type,
provided that the data items passed are restricted to simple scalar
values or simple record types without variants, or simple array
types with fixed bounds.

---

### Gcc Ada Doc Gnat Rm Intrinsic Subprograms (`gcc/ada/doc/gnat_rm/intrinsic_subprograms.rst`)

.. _Intrinsic_Subprograms:

*********************
Intrinsic Subprograms
*********************

.. index:: Intrinsic Subprograms

GNAT allows a user application program to write the declaration:


.. code-block:: ada

     pragma Import (Intrinsic, name);


providing that the name corresponds to one of the implemented intrinsic
subprograms in GNAT, and that the parameter profile of the referenced
subprogram meets the requirements.  This chapter describes the set of
implemented intrinsic subprograms, and the requirements on parameter profiles.
Note that no body is supplied; as with other uses of pragma Import, the
body is supplied elsewhere (in this case by the compiler itself).  Note
that any use of this feature is potentially non-portable, since the
Ada standard does not require Ada compilers to implement this feature.

.. _Intrinsic_Operators:

Intrinsic Operators
===================

.. index:: Intrinsic operator

All the predefined numeric operators in package Standard
in ``pragma Import (Intrinsic,..)``
declarations.  In the binary operator case, the operands must have the same
size.  The operand or operands must also be appropriate for
the operator.  For example, for addition, the operands must
both be floating-point or both be fixed-point, and the
right operand for ``"**"`` must have a root type of
``Standard.Integer'Base``.
You can use an intrinsic operator declaration as in the following example:


.. code-block:: ada

     type Int1 is new Integer;
     type Int2 is new Integer;

     function "+" (X1 : Int1; X2 : Int2) return Int1;
     function "+" (X1 : Int1; X2 : Int2) return Int2;
     pragma Import (Intrinsic, "+");


This declaration would permit 'mixed mode' arithmetic on items
of the differing types ``Int1`` and ``Int2``.
It is also possible to specify such operators for private types, if the
full views are appropriate arithmetic types.

.. _Compilation_ISO_Date:

Compilation_ISO_Date
====================

.. index:: Compilation_ISO_Date

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.Compilation_ISO_Date`` to obtain the date of
the current compilation (in local time format YYYY-MM-DD).

.. _Compilation_Date:

Compilation_Date
================

.. index:: Compilation_Date

Same as Compilation_ISO_Date, except the string is in the form
MMM DD YYYY.

.. _Compilation_Time:

Compilation_Time
================

.. index:: Compilation_Time

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.Compilation_Time`` to obtain the time of
the current compilation (in local time format HH:MM:SS).

.. _Enclosing_Entity:

Enclosing_Entity
================

.. index:: Enclosing_Entity

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.Enclosing_Entity`` to obtain the name of
the current subprogram, package, task, entry, or protected subprogram.

.. _Exception_Information:

Exception_Information
=====================

.. index:: Exception_Information'

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Current_Exception``.  The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
``GNAT.Current_Exception.Exception_Information`` to obtain
the exception information associated with the current exception.

.. _Exception_Message:

Exception_Message
=================

.. index:: Exception_Message

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Current_Exception``.  The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
``GNAT.Current_Exception.Exception_Message`` to obtain
the message associated with the current exception.

.. _Exception_Name:

Exception_Name
==============

.. index:: Exception_Name

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Current_Exception``.  The only useful
use of the intrinsic import in this case is the one in this unit,
so an application program should simply call the function
``GNAT.Current_Exception.Exception_Name`` to obtain
the name of the current exception.

.. _File:

File
====

.. index:: File

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.File`` to obtain the name of the current
file.

.. _Line:

Line
====

.. index:: Line

This intrinsic subprogram is used in the implementation of the
library package ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.Line`` to obtain the number of the current
source line.

.. _Shifts_and_Rotates:

Shifts and Rotates
==================

.. index:: Shift_Left

.. index:: Shift_Right

.. index:: Shift_Right_Arithmetic

.. index:: Rotate_Left

.. index:: Rotate_Right

In standard Ada, the shift and rotate functions are available only
for the predefined modular types in package ``Interfaces``.  However, in
GNAT it is possible to define these functions for any integer
type (signed or modular), as in this example:


.. code-block:: ada

     function Shift_Left
       (Value  : T;
        Amount : Natural) return T
     with Import, Convention => Intrinsic;


The function name must be one of
Shift_Left, Shift_Right, Shift_Right_Arithmetic, Rotate_Left, or
Rotate_Right. T must be an integer type. T'Size must be
8, 16, 32 or 64 bits; if T is modular, the modulus
must be 2**8, 2**16, 2**32 or 2**64.
The result type must be the same as the type of ``Value``.
The shift amount must be Natural.
The formal parameter names can be anything.

A more convenient way of providing these shift operators is to use the
Provide_Shift_Operators pragma, which provides the function declarations and
corresponding pragma Import's for all five shift functions. For signed types
the semantics of these operators is to interpret the bitwise result of the
corresponding operator for modular type. In particular, shifting a negative
number may change its sign bit to positive.

.. _Source_Location:

Source_Location
===============

.. index:: Source_Location

This intrinsic subprogram is used in the implementation of the
library routine ``GNAT.Source_Info``.  The only useful use of the
intrinsic import in this case is the one in this unit, so an
application program should simply call the function
``GNAT.Source_Info.Source_Location`` to obtain the current
source file location.

---

### Gcc Ada Doc Gnat Rm Obsolescent Features (`gcc/ada/doc/gnat_rm/obsolescent_features.rst`)

.. _Obsolescent_Features:

********************
Obsolescent Features
********************

This chapter describes features that are provided by GNAT, but are
considered obsolescent since there are other, more appropriate, ways
of achieving the same effect. These features are provided solely for
historical compatibility purposes.

.. _polyORB:

PolyORB
========

PolyORB is a deprecated product. It will be baselined with the GNAT Pro
release 28. After this release, there will be no new versions of this
product. Contact AdaCore support to get recommendations for replacements.

.. _pragma_No_Run_Time:

pragma No_Run_Time
==================

The pragma ``No_Run_Time`` is used to achieve an affect similar
to the use of the "Zero Foot Print" configurable run time, but without
requiring a specially configured run time. The result of using this
pragma, which must be used for all units in a partition, is to restrict
the use of any language features requiring run-time support code. The
preferred usage is to use an appropriately configured run-time that
includes just those features that are to be made accessible.

.. _pragma_Ravenscar:

pragma Ravenscar
================

The pragma ``Ravenscar`` has exactly the same effect as pragma
``Profile (Ravenscar)``. The latter usage is preferred since it
is part of the new Ada 2005 standard.

.. _pragma_Restricted_Run_Time:

pragma Restricted_Run_Time
==========================

The pragma ``Restricted_Run_Time`` has exactly the same effect as
pragma ``Profile (Restricted)``. The latter usage is
preferred since the Ada 2005 pragma ``Profile`` is intended for
this kind of implementation dependent addition.

.. _pragma_Task_Info:

pragma Task_Info
================

The functionality provided by pragma ``Task_Info`` is now part of the
Ada language. The ``CPU`` aspect and the package
``System.Multiprocessors`` offer a less system-dependent way to specify
task affinity or to query the number of processors.

Syntax

.. code-block:: ada

  pragma Task_Info (EXPRESSION);

This pragma appears within a task definition (like pragma
``Priority``) and applies to the task in which it appears.  The
argument must be of type ``System.Task_Info.Task_Info_Type``.
The ``Task_Info`` pragma provides system dependent control over
aspects of tasking implementation, for example, the ability to map
tasks to specific processors.  For details on the facilities available
for the version of GNAT that you are using, see the documentation
in the spec of package System.Task_Info in the runtime
library.

.. _package_System_Task_Info:

package System.Task_Info (:file:`s-tasinf.ads`)
===============================================

This package provides target dependent functionality that is used
to support the ``Task_Info`` pragma. The predefined Ada package
``System.Multiprocessors`` and the ``CPU`` aspect now provide a
standard replacement for GNAT's ``Task_Info`` functionality.

.. raw:: latex

    \appendix

---

### Gcc Ada Doc Gnat Rm Representation Clauses And Pragmas (`gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst`)

.. role:: switch(samp)

.. role:: ada(code)
   :language: ada

.. _Representation_Clauses_and_Pragmas:

**********************************
Representation Clauses and Pragmas
**********************************

.. index:: Representation Clauses

.. index:: Representation Clause

.. index:: Representation Pragma

.. index:: Pragma, representation

This section describes the representation clauses accepted by GNAT, and
their effect on the representation of corresponding data objects.

GNAT fully implements Annex C (Systems Programming).  This means that all
the implementation advice sections in chapter 13 are fully implemented.
However, these sections only require a minimal level of support for
representation clauses.  GNAT provides much more extensive capabilities,
and this section describes the additional capabilities provided.

.. _Alignment_Clauses:

Alignment Clauses
=================

.. index:: Alignment Clause

GNAT requires that all alignment clauses specify 0 or a power of 2, and
all default alignments are always a power of 2. Specifying 0 is the
same as specifying 1.

The default alignment values are as follows:

* *Elementary Types*.

  For elementary types, the alignment is the minimum of the actual size of
  objects of the type divided by ``Storage_Unit``,
  and the maximum default alignment supported by the target.
  (This maximum default alignment is given by the GNAT-specific attribute
  ``Standard'Maximum_Alignment``; see :ref:`Attribute_Maximum_Alignment`.)

  .. index:: Maximum_Alignment attribute

  For example, for type ``Long_Float``, the object size is 8 bytes, and the
  default alignment will be 8 on any target that supports alignments
  this large, but on some targets, the maximum alignment may be smaller
  than 8, in which case objects of type ``Long_Float`` will be maximally
  aligned.

* *Arrays*.

  For arrays, the alignment is equal to the alignment of the component type
  for the normal case where no packing or component size is given.  If the
  array is packed, and the packing is effective (see separate section on
  packed arrays), then the alignment will be either 4, 2, or 1 for long packed
  arrays or arrays whose length is not known at compile time, depending on
  whether the component size is divisible by 4, 2, or is odd.  For short packed
  arrays, which are handled internally as modular types, the alignment
  will be as described for elementary types, e.g. a packed array of length
  31 bits will have an object size of four bytes, and an alignment of 4.

* *Records*.

  For the normal unpacked case, the alignment of a record is equal to
  the maximum alignment of any of its components.  For tagged records, this
  includes the implicit access type used for the tag.  If a pragma ``Pack``
  is used and all components are packable (see separate section on pragma
  ``Pack``), then the resulting alignment is 1, unless the layout of the
  record makes it profitable to increase it.

  A special case is when:

  * the size of the record is given explicitly, or a
    full record representation clause is given, and

  * the size of the record is 2, 4, or 8 bytes.

  In this case, an alignment is chosen to match the
  size of the record. For example, if we have:

  .. code-block:: ada

       type Small is record
          A, B : Character;
       end record;
       for Small'Size use 16;

  then the default alignment of the record type ``Small`` is 2, not 1. This
  leads to more efficient code when the record is treated as a unit, and also
  allows the type to specified as ``Atomic`` on architectures requiring
  strict alignment.

An alignment clause may specify a larger alignment than the default value
up to some maximum value dependent on the target. It may also specify
a smaller alignment than the default value for enumeration, integer and
fixed point types, as well as for record types, for example

.. code-block:: ada

    type V is record
       A : Integer;
    end record;

    for V'alignment use 1;

.. index:: Alignment, default

The default alignment for the type ``V`` is 4, as a result of the
Integer field in the record, but it is permissible, as shown, to
override the default alignment of the record with a smaller value.

.. index:: Alignment, subtypes

Note that according to the Ada standard, an alignment clause applies only
to the first named subtype. If additional subtypes are declared, then the
compiler is allowed to choose any alignment it likes, and there is no way
to control this choice. Consider:

.. code-block:: ada

     type R is range 1 .. 10_000;
     for R'Alignment use 1;
     subtype RS is R range 1 .. 1000;

The alignment clause specifies an alignment of 1 for the first named subtype
``R`` but this does not necessarily apply to ``RS``. When writing
portable Ada code, you should avoid writing code that explicitly or
implicitly relies on the alignment of such subtypes.

For the GNAT compiler, if an explicit alignment clause is given, this
value is also used for any subsequent subtypes. So for GNAT, in the
above example, you can count on the alignment of ``RS`` being 1. But this
assumption is non-portable, and other compilers may choose different
alignments for the subtype ``RS``.

.. _Size_Clauses:

Size Clauses
============

.. index:: Size Clause

The default size for a type ``T`` is obtainable through the
language-defined attribute ``T'Size`` and also through the
equivalent GNAT-defined attribute ``T'Value_Size``.
For objects of type ``T``, GNAT will generally increase the type size
so that the object size (obtainable through the GNAT-defined attribute
``T'Object_Size``)
is a multiple of ``T'Alignment * Storage_Unit``.

For example:

.. code-block:: ada

     type Smallint is range 1 .. 6;

     type Rec is record
        Y1 : integer;
        Y2 : boolean;
     end record;

In this example, ``Smallint'Size`` = ``Smallint'Value_Size`` = 3,
as specified by the RM rules,
but objects of this type will have a size of 8
(``Smallint'Object_Size`` = 8),
since objects by default occupy an integral number
of storage units.  On some targets, notably older
versions of the Digital Alpha, the size of stand
alone objects of this type may be 32, reflecting
the inability of the hardware to do byte load/stores.

Similarly, the size of type ``Rec`` is 40 bits
(``Rec'Size`` = ``Rec'Value_Size`` = 40), but
the alignment is 4, so objects of this type will have
their size increased to 64 bits so that it is a multiple
of the alignment (in bits).  This decision is
in accordance with the specific Implementation Advice in RM 13.3(43):

   "A ``Size`` clause should be supported for an object if the specified
   ``Size`` is at least as large as its subtype's ``Size``, and corresponds
   to a size in storage elements that is a multiple of the object's
   ``Alignment`` (if the ``Alignment`` is nonzero)."

An explicit size clause may be used to override the default size by
increasing it.  For example, if we have:

.. code-block:: ada

     type My_Boolean is new Boolean;
     for My_Boolean'Size use 32;

then values of this type will always be 32-bit long.  In the case of discrete
types, the size can be increased up to 64 bits on 32-bit targets and 128 bits
on 64-bit targets, with the effect that the entire specified field is used to
hold the value, sign- or zero-extended as appropriate.  If more than 64 bits
or 128 bits resp. is specified, then padding space is allocated after the
value, and a warning is issued that there are unused bits.

Similarly the size of records and arrays may be increased, and the effect
is to add padding bits after the value.  This also causes a warning message
to be generated.

The largest Size value permitted in GNAT is 2**31-1.  Since this is a
Size in bits, this corresponds to an object of size 256 megabytes (minus
one).  This limitation is true on all targets.  The reason for this
limitation is that it improves the quality of the code in many cases
if it is known that a Size value can be accommodated in an object of
type Integer.


.. _Storage_Size_Clauses:

Storage_Size Clauses
====================

.. index:: Storage_Size Clause

For tasks, the ``Storage_Size`` clause specifies the amount of space
to be allocated for the task stack.  This cannot be extended, and if the
stack is exhausted, then ``Storage_Error`` will be raised (if stack
checking is enabled).  Use a ``Storage_Size`` attribute definition clause,
or a ``Storage_Size`` pragma in the task definition to set the
appropriate required size.  A useful technique is to include in every
task definition a pragma of the form:

.. code-block:: ada

     pragma Storage_Size (Default_Stack_Size);

Then ``Default_Stack_Size`` can be defined in a global package, and
modified as required. Any tasks requiring stack sizes different from the
default can have an appropriate alternative reference in the pragma.

You can also use the *-d* binder switch to modify the default stack
size.

For access types, the ``Storage_Size`` clause specifies the maximum
space available for allocation of objects of the type.  If this space is
exceeded then ``Storage_Error`` will be raised by an allocation attempt.
In the case where the access type is declared local to a subprogram, the
use of a ``Storage_Size`` clause triggers automatic use of a special
predefined storage pool (``System.Pool_Size``) that ensures that all
space for the pool is automatically reclaimed on exit from the scope in
which the type is declared.

A special case recognized by the compiler is the specification of a
``Storage_Size`` of zero for an access type.  This means that no
items can be allocated from the pool, and this is recognized at compile
time, and all the overhead normally associated with maintaining a fixed
size storage pool is eliminated.  Consider the following example:

.. code-block:: ada

     procedure p is
        type R is array (Natural) of Character;
        type P is access all R;
        for P'Storage_Size use 0;
        --  Above access type intended only for interfacing purposes

        y : P;

        procedure g (m : P);
        pragma Import (C, g);

        --  ...

     begin
        --  ...
        y := new R;
     end;

As indicated in this example, these dummy storage pools are often useful in
connection with interfacing where no object will ever be allocated.  If you
compile the above example, you get the warning:

::

     p.adb:16:09: warning: allocation from empty storage pool
     p.adb:16:09: warning: Storage_Error will be raised at run time


Of course in practice, there will not be any explicit allocators in the
case of such an access declaration.

.. _Size_of_Variant_Record_Objects:

Size of Variant Record Objects
==============================

.. index:: Size, variant record objects

.. index:: Variant record objects, size

In the case of variant record objects, there is a question whether Size gives
information about a particular variant, or the maximum size required
for any variant.  Consider the following program

.. code-block:: ada

  with Text_IO; use Text_IO;
  procedure q is
     type R1 (A : Boolean := False) is record
       case A is
         when True  => X : Character;
         when False => null;
       end case;
     end record;

     V1 : R1 (False);
     V2 : R1;

  begin
     Put_Line (Integer'Image (V1'Size));
     Put_Line (Integer'Image (V2'Size));
  end q;

Here we are dealing with a variant record, where the True variant
requires 16 bits, and the False variant requires 8 bits.
In the above example, both V1 and V2 contain the False variant,
which is only 8 bits long.  However, the result of running the
program is:

::

  8
  16

The reason for the difference here is that the discriminant value of
V1 is fixed, and will always be False.  It is not possible to assign
a True variant value to V1, therefore 8 bits is sufficient.  On the
other hand, in the case of V2, the initial discriminant value is
False (from the default), but it is possible to assign a True
variant value to V2, therefore 16 bits must be allocated for V2
in the general case, even fewer bits may be needed at any particular
point during the program execution.

As can be seen from the output of this program, the ``'Size``
attribute applied to such an object in GNAT gives the actual allocated
size of the variable, which is the largest size of any of the variants.
The Ada Reference Manual is not completely clear on what choice should
be made here, but the GNAT behavior seems most consistent with the
language in the RM.

In some cases, it may be desirable to obtain the size of the current
variant, rather than the size of the largest variant.  This can be
achieved in GNAT by making use of the fact that in the case of a
subprogram parameter, GNAT does indeed return the size of the current
variant (because a subprogram has no way of knowing how much space
is actually allocated for the actual).

Consider the following modified version of the above program:

.. code-block:: ada

  with Text_IO; use Text_IO;
  procedure q is
     type R1 (A : Boolean := False) is record
       case A is
         when True  => X : Character;
         when False => null;
       end case;
     end record;

     V2 : R1;

     function Size (V : R1) return Integer is
     begin
        return V'Size;
     end Size;

  begin
     Put_Line (Integer'Image (V2'Size));
     Put_Line (Integer'Image (Size (V2)));
     V2 := (True, 'x');
     Put_Line (Integer'Image (V2'Size));
     Put_Line (Integer'Image (Size (V2)));
  end q;

The output from this program is

::

  16
  8
  16
  16

Here we see that while the ``'Size`` attribute always returns
the maximum size, regardless of the current variant value, the
``Size`` function does indeed return the size of the current
variant value.


.. _Biased_Representation:

Biased Representation
=====================

.. index:: Size for biased representation

.. index:: Biased representation

In the case of scalars with a range starting at other than zero, it is
possible in some cases to specify a size smaller than the default minimum
value, and in such cases, GNAT uses an unsigned biased representation,
in which zero is used to represent the lower bound, and successive values
represent successive values of the type.

For example, suppose we have the declaration:

.. code-block:: ada

     type Small is range -7 .. -4;
     for Small'Size use 2;

Although the default size of type ``Small`` is 4, the ``Size``
clause is accepted by GNAT and results in the following representation
scheme:

::

    -7 is represented as 2#00#
    -6 is represented as 2#01#
    -5 is represented as 2#10#
    -4 is represented as 2#11#

Biased representation is only used if the specified ``Size`` clause
cannot be accepted in any other manner.  These reduced sizes that force
biased representation can be used for all discrete types except for
enumeration types for which a representation clause is given.


.. _Value_Size_and_Object_Size_Clauses:

Value_Size and Object_Size Clauses
==================================

.. index:: Value_Size
.. index:: Object_Size
.. index:: Size, of objects

In Ada 95 and Ada 2005, ``T'Size`` for a type ``T`` is the minimum
number of bits required to hold values of type ``T``.
Although this interpretation was allowed in Ada 83, it was not required,
and this requirement in practice can cause some significant difficulties.
For example, in most Ada 83 compilers, ``Natural'Size`` was 32.
However, in Ada 95 and Ada 2005,
``Natural'Size`` is
typically 31.  This means that code may change in behavior when moving
from Ada 83 to Ada 95 or Ada 2005.  For example, consider:

.. code-block:: ada

     type Rec is record
        A : Natural;
        B : Natural;
     end record;

     for Rec use record
        A at 0 range 0 .. Natural'Size - 1;
        B at 0 range Natural'Size .. 2 * Natural'Size - 1;
     end record;

In the above code, since the typical size of ``Natural`` objects
is 32 bits and ``Natural'Size`` is 31, the above code can cause
unexpected inefficient packing in Ada 95 and Ada 2005, and in general
there are cases where the fact that the object size can exceed the
size of the type causes surprises.

To help get around this problem GNAT provides two implementation
defined attributes, ``Value_Size`` and ``Object_Size``.  When
applied to a type, these attributes yield the size of the type
(corresponding to the RM defined size attribute), and the size of
objects of the type respectively.

The ``Object_Size`` is used for determining the default size of
objects and components.  This size value can be referred to using the
``Object_Size`` attribute.  The phrase 'is used' here means that it is
the basis of the determination of the size.  The backend is free to
pad this up if necessary for efficiency, e.g., an 8-bit stand-alone
character might be stored in 32 bits on a machine with no efficient
byte access instructions such as the Alpha.

The default rules for the value of ``Object_Size`` for
discrete types are as follows:

*
  The ``Object_Size`` for base subtypes reflect the natural hardware
  size in bits (run the compiler with *-gnatS* to find those values
  for numeric types). Enumeration types and fixed-point base subtypes have
  8, 16, 32, or 64 bits for this size, depending on the range of values
  to be stored.

*
  The ``Object_Size`` of a subtype is the same as the
  ``Object_Size`` of
  the type from which it is obtained.

*
  The ``Object_Size`` of a derived base type is copied from the parent
  base type, and the ``Object_Size`` of a derived first subtype is copied
  from the parent first subtype.

The ``Value_Size`` attribute
is the (minimum) number of bits required to store a value
of the type.
This value is used to determine how tightly to pack
records or arrays with components of this type, and also affects
the semantics of unchecked conversion (unchecked conversions where
the ``Value_Size`` values differ generate a warning, and are potentially
target dependent).

The default rules for the value of ``Value_Size`` are as follows:

*
  The ``Value_Size`` for a base subtype is the minimum number of bits
  required to store all values of the type (including the sign bit
  only if negative values are possible).

*
  If a subtype statically matches the first subtype of a given type, then it has
  by default the same ``Value_Size`` as the first subtype.  (This is a
  consequence of RM 13.1(14): "if two subtypes statically match,
  then their subtype-specific aspects are the same".)

*
  All other subtypes have a ``Value_Size`` corresponding to the minimum
  number of bits required to store all values of the subtype.  For
  dynamic bounds, it is assumed that the value can range down or up
  to the corresponding bound of the ancestor

The RM defined attribute ``Size`` corresponds to the
``Value_Size`` attribute.

The ``Size`` attribute may be defined for a first-named subtype.  This sets
the ``Value_Size`` of
the first-named subtype to the given value, and the
``Object_Size`` of this first-named subtype to the given value padded up
to an appropriate boundary.  It is a consequence of the default rules
above that this ``Object_Size`` will apply to all further subtypes.  On the
other hand, ``Value_Size`` is affected only for the first subtype, any
dynamic subtypes obtained from it directly, and any statically matching
subtypes.  The ``Value_Size`` of any other static subtypes is not affected.

``Value_Size`` and
``Object_Size`` may be explicitly set for any subtype using
an attribute definition clause.  Note that the use of these attributes
can cause the RM 13.1(14) rule to be violated.  If two access types
reference aliased objects whose subtypes have differing ``Object_Size``
values as a result of explicit attribute definition clauses, then it
is illegal to convert from one access subtype to the other. For a more
complete description of this additional legality rule, see the
description of the ``Object_Size`` attribute.

To get a feel for the difference, consider the following examples (note
that in each case the base is ``Short_Short_Integer`` with a size of 8):

+------------------------------------------------+-------------+-------------+
|Type or subtype declaration                     | Object_Size |   Value_Size|
+================================================+=============+=============+
|:ada:`type X1 is range 0 .. 5;`                 |  8          |    3        |
+------------------------------------------------+-------------+-------------+
|:ada:`type X2 is range 0 .. 5;                  | 16          |   12        |
|for X2'Size use 12;`                            |             |             |
+------------------------------------------------+-------------+-------------+
|:ada:`subtype X3 is X2 range 0 .. 3;`           | 16          |    2        |
+------------------------------------------------+-------------+-------------+
|:ada:`subtype X4 is X2'Base range 0 .. 10;`     |  8          |    4        |
+------------------------------------------------+-------------+-------------+
|:ada:`Dynamic : X2'Base range -64 .. +63;`      |             |             |
+------------------------------------------------+-------------+-------------+
|:ada:`subtype X5 is X2 range 0 .. Dynamic;`     | 16          |    3*       |
+------------------------------------------------+-------------+-------------+
|:ada:`subtype X6 is X2'Base range 0 .. Dynamic;`|  8          |    7*       |
+------------------------------------------------+-------------+-------------+

Note: the entries marked '*' are not actually specified by the Ada
Reference Manual, which has nothing to say about size in the dynamic
case. What GNAT does is to allocate sufficient bits to accommodate any
possible dynamic values for the bounds at run-time.

So far, so good, but GNAT has to obey the RM rules, so the question is
under what conditions must the RM ``Size`` be used.
The following is a list
of the occasions on which the RM ``Size`` must be used:

*
  Component size for packed arrays or records

*
  Value of the attribute ``Size`` for a type

*
  Warning about sizes not matching for unchecked conversion

For record types, the ``Object_Size`` is always a multiple of the
alignment of the type (this is true for all types). In some cases the
``Value_Size`` can be smaller. Consider:


.. code-block:: ada

     type R is record
       X : Integer;
       Y : Character;
     end record;


On a typical 32-bit architecture, the X component will occupy four bytes
and the Y component will occupy one byte, for a total of 5 bytes. As a
result ``R'Value_Size`` will be 40 (bits) since this is the minimum size
required to store a value of this type. For example, it is permissible
to have a component of type R in an array whose component size is
specified to be 40 bits.

However, ``R'Object_Size`` will be 64 (bits). The difference is due to
the alignment requirement for objects of the record type. The X
component will require four-byte alignment because that is what type
Integer requires, whereas the Y component, a Character, will only
require 1-byte alignment. Since the alignment required for X is the
greatest of all the components' alignments, that is the alignment
required for the enclosing record type, i.e., 4 bytes or 32 bits. As
indicated above, the actual object size must be rounded up so that it is
a multiple of the alignment value. Therefore, 40 bits rounded up to the
next multiple of 32 yields 64 bits.

For all other types, the ``Object_Size``
and ``Value_Size`` are the same (and equivalent to the RM attribute ``Size``).
Only ``Size`` may be specified for such types.

Note that ``Value_Size`` can be used to force biased representation
for a particular subtype. Consider this example:


.. code-block:: ada

     type R is (A, B, C, D, E, F);
     subtype RAB is R range A .. B;
     subtype REF is R range E .. F;


By default, ``RAB``
has a size of 1 (sufficient to accommodate the representation
of ``A`` and ``B``, 0 and 1), and ``REF``
has a size of 3 (sufficient to accommodate the representation
of ``E`` and ``F``, 4 and 5). But if we add the
following ``Value_Size`` attribute definition clause:


.. code-block:: ada

     for REF'Value_Size use 1;


then biased representation is forced for ``REF``,
and 0 will represent ``E`` and 1 will represent ``F``.
A warning is issued when a ``Value_Size`` attribute
definition clause forces biased representation. This
warning can be turned off using :switch:`-gnatw.B`.

.. _Component_Size_Clauses:

Component_Size Clauses
======================

.. index:: Component_Size Clause

Normally, the value specified in a component size clause must be consistent
with the subtype of the array component with regard to size and alignment.
In other words, the value specified must be at least equal to the size
of this subtype, and must be a multiple of the alignment value.

In addition, component size clauses are allowed which cause the array
to be packed, by specifying a smaller value.  A first case is for
component size values in the range 1 through 63 on 32-bit targets,
and 1 through 127 on 64-bit targets.  The value specified may not
be smaller than the Size of the subtype.  GNAT will accurately
honor all packing requests in this range.  For example, if we have:


.. code-block:: ada

  type r is array (1 .. 8) of Natural;
  for r'Component_Size use 31;


then the resulting array has a length of 31 bytes (248 bits = 8 * 31).
Of course access to the components of such an array is considerably
less efficient than if the natural component size of 32 is used.
A second case is when the subtype of the component is a record type
padded because of its default alignment.  For example, if we have:


.. code-block:: ada

  type r is record
    i : Integer;
    j : Integer;
    b : Boolean;
  end record;

  type a is array (1 .. 8) of r;
  for a'Component_Size use 72;


then the resulting array has a length of 72 bytes, instead of 96 bytes
if the alignment of the record (4) was obeyed.

Note that there is no point in giving both a component size clause
and a pragma Pack for the same array type. if such duplicate
clauses are given, the pragma Pack will be ignored.

.. _Bit_Order_Clauses:

Bit_Order Clauses
=================

.. index:: Bit_Order Clause

.. index:: bit ordering

.. index:: ordering, of bits

For record subtypes, GNAT permits the specification of the ``Bit_Order``
attribute.  The specification may either correspond to the default bit
order for the target, in which case the specification has no effect and
places no additional restrictions, or it may be for the non-standard
setting (that is the opposite of the default).

In the case where the non-standard value is specified, the effect is
to renumber bits within each byte, but the ordering of bytes is not
affected.  There are certain
restrictions placed on component clauses as follows:


* Components fitting within a single storage unit.

  These are unrestricted, and the effect is merely to renumber bits.  For
  example if we are on a little-endian machine with ``Low_Order_First``
  being the default, then the following two declarations have exactly
  the same effect:


  ::

       type R1 is record
          A : Boolean;
          B : Integer range 1 .. 120;
       end record;

       for R1 use record
          A at 0 range 0 .. 0;
          B at 0 range 1 .. 7;
       end record;

       type R2 is record
          A : Boolean;
          B : Integer range 1 .. 120;
       end record;

       for R2'Bit_Order use High_Order_First;

       for R2 use record
          A at 0 range 7 .. 7;
          B at 0 range 0 .. 6;
       end record;


  The useful application here is to write the second declaration with the
  ``Bit_Order`` attribute definition clause, and know that it will be treated
  the same, regardless of whether the target is little-endian or big-endian.

* Components occupying an integral number of bytes.

  These are components that exactly fit in two or more bytes.  Such component
  declarations are allowed, but have no effect, since it is important to realize
  that the ``Bit_Order`` specification does not affect the ordering of bytes.
  In particular, the following attempt at getting an endian-independent integer
  does not work:


  ::

       type R2 is record
          A : Integer;
       end record;

       for R2'Bit_Order use High_Order_First;

       for R2 use record
          A at 0 range 0 .. 31;
       end record;


  This declaration will result in a little-endian integer on a
  little-endian machine, and a big-endian integer on a big-endian machine.
  If byte flipping is required for interoperability between big- and
  little-endian machines, this must be explicitly programmed.  This capability
  is not provided by ``Bit_Order``.

* Components that are positioned across byte boundaries.

  but do not occupy an integral number of bytes.  Given that bytes are not
  reordered, such fields would occupy a non-contiguous sequence of bits
  in memory, requiring non-trivial code to reassemble.  They are for this
  reason not permitted, and any component clause specifying such a layout
  will be flagged as illegal by GNAT.


Since the misconception that Bit_Order automatically deals with all
endian-related incompatibilities is a common one, the specification of
a component field that is an integral number of bytes will always
generate a warning.  This warning may be suppressed using ``pragma Warnings (Off)``
if desired.  The following section contains additional
details regarding the issue of byte ordering.

.. _Effect_of_Bit_Order_on_Byte_Ordering:

Effect of Bit_Order on Byte Ordering
====================================

.. index:: byte ordering

.. index:: ordering, of bytes

In this section we will review the effect of the ``Bit_Order`` attribute
definition clause on byte ordering.  Briefly, it has no effect at all, but
a detailed example will be helpful.  Before giving this
example, let us review the precise
definition of the effect of defining ``Bit_Order``.  The effect of a
non-standard bit order is described in section 13.5.3 of the Ada
Reference Manual:

   "2   A bit ordering is a method of interpreting the meaning of
   the storage place attributes."

To understand the precise definition of storage place attributes in
this context, we visit section 13.5.1 of the manual:

   "13   A record_representation_clause (without the mod_clause)
   specifies the layout.  The storage place attributes (see 13.5.2)
   are taken from the values of the position, first_bit, and last_bit
   expressions after normalizing those values so that first_bit is
   less than Storage_Unit."

The critical point here is that storage places are taken from
the values after normalization, not before.  So the ``Bit_Order``
interpretation applies to normalized values.  The interpretation
is described in the later part of the 13.5.3 paragraph:

   "2   A bit ordering is a method of interpreting the meaning of
   the storage place attributes.  High_Order_First (known in the
   vernacular as 'big endian') means that the first bit of a
   storage element (bit 0) is the most significant bit (interpreting
   the sequence of bits that represent a component as an unsigned
   integer value).  Low_Order_First (known in the vernacular as
   'little endian') means the opposite: the first bit is the
   least significant."

Note that the numbering is with respect to the bits of a storage
unit.  In other words, the specification affects only the numbering
of bits within a single storage unit.

We can make the effect clearer by giving an example.

Suppose that we have an external device which presents two bytes, the first
byte presented, which is the first (low addressed byte) of the two byte
record is called Master, and the second byte is called Slave.

The left most (most significant) bit is called Control for each byte, and
the remaining 7 bits are called V1, V2, ... V7, where V7 is the rightmost
(least significant) bit.

On a big-endian machine, we can write the following representation clause


.. code-block:: ada

     type Data is record
        Master_Control : Bit;
        Master_V1      : Bit;
        Master_V2      : Bit;
        Master_V3      : Bit;
        Master_V4      : Bit;
        Master_V5      : Bit;
        Master_V6      : Bit;
        Master_V7      : Bit;
        Slave_Control  : Bit;
        Slave_V1       : Bit;
        Slave_V2       : Bit;
        Slave_V3       : Bit;
        Slave_V4       : Bit;
        Slave_V5       : Bit;
        Slave_V6       : Bit;
        Slave_V7       : Bit;
     end record;

     for Data use record
        Master_Control at 0 range 0 .. 0;
        Master_V1      at 0 range 1 .. 1;
        Master_V2      at 0 range 2 .. 2;
        Master_V3      at 0 range 3 .. 3;
        Master_V4      at 0 range 4 .. 4;
        Master_V5      at 0 range 5 .. 5;
        Master_V6      at 0 range 6 .. 6;
        Master_V7      at 0 range 7 .. 7;
        Slave_Control  at 1 range 0 .. 0;
        Slave_V1       at 1 range 1 .. 1;
        Slave_V2       at 1 range 2 .. 2;
        Slave_V3       at 1 range 3 .. 3;
        Slave_V4       at 1 range 4 .. 4;
        Slave_V5       at 1 range 5 .. 5;
        Slave_V6       at 1 range 6 .. 6;
        Slave_V7       at 1 range 7 .. 7;
     end record;


Now if we move this to a little endian machine, then the bit ordering within
the byte is backwards, so we have to rewrite the record rep clause as:


.. code-block:: ada

     for Data use record
        Master_Control at 0 range 7 .. 7;
        Master_V1      at 0 range 6 .. 6;
        Master_V2      at 0 range 5 .. 5;
        Master_V3      at 0 range 4 .. 4;
        Master_V4      at 0 range 3 .. 3;
        Master_V5      at 0 range 2 .. 2;
        Master_V6      at 0 range 1 .. 1;
        Master_V7      at 0 range 0 .. 0;
        Slave_Control  at 1 range 7 .. 7;
        Slave_V1       at 1 range 6 .. 6;
        Slave_V2       at 1 range 5 .. 5;
        Slave_V3       at 1 range 4 .. 4;
        Slave_V4       at 1 range 3 .. 3;
        Slave_V5       at 1 range 2 .. 2;
        Slave_V6       at 1 range 1 .. 1;
        Slave_V7       at 1 range 0 .. 0;
     end record;


It is a nuisance to have to rewrite the clause, especially if
the code has to be maintained on both machines.  However,
this is a case that we can handle with the
``Bit_Order`` attribute if it is implemented.
Note that the implementation is not required on byte addressed
machines, but it is indeed implemented in GNAT.
This means that we can simply use the
first record clause, together with the declaration


.. code-block:: ada

     for Data'Bit_Order use High_Order_First;


and the effect is what is desired, namely the layout is exactly the same,
independent of whether the code is compiled on a big-endian or little-endian
machine.

The important point to understand is that byte ordering is not affected.
A ``Bit_Order`` attribute definition never affects which byte a field
ends up in, only where it ends up in that byte.
To make this clear, let us rewrite the record rep clause of the previous
example as:


.. code-block:: ada

     for Data'Bit_Order use High_Order_First;
     for Data use record
        Master_Control at 0 range  0 .. 0;
        Master_V1      at 0 range  1 .. 1;
        Master_V2      at 0 range  2 .. 2;
        Master_V3      at 0 range  3 .. 3;
        Master_V4      at 0 range  4 .. 4;
        Master_V5      at 0 range  5 .. 5;
        Master_V6      at 0 range  6 .. 6;
        Master_V7      at 0 range  7 .. 7;
        Slave_Control  at 0 range  8 .. 8;
        Slave_V1       at 0 range  9 .. 9;
        Slave_V2       at 0 range 10 .. 10;
        Slave_V3       at 0 range 11 .. 11;
        Slave_V4       at 0 range 12 .. 12;
        Slave_V5       at 0 range 13 .. 13;
        Slave_V6       at 0 range 14 .. 14;
        Slave_V7       at 0 range 15 .. 15;
     end record;


This is exactly equivalent to saying (a repeat of the first example):


.. code-block:: ada

     for Data'Bit_Order use High_Order_First;
     for Data use record
        Master_Control at 0 range 0 .. 0;
        Master_V1      at 0 range 1 .. 1;
        Master_V2      at 0 range 2 .. 2;
        Master_V3      at 0 range 3 .. 3;
        Master_V4      at 0 range 4 .. 4;
        Master_V5      at 0 range 5 .. 5;
        Master_V6      at 0 range 6 .. 6;
        Master_V7      at 0 range 7 .. 7;
        Slave_Control  at 1 range 0 .. 0;
        Slave_V1       at 1 range 1 .. 1;
        Slave_V2       at 1 range 2 .. 2;
        Slave_V3       at 1 range 3 .. 3;
        Slave_V4       at 1 range 4 .. 4;
        Slave_V5       at 1 range 5 .. 5;
        Slave_V6       at 1 range 6 .. 6;
        Slave_V7       at 1 range 7 .. 7;
     end record;


Why are they equivalent? Well take a specific field, the ``Slave_V2``
field.  The storage place attributes are obtained by normalizing the
values given so that the ``First_Bit`` value is less than 8.  After
normalizing the values (0,10,10) we get (1,2,2) which is exactly what
we specified in the other case.

Now one might expect that the ``Bit_Order`` attribute might affect
bit numbering within the entire record component (two bytes in this
case, thus affecting which byte fields end up in), but that is not
the way this feature is defined, it only affects numbering of bits,
not which byte they end up in.

Consequently it never makes sense to specify a starting bit number
greater than 7 (for a byte addressable field) if an attribute
definition for ``Bit_Order`` has been given, and indeed it
may be actively confusing to specify such a value, so the compiler
generates a warning for such usage.

If you do need to control byte ordering then appropriate conditional
values must be used.  If in our example, the slave byte came first on
some machines we might write:

.. code-block:: ada

     Master_Byte_First constant Boolean := ...;

     Master_Byte : constant Natural :=
                     1 - Boolean'Pos (Master_Byte_First);
     Slave_Byte  : constant Natural :=
                     Boolean'Pos (Master_Byte_First);

     for Data'Bit_Order use High_Order_First;
     for Data use record
        Master_Control at Master_Byte range 0 .. 0;
        Master_V1      at Master_Byte range 1 .. 1;
        Master_V2      at Master_Byte range 2 .. 2;
        Master_V3      at Master_Byte range 3 .. 3;
        Master_V4      at Master_Byte range 4 .. 4;
        Master_V5      at Master_Byte range 5 .. 5;
        Master_V6      at Master_Byte range 6 .. 6;
        Master_V7      at Master_Byte range 7 .. 7;
        Slave_Control  at Slave_Byte  range 0 .. 0;
        Slave_V1       at Slave_Byte  range 1 .. 1;
        Slave_V2       at Slave_Byte  range 2 .. 2;
        Slave_V3       at Slave_Byte  range 3 .. 3;
        Slave_V4       at Slave_Byte  range 4 .. 4;
        Slave_V5       at Slave_Byte  range 5 .. 5;
        Slave_V6       at Slave_Byte  range 6 .. 6;
        Slave_V7       at Slave_Byte  range 7 .. 7;
     end record;

Now to switch between machines, all that is necessary is
to set the boolean constant ``Master_Byte_First`` in
an appropriate manner.

.. _Pragma_Pack_for_Arrays:

Pragma Pack for Arrays
======================

.. index:: Pragma Pack (for arrays)

Pragma ``Pack`` applied to an array has an effect that depends upon whether the
component type is *packable*.  For a component type to be *packable*, it must
be one of the following cases:

* Any elementary type.

* Any small packed array type with a static size.

* Any small simple record type with a static size.

For all these cases, if the component subtype size is in the range
1 through 63 on 32-bit targets, and 1 through 127 on 64-bit targets,
then the effect of the pragma ``Pack`` is exactly as though a
component size were specified giving the component subtype size.

All other types are non-packable, they occupy an integral number of storage
units and the only effect of pragma Pack is to remove alignment gaps.

For example if we have:

.. code-block:: ada

     type r is range 0 .. 17;

     type ar is array (1 .. 8) of r;
     pragma Pack (ar);

Then the component size of ``ar`` will be set to 5 (i.e., to ``r'size``,
and the size of the array ``ar`` will be exactly 40 bits).

Note that in some cases this rather fierce approach to packing can produce
unexpected effects.  For example, in Ada 95 and Ada 2005,
subtype ``Natural`` typically has a size of 31, meaning that if you
pack an array of ``Natural``, you get 31-bit
close packing, which saves a few bits, but results in far less efficient
access.  Since many other Ada compilers will ignore such a packing request,
GNAT will generate a warning on some uses of pragma ``Pack`` that it guesses
might not be what is intended.  You can easily remove this warning by
using an explicit ``Component_Size`` setting instead, which never generates
a warning, since the intention of the programmer is clear in this case.

GNAT treats packed arrays in one of two ways.  If the size of the array is
known at compile time and is at most 64 bits on 32-bit targets, and at most
128 bits on 64-bit targets, then internally the array is represented as a
single modular type, of exactly the appropriate number of bits.  If the
length is greater than 64 bits on 32-bit targets, and greater than 128
bits on 64-bit targets, or is not known at compile time, then the packed
array is represented as an array of bytes, and its length is always a
multiple of 8 bits.

Note that to represent a packed array as a modular type, the alignment must
be suitable for the modular type involved. For example, on typical machines
a 32-bit packed array will be represented by a 32-bit modular integer with
an alignment of four bytes. If you explicitly override the default alignment
with an alignment clause that is too small, the modular representation
cannot be used. For example, consider the following set of declarations:

.. code-block:: ada

     type R is range 1 .. 3;
     type S is array (1 .. 31) of R;
     for S'Component_Size use 2;
     for S'Size use 62;
     for S'Alignment use 1;

If the alignment clause were not present, then a 62-bit modular
representation would be chosen (typically with an alignment of 4 or 8
bytes depending on the target). But the default alignment is overridden
with the explicit alignment clause. This means that the modular
representation cannot be used, and instead the array of bytes
representation must be used, meaning that the length must be a multiple
of 8. Thus the above set of declarations will result in a diagnostic
rejecting the size clause and noting that the minimum size allowed is 64.

.. index:: Pragma Pack (for type Natural)

.. index:: Pragma Pack warning

One special case that is worth noting occurs when the base type of the
component size is 8/16/32 and the subtype is one bit less. Notably this
occurs with subtype ``Natural``. Consider:

.. code-block:: ada

     type Arr is array (1 .. 32) of Natural;
     pragma Pack (Arr);

In all commonly used Ada 83 compilers, this pragma Pack would be ignored,
since typically ``Natural'Size`` is 32 in Ada 83, and in any case most
Ada 83 compilers did not attempt 31 bit packing.

In Ada 95 and Ada 2005, ``Natural'Size`` is required to be 31. Furthermore,
GNAT really does pack 31-bit subtype to 31 bits. This may result in a
substantial unintended performance penalty when porting legacy Ada 83 code.
To help prevent this, GNAT generates a warning in such cases. If you really
want 31 bit packing in a case like this, you can set the component size
explicitly:

.. code-block:: ada

     type Arr is array (1 .. 32) of Natural;
     for Arr'Component_Size use 31;

Here 31-bit packing is achieved as required, and no warning is generated,
since in this case the programmer intention is clear.

.. _Pragma_Pack_for_Records:

Pragma Pack for Records
=======================

.. index:: Pragma Pack (for records)

Pragma ``Pack`` applied to a record will pack the components to reduce
wasted space from alignment gaps and by reducing the amount of space
taken by components.  We distinguish between *packable* components and
*non-packable* components.
Components of the following types are considered packable:

* Components of an elementary type are packable unless they are aliased,
  independent or atomic.

* Small packed arrays, where the size is statically known, are represented
  internally as modular integers, and so they are also packable.

* Small simple records, where the size is statically known, are also packable.

For all these cases, if the ``'Size`` value is in the range 1 through 64 on
32-bit targets, and 1 through 128 on 64-bit targets, the components occupy
the exact number of bits corresponding to this value and are packed with no
padding bits, i.e. they can start on an arbitrary bit boundary.

All other types are non-packable, they occupy an integral number of storage
units and the only effect of pragma ``Pack`` is to remove alignment gaps.

For example, consider the record

.. code-block:: ada

     type Rb1 is array (1 .. 13) of Boolean;
     pragma Pack (Rb1);

     type Rb2 is array (1 .. 65) of Boolean;
     pragma Pack (Rb2);

     type AF is new Float with Atomic;

     type X2 is record
        L1 : Boolean;
        L2 : Duration;
        L3 : AF;
        L4 : Boolean;
        L5 : Rb1;
        L6 : Rb2;
     end record;
     pragma Pack (X2);

The representation for the record ``X2`` is as follows on 32-bit targets:

.. code-block:: ada

  for X2'Size use 224;
  for X2 use record
     L1 at  0 range  0 .. 0;
     L2 at  0 range  1 .. 64;
     L3 at 12 range  0 .. 31;
     L4 at 16 range  0 .. 0;
     L5 at 16 range  1 .. 13;
     L6 at 18 range  0 .. 71;
  end record;

Studying this example, we see that the packable fields ``L1``
and ``L2`` are of length equal to their sizes, and placed at
specific bit boundaries (and not byte boundaries) to eliminate
padding.  But ``L3`` is of a non-packable float type (because
it is aliased), so it is on the next appropriate alignment boundary.

The next two fields are fully packable, so ``L4`` and ``L5`` are
minimally packed with no gaps.  However, type ``Rb2`` is a packed
array that is longer than 64 bits, so it is itself non-packable on
32-bit targets.  Thus the ``L6`` field is aligned to the next byte
boundary, and takes an integral number of bytes, i.e., 72 bits.

.. _Record_Representation_Clauses:

Record Representation Clauses
=============================

.. index:: Record Representation Clause

Record representation clauses may be given for all record types, including
types obtained by record extension.  Component clauses are allowed for any
static component.  The restrictions on component clauses depend on the type
of the component.

.. index:: Component Clause

For all components of an elementary type, the only restriction on component
clauses is that the size must be at least the ``'Size`` value of the type
(actually the Value_Size).  There are no restrictions due to alignment,
and such components may freely cross storage boundaries.

Packed arrays with a size up to and including 64 bits on 32-bit targets,
and up to and including 128 bits on 64-bit targets, are represented
internally using a modular type with the appropriate number of bits, and
thus the same lack of restriction applies.  For example, if you declare:

.. code-block:: ada

     type R is array (1 .. 49) of Boolean;
     pragma Pack (R);
     for R'Size use 49;

then a component clause for a component of type ``R`` may start on any
specified bit boundary, and may specify a value of 49 bits or greater.

For packed bit arrays that are longer than 64 bits on 32-bit targets,
and longer than 128 bits on 64-bit targets, there are two cases. If the
component size is a power of 2 (1,2,4,8,16,32,64 bits), including the
important case of single bits or boolean values, then there are no
limitations on placement of such components, and they may start and
end at arbitrary bit boundaries.

If the component size is not a power of 2 (e.g., 3 or 5), then an array
of this type must always be placed on on a storage unit (byte) boundary
and occupy an integral number of storage units (bytes). Any component
clause that does not meet this requirement will be rejected.

Any aliased component, or component of an aliased type, must have its
normal alignment and size. A component clause that does not meet this
requirement will be rejected.

The tag field of a tagged type always occupies an address sized field at
the start of the record.  No component clause may attempt to overlay this
tag. When a tagged type appears as a component, the tag field must have
proper alignment

In the case of a record extension ``T1``, of a type ``T``, no component
clause applied to the type ``T1`` can specify a storage location that
would overlap the first ``T'Object_Size`` bits of the record.

For all other component types, including non-bit-packed arrays,
the component can be placed at an arbitrary bit boundary,
so for example, the following is permitted:

.. code-block:: ada

     type R is array (1 .. 10) of Boolean;
     for R'Size use 80;

     type Q is record
        G, H : Boolean;
        L, M : R;
     end record;

     for Q use record
        G at 0 range  0 ..   0;
        H at 0 range  1 ..   1;
        L at 0 range  2 ..  81;
        R at 0 range 82 .. 161;
     end record;

.. _Handling_of_Records_with_Holes:

Handling of Records with Holes
==============================

.. index:: Handling of Records with Holes

As a result of alignment considerations, records may contain "holes"
or gaps which do not correspond to the data bits of any of the components.
Record representation clauses can also result in holes in records.

GNAT does not attempt to clear these holes, so in record objects,
they should be considered to hold undefined rubbish. The generated
equality routine just tests components so does not access these
undefined bits, and assignment and copy operations may or may not
preserve the contents of these holes (for assignments, the holes
in the target will in practice contain either the bits that are
present in the holes in the source, or the bits that were present
in the target before the assignment).

If it is necessary to ensure that holes in records have all zero
bits, then record objects for which this initialization is desired
should be explicitly set to all zero values using Unchecked_Conversion
or address overlays. For example

.. code-block:: ada

  type HRec is record
     C : Character;
     I : Integer;
  end record;

On typical machines, integers need to be aligned on a four-byte
boundary, resulting in three bytes of undefined rubbish following
the 8-bit field for C. To ensure that the hole in a variable of
type HRec is set to all zero bits,
you could for example do:

.. code-block:: ada

  type Base is record
     Dummy1, Dummy2 : Integer := 0;
  end record;

  BaseVar : Base;
  RealVar : Hrec;
  for RealVar'Address use BaseVar'Address;


Now the 8-bytes of the value of RealVar start out containing all zero
bits. A safer approach is to just define dummy fields, avoiding the
holes, as in:

.. code-block:: ada

  type HRec is record
     C      : Character;
     Dummy1 : Short_Short_Integer := 0;
     Dummy2 : Short_Short_Integer := 0;
     Dummy3 : Short_Short_Integer := 0;
     I      : Integer;
  end record;

And to make absolutely sure that the intent of this is followed, you
can use representation clauses:

.. code-block:: ada

  for Hrec use record
     C      at 0 range 0 .. 7;
     Dummy1 at 1 range 0 .. 7;
     Dummy2 at 2 range 0 .. 7;
     Dummy3 at 3 range 0 .. 7;
     I      at 4 range 0 .. 31;
  end record;
  for Hrec'Size use 64;


.. _Enumeration_Clauses:

Enumeration Clauses
===================

The only restriction on enumeration clauses is that the range of values
must be representable.  For the signed case, if one or more of the
representation values are negative, all values must be in the range:

.. code-block:: ada

     System.Min_Int .. System.Max_Int

For the unsigned case, where all values are nonnegative, the values must
be in the range:

.. code-block:: ada

     0 .. System.Max_Binary_Modulus;


A *confirming* representation clause is one in which the values range
from 0 in sequence, i.e., a clause that confirms the default representation
for an enumeration type.
Such a confirming representation
is permitted by these rules, and is specially recognized by the compiler so
that no extra overhead results from the use of such a clause.

If an array has an index type which is an enumeration type to which an
enumeration clause has been applied, then the array is stored in a compact
manner.  Consider the declarations:

.. code-block:: ada

     type r is (A, B, C);
     for r use (A => 1, B => 5, C => 10);
     type t is array (r) of Character;

The array type t corresponds to a vector with exactly three elements and
has a default size equal to ``3*Character'Size``.  This ensures efficient
use of space, but means that accesses to elements of the array will incur
the overhead of converting representation values to the corresponding
positional values, (i.e., the value delivered by the ``Pos`` attribute).


.. _Address_Clauses:

Address Clauses
===============
.. index:: Address Clause

The reference manual allows a general restriction on representation clauses,
as found in RM 13.1(22):

   "An implementation need not support representation
   items containing nonstatic expressions, except that
   an implementation should support a representation item
   for a given entity if each nonstatic expression in the
   representation item is a name that statically denotes
   a constant declared before the entity."

In practice this is applicable only to address clauses, since this is the
only case in which a nonstatic expression is permitted by the syntax.  As
the AARM notes in sections 13.1 (22.a-22.h):

   22.a   Reason: This is to avoid the following sort of thing:

   22.b        X : Integer := F(...);
   Y : Address := G(...);
   for X'Address use Y;

   22.c   In the above, we have to evaluate the
   initialization expression for X before we
   know where to put the result.  This seems
   like an unreasonable implementation burden.

   22.d   The above code should instead be written
   like this:

   22.e        Y : constant Address := G(...);
   X : Integer := F(...);
   for X'Address use Y;

   22.f   This allows the expression 'Y' to be safely
   evaluated before X is created.

   22.g   The constant could be a formal parameter of mode in.

   22.h   An implementation can support other nonstatic
   expressions if it wants to.  Expressions of type
   Address are hardly ever static, but their value
   might be known at compile time anyway in many
   cases.

GNAT does indeed permit many additional cases of nonstatic expressions.  In
particular, if the type involved is elementary there are no restrictions
(since in this case, holding a temporary copy of the initialization value,
if one is present, is inexpensive).  In addition, if there is no implicit or
explicit initialization, then there are no restrictions.  GNAT will reject
only the case where all three of these conditions hold:

*
  The type of the item is non-elementary (e.g., a record or array).

*
  There is explicit or implicit initialization required for the object.
  Note that access values are always implicitly initialized.

*
  The address value is nonstatic.  Here GNAT is more permissive than the
  RM, and allows the address value to be the address of a previously declared
  stand-alone variable, as long as it does not itself have an address clause.

  ::

               Anchor  : Some_Initialized_Type;
               Overlay : Some_Initialized_Type;
               for Overlay'Address use Anchor'Address;

  However, the prefix of the address clause cannot be an array component, or
  a component of a discriminated record.

As noted above in section 22.h, address values are typically nonstatic.  In
particular the To_Address function, even if applied to a literal value, is
a nonstatic function call.  To avoid this minor annoyance, GNAT provides
the implementation defined attribute 'To_Address.  The following two
expressions have identical values:

.. index:: Attribute
.. index:: To_Address

.. code-block:: ada

     To_Address (16#1234_0000#)
     System'To_Address (16#1234_0000#);

except that the second form is considered to be a static expression, and
thus when used as an address clause value is always permitted.

Additionally, GNAT treats as static an address clause that is an
unchecked_conversion of a static integer value.  This simplifies the porting
of legacy code, and provides a portable equivalent to the GNAT attribute
``To_Address``.

Another issue with address clauses is the interaction with alignment
requirements.  When an address clause is given for an object, the address
value must be consistent with the alignment of the object (which is usually
the same as the alignment of the type of the object).  If an address clause
is given that specifies an inappropriately aligned address value, then the
program execution is erroneous.

Since this source of erroneous behavior can have unfortunate effects on
machines with strict alignment requirements, GNAT
checks (at compile time if possible, generating a warning, or at execution
time with a run-time check) that the alignment is appropriate.  If the
run-time check fails, then ``Program_Error`` is raised.  This run-time
check is suppressed if the GNAT check Alignment_Check is suppressed, or if
``pragma Restrictions (No_Elaboration_Code)`` is in effect. It is also
suppressed by default on non-strict alignment machines (such as the x86).

In some cases, GNAT does not support an address specification (using either
form of aspect specification syntax) for the declaration of an object that has
an indefinite nominal subtype. An object declaration has an indefinite
nominal subtype if it takes its bounds (for an array type), discriminant
values (for a discriminated type whose discriminants lack defaults), or tag
(for a class-wide type) from its initial value, as in

.. code-block:: ada

    X : String := Some_Function_Call;
    -- String has no constraint, so bounds for X come from function call

This restriction does not apply if the size of the object's initial value is
known at compile time and the type of the object is not class-wide.

.. index:: Export

An address clause cannot be given for an exported object.  More
understandably the real restriction is that objects with an address
clause cannot be exported.  This is because such variables are not
defined by the Ada program, so there is no external object to export.

.. index:: Import

It is permissible to give an address clause and a pragma Import for the
same object.  In this case, the variable is not really defined by the
Ada program, so there is no external symbol to be linked.  The link name
and the external name are ignored in this case.  The reason that we allow this
combination is that it provides a useful idiom to avoid unwanted
initializations on objects with address clauses.

When an address clause is given for an object that has implicit or
explicit initialization, then by default initialization takes place.  This
means that the effect of the object declaration is to overwrite the
memory at the specified address.  This is almost always not what the
programmer wants, so GNAT will output a warning:

::

    with System;
    package G is
       type R is record
          M : Integer := 0;
       end record;

       Ext : R;
       for Ext'Address use System'To_Address (16#1234_1234#);
           |
    >>> warning: implicit initialization of "Ext" may
        modify overlaid storage
    >>> warning: use pragma Import for "Ext" to suppress
        initialization (RM B(24))

    end G;

As indicated by the warning message, the solution is to use a (dummy) pragma
Import to suppress this initialization.  The pragma tell the compiler that the
object is declared and initialized elsewhere.  The following package compiles
without warnings (and the initialization is suppressed):

.. code-block:: ada

     with System;
     package G is
        type R is record
           M : Integer := 0;
        end record;

        Ext : R;
        for Ext'Address use System'To_Address (16#1234_1234#);
        pragma Import (Ada, Ext);
     end G;


A final issue with address clauses involves their use for overlaying
variables, as in the following example:

.. index:: Overlaying of objects

.. code-block:: ada

    A : Integer;
    B : Integer;
    for B'Address use A'Address;


or alternatively, using the form recommended by the RM:

.. code-block:: ada

    A    : Integer;
    Addr : constant Address := A'Address;
    B    : Integer;
    for B'Address use Addr;


In both of these cases, ``A`` and ``B`` become aliased to one another
via the address clause. This use of address clauses to overlay
variables, achieving an effect similar to unchecked conversion
was erroneous in Ada 83, but in Ada 95 and Ada 2005
the effect is implementation defined. Furthermore, the
Ada RM specifically recommends that in a situation
like this, ``B`` should be subject to the following
implementation advice (RM 13.3(19)):

   "19  If the Address of an object is specified, or it is imported
   or exported, then the implementation should not perform
   optimizations based on assumptions of no aliases."

GNAT follows this recommendation, and goes further by also applying
this recommendation to the overlaid variable (``A`` in the above example)
in this case. This means that the overlay works "as expected", in that
a modification to one of the variables will affect the value of the other.

More generally, GNAT interprets this recommendation conservatively for
address clauses: in the cases other than overlays, it considers that the
object is effectively subject to pragma ``Volatile`` and implements the
associated semantics.

Note that when address clause overlays are used in this way, there is an
issue of unintentional initialization, as shown by this example:

::

  package Overwrite_Record is
     type R is record
        A : Character := 'C';
        B : Character := 'A';
     end record;
     X : Short_Integer := 3;
     Y : R;
     for Y'Address use X'Address;
         |
  >>> warning: default initialization of "Y" may
      modify "X", use pragma Import for "Y" to
      suppress initialization (RM B.1(24))

  end Overwrite_Record;

Here the default initialization of ``Y`` will clobber the value
of ``X``, which justifies the warning. The warning notes that
this effect can be eliminated by adding a ``pragma Import``
which suppresses the initialization:

.. code-block:: ada

  package Overwrite_Record is
     type R is record
        A : Character := 'C';
        B : Character := 'A';
     end record;
     X : Short_Integer := 3;
     Y : R;
     for Y'Address use X'Address;
     pragma Import (Ada, Y);
  end Overwrite_Record;


Note that the use of ``pragma Initialize_Scalars`` may cause variables to
be initialized when they would not otherwise have been in the absence
of the use of this pragma. This may cause an overlay to have this
unintended clobbering effect. The compiler avoids this for scalar
types, but not for composite objects (where in general the effect
of ``Initialize_Scalars`` is part of the initialization routine
for the composite object):

::

  pragma Initialize_Scalars;
  with Ada.Text_IO;  use Ada.Text_IO;
  procedure Overwrite_Array is
     type Arr is array (1 .. 5) of Integer;
     X : Arr := (others => 1);
     A : Arr;
     for A'Address use X'Address;
         |
  >>> warning: default initialization of "A" may
      modify "X", use pragma Import for "A" to
      suppress initialization (RM B.1(24))

  begin
     if X /= Arr'(others => 1) then
        Put_Line ("X was clobbered");
     else
        Put_Line ("X was not clobbered");
     end if;
  end Overwrite_Array;

The above program generates the warning as shown, and at execution
time, prints ``X was clobbered``. If the ``pragma Import`` is
added as suggested:

.. code-block:: ada

  pragma Initialize_Scalars;
  with Ada.Text_IO;  use Ada.Text_IO;
  procedure Overwrite_Array is
     type Arr is array (1 .. 5) of Integer;
     X : Arr := (others => 1);
     A : Arr;
     for A'Address use X'Address;
     pragma Import (Ada, A);
  begin
     if X /= Arr'(others => 1) then
        Put_Line ("X was clobbered");
     else
        Put_Line ("X was not clobbered");
     end if;
  end Overwrite_Array;

then the program compiles without the warning and when run will generate
the output ``X was not clobbered``.


.. _Use_of_Address_Clauses_for_Memory-Mapped_I/O:

Use of Address Clauses for Memory-Mapped I/O
============================================

.. index:: Memory-mapped I/O

A common pattern is to use an address clause to map an atomic variable to
a location in memory that corresponds to a memory-mapped I/O operation or
operations, for example:

.. code-block:: ada

      type Mem_Word is record
         A,B,C,D : Byte;
      end record;
      pragma Atomic (Mem_Word);
      for Mem_Word_Size use 32;

      Mem : Mem_Word;
      for Mem'Address use some-address;
      ...
      Temp := Mem;
      Temp.A := 32;
      Mem := Temp;

For a full access (reference or modification) of the variable (Mem) in this
case, as in the above examples, GNAT guarantees that the entire atomic word
will be accessed, in accordance with the RM C.6(15) clause.

A problem arises with a component access such as:

.. code-block:: ada

      Mem.A := 32;

Note that the component A is not declared as atomic. This means that it is
not clear what this assignment means. It could correspond to full word read
and write as given in the first example, or on architectures that supported
such an operation it might be a single byte store instruction. The RM does
not have anything to say in this situation, and GNAT does not make any
guarantee. The code generated may vary from target to target. GNAT will issue
a warning in such a case:

::

      Mem.A := 32;
      |
      >>> warning: access to non-atomic component of atomic array,
          may cause unexpected accesses to atomic object

It is best to be explicit in this situation, by either declaring the
components to be atomic if you want the byte store, or explicitly writing
the full word access sequence if that is what the hardware requires.
Alternatively, if the full word access sequence is required, GNAT also
provides the pragma ``Volatile_Full_Access`` which can be used in lieu of
pragma ``Atomic`` and will give the additional guarantee.


.. _Effect_of_Convention_on_Representation:

Effect of Convention on Representation
======================================

.. index:: Convention, effect on representation

Normally the specification of a foreign language convention for a type or
an object has no effect on the chosen representation.  In particular, the
representation chosen for data in GNAT generally meets the standard system
conventions, and for example records are laid out in a manner that is
consistent with C.  This means that specifying convention C (for example)
has no effect.

There are three exceptions to this general rule:

* *Convention Fortran and array subtypes*.

  If pragma Convention Fortran is specified for an array subtype, then in
  accordance with the implementation advice in section 3.6.2(11) of the
  Ada Reference Manual, the array will be stored in a Fortran-compatible
  column-major manner, instead of the normal default row-major order.

* *Convention C and enumeration types*

  GNAT normally stores enumeration types in 8, 16, or 32 bits as required
  to accommodate all values of the type.  For example, for the enumeration
  type declared by:

  ::

       type Color is (Red, Green, Blue);

  8 bits is sufficient to store all values of the type, so by default, objects
  of type ``Color`` will be represented using 8 bits.  However, normal C
  convention is to use 32 bits for all enum values in C, since enum values
  are essentially of type int.  If pragma ``Convention C`` is specified for an
  Ada enumeration type, then the size is modified as necessary (usually to
  32 bits) to be consistent with the C convention for enum values.

  Note that this treatment applies only to types. If Convention C is given for
  an enumeration object, where the enumeration type is not Convention C, then
  Object_Size bits are allocated. For example, for a normal enumeration type,
  with less than 256 elements, only 8 bits will be allocated for the object.
  Since this may be a surprise in terms of what C expects, GNAT will issue a
  warning in this situation. The warning can be suppressed by giving an explicit
  size clause specifying the desired size.

* *Convention C/Fortran and Boolean types*

  In C, the usual convention for boolean values, that is values used for
  conditions, is that zero represents false, and nonzero values represent
  true.  In Ada, the normal convention is that two specific values, typically
  0/1, are used to represent false/true respectively.

  Fortran has a similar convention for ``LOGICAL`` values (any nonzero
  value represents true).

  To accommodate the Fortran and C conventions, if a pragma Convention specifies
  C or Fortran convention for a derived Boolean, as in the following example:

  ::

       type C_Switch is new Boolean;
       pragma Convention (C, C_Switch);


  then the GNAT generated code will treat any nonzero value as true.  For truth
  values generated by GNAT, the conventional value 1 will be used for True, but
  when one of these values is read, any nonzero value is treated as True.


.. _Conventions_and_Anonymous_Access_Types:

Conventions and Anonymous Access Types
======================================

.. index:: Anonymous access types

.. index:: Convention for anonymous access types

The RM is not entirely clear on convention handling in a number of cases,
and in particular, it is not clear on the convention to be given to
anonymous access types in general, and in particular what is to be
done for the case of anonymous access-to-subprogram.

In GNAT, we decide that if an explicit Convention is applied
to an object or component, and its type is such an anonymous type,
then the convention will apply to this anonymous type as well. This
seems to make sense since it is anomalous in any case to have a
different convention for an object and its type, and there is clearly
no way to explicitly specify a convention for an anonymous type, since
it doesn't have a name to specify!

Furthermore, we decide that if a convention is applied to a record type,
then this convention is inherited by any of its components that are of an
anonymous access type which do not have an explicitly specified convention.

The following program shows these conventions in action:

::

  package ConvComp is
     type Foo is range 1 .. 10;
     type T1 is record
        A : access function (X : Foo) return Integer;
        B : Integer;
     end record;
     pragma Convention (C, T1);

     type T2 is record
        A : access function (X : Foo) return Integer;
        pragma Convention  (C, A);
        B : Integer;
     end record;
     pragma Convention (COBOL, T2);

     type T3 is record
        A : access function (X : Foo) return Integer;
        pragma Convention  (COBOL, A);
        B : Integer;
     end record;
     pragma Convention (C, T3);

     type T4 is record
        A : access function (X : Foo) return Integer;
        B : Integer;
     end record;
     pragma Convention (COBOL, T4);

     function F (X : Foo) return Integer;
     pragma Convention (C, F);

     function F (X : Foo) return Integer is (13);

     TV1 : T1 := (F'Access, 12);  -- OK
     TV2 : T2 := (F'Access, 13);  -- OK

     TV3 : T3 := (F'Access, 13);  -- ERROR
                  |
  >>> subprogram "F" has wrong convention
  >>> does not match access to subprogram declared at line 17
       38.    TV4 : T4 := (F'Access, 13);  -- ERROR
                  |
  >>> subprogram "F" has wrong convention
  >>> does not match access to subprogram declared at line 24
       39. end ConvComp;


.. _Determining_the_Representations_chosen_by_GNAT:

Determining the Representations chosen by GNAT
==============================================

.. index:: Representation, determination of

.. index:: -gnatR (gcc)

Although the descriptions in this section are intended to be complete, it is
often easier to simply experiment to see what GNAT accepts and what the
effect is on the layout of types and objects.

As required by the Ada RM, if a representation clause is not accepted, then
it must be rejected as illegal by the compiler.  However, when a
representation clause or pragma is accepted, there can still be questions
of what the compiler actually does.  For example, if a partial record
representation clause specifies the location of some components and not
others, then where are the non-specified components placed? Or if pragma
``Pack`` is used on a record, then exactly where are the resulting
fields placed? The section on pragma ``Pack`` in this chapter can be
used to answer the second question, but it is often easier to just see
what the compiler does.

For this purpose, GNAT provides the option *-gnatR*.  If you compile
with this option, then the compiler will output information on the actual
representations chosen, in a format similar to source representation
clauses.  For example, if we compile the package:

.. code-block:: ada

  package q is
     type r (x : boolean) is tagged record
        case x is
           when True => S : String (1 .. 100);
           when False => null;
        end case;
     end record;

     type r2 is new r (false) with record
        y2 : integer;
     end record;

     for r2 use record
        y2 at 16 range 0 .. 31;
     end record;

     type x is record
        y : character;
     end record;

     type x1 is array (1 .. 10) of x;
     for x1'component_size use 11;

     type ia is access integer;

     type Rb1 is array (1 .. 13) of Boolean;
     pragma Pack (rb1);

     type Rb2 is array (1 .. 65) of Boolean;
     pragma Pack (rb2);

     type x2 is record
        l1 : Boolean;
        l2 : Duration;
        l3 : Float;
        l4 : Boolean;
        l5 : Rb1;
        l6 : Rb2;
     end record;
     pragma Pack (x2);
  end q;

using the switch *-gnatR* we obtain the following output:

.. code-block:: ada

  Representation information for unit q
  -------------------------------------

  for r'Size use ??;
  for r'Alignment use 4;
  for r use record
     x    at 4 range  0 .. 7;
     _tag at 0 range  0 .. 31;
     s    at 5 range  0 .. 799;
  end record;

  for r2'Size use 160;
  for r2'Alignment use 4;
  for r2 use record
     x       at  4 range  0 .. 7;
     _tag    at  0 range  0 .. 31;
     _parent at  0 range  0 .. 63;
     y2      at 16 range  0 .. 31;
  end record;

  for x'Size use 8;
  for x'Alignment use 1;
  for x use record
     y at 0 range  0 .. 7;
  end record;

  for x1'Size use 112;
  for x1'Alignment use 1;
  for x1'Component_Size use 11;

  for rb1'Size use 13;
  for rb1'Alignment use 2;
  for rb1'Component_Size use 1;

  for rb2'Size use 72;
  for rb2'Alignment use 1;
  for rb2'Component_Size use 1;

  for x2'Size use 224;
  for x2'Alignment use 4;
  for x2 use record
     l1 at  0 range  0 .. 0;
     l2 at  0 range  1 .. 64;
     l3 at 12 range  0 .. 31;
     l4 at 16 range  0 .. 0;
     l5 at 16 range  1 .. 13;
     l6 at 18 range  0 .. 71;
  end record;

The Size values are actually the Object_Size, i.e., the default size that
will be allocated for objects of the type.
The ``??`` size for type r indicates that we have a variant record, and the
actual size of objects will depend on the discriminant value.

The Alignment values show the actual alignment chosen by the compiler
for each record or array type.

The record representation clause for type r shows where all fields
are placed, including the compiler generated tag field (whose location
cannot be controlled by the programmer).

The record representation clause for the type extension r2 shows all the
fields present, including the parent field, which is a copy of the fields
of the parent type of r2, i.e., r1.

The component size and size clauses for types rb1 and rb2 show
the exact effect of pragma ``Pack`` on these arrays, and the record
representation clause for type x2 shows how pragma `Pack` affects
this record type.

In some cases, it may be useful to cut and paste the representation clauses
generated by the compiler into the original source to fix and guarantee
the actual representation to be used.

---

### Gcc Ada Doc Gnat Rm Security Hardening Features (`gcc/ada/doc/gnat_rm/security_hardening_features.rst`)

.. _Security_Hardening_Features:

***************************
Security Hardening Features
***************************

This chapter describes Ada extensions aimed at security hardening that
are provided by GNAT.

The features in this chapter are currently experimental and subject to
change.

These features are supported only by the GCC back end, not by LLVM.

.. Register Scrubbing:

Register Scrubbing
==================

GNAT can generate code to zero-out hardware registers before returning
from a subprogram.

It can be enabled with the :switch:`-fzero-call-used-regs={choice}`
command-line option, to affect all subprograms in a compilation, and
with a :samp:`Machine_Attribute` pragma, to affect only specific
subprograms.

.. code-block:: ada

     procedure Foo;
     pragma Machine_Attribute (Foo, "zero_call_used_regs", "used");
     --  Before returning, Foo scrubs only call-clobbered registers
     --  that it uses itself.

     function Bar return Integer;
     pragma Machine_Attribute (Bar, "zero_call_used_regs", "all");
     --  Before returning, Bar scrubs all call-clobbered registers.

     function Baz return Integer;
     pragma Machine_Attribute (Bar, "zero_call_used_regs", "leafy");
     --  Before returning, Bar scrubs call-clobbered registers, either
     --  those it uses itself, if it can be identified as a leaf
     --  function, or all of them otherwise.


For usage and more details on the command-line option, on the
``zero_call_used_regs`` attribute, and on their use with other
programming languages, see :title:`Using the GNU Compiler Collection
(GCC)`.


.. Stack Scrubbing:

Stack Scrubbing
===============

GNAT can generate code to zero-out stack frames used by subprograms.

It can be activated with the :samp:`Machine_Attribute` pragma, on
specific subprograms and variables, or their types.  (This attribute
always applies to a type, even when it is associated with a subprogram
or a variable.)

.. code-block:: ada

     function Foo returns Integer;
     pragma Machine_Attribute (Foo, "strub");
     --  Foo and its callers are modified so as to scrub the stack
     --  space used by Foo after it returns.  Shorthand for:
     --  pragma Machine_Attribute (Foo, "strub", "at-calls");

     procedure Bar;
     pragma Machine_Attribute (Bar, "strub", "internal");
     --  Bar is turned into a wrapper for its original body,
     --  and they scrub the stack used by the original body.

     Var : Integer;
     pragma Machine_Attribute (Var, "strub");
     --  Reading from Var in a subprogram enables stack scrubbing
     --  of the stack space used by the subprogram.  Furthermore, if
     --  Var is declared within a subprogram, this also enables
     --  scrubbing of the stack space used by that subprogram.


Given these declarations, Foo has its type and body modified as
follows:

.. code-block:: ada

     function Foo (<WaterMark> : in out System.Address) returns Integer
     is
       --  ...
     begin
       <__strub_update> (<WaterMark>);  --  Updates the stack WaterMark.
       --  ...
     end;


whereas its callers are modified from:

.. code-block:: ada

     X := Foo;

to:

.. code-block:: ada

     declare
       <WaterMark> : System.Address;
     begin
       <__strub_enter> (<WaterMark>);  -- Initialize <WaterMark>.
       X := Foo (<WaterMark>);
       <__strub_leave> (<WaterMark>);  -- Scrubs stack up to <WaterMark>.
     end;


As for Bar, because it is strubbed in internal mode, its callers are
not modified.  Its definition is modified roughly as follows:

.. code-block:: ada

     procedure Bar is
       <WaterMark> : System.Address;
       procedure Strubbed_Bar (<WaterMark> : in out System.Address) is
       begin
         <__strub_update> (<WaterMark>);  --  Updates the stack WaterMark.
         -- original Bar body.
       end Strubbed_Bar;
     begin
       <__strub_enter> (<WaterMark>);  -- Initialize <WaterMark>.
       Strubbed_Bar (<WaterMark>);
       <__strub_leave> (<WaterMark>);  -- Scrubs stack up to <WaterMark>.
     end Bar;


There are also :switch:`-fstrub={choice}` command-line options to
control default settings.  For usage and more details on the
command-line options, on the ``strub`` attribute, and their use with
other programming languages, see :title:`Using the GNU Compiler
Collection (GCC)`.

Note that Ada secondary stacks are not scrubbed.  The restriction
``No_Secondary_Stack`` avoids their use, and thus their accidental
preservation of data that should be scrubbed.

Attributes ``Access`` and ``Unconstrained_Access`` of variables and
constants with ``strub`` enabled require types with ``strub`` enabled;
there is no way to express an access-to-strub type otherwise.
``Unchecked_Access`` bypasses this constraint, but the resulting
access type designates a non-strub type.

.. code-block:: ada

     VI : aliased Integer;
     pragma Machine_Attribute (VI, "strub");
     XsVI : access Integer := VI'Access; -- Error.
     UXsVI : access Integer := VI'Unchecked_Access; -- OK,
     --  UXsVI does *not* enable strub in subprograms that
     --  dereference it to obtain the UXsVI.all value.

     type Strub_Int is new Integer;
     pragma Machine_Attribute (Strub_Int, "strub");
     VSI : aliased Strub_Int;
     XsVSI : access Strub_Int := VSI'Access; -- OK,
     --  VSI and XsVSI.all both enable strub in subprograms that
     --  read their values.


Every access-to-subprogram type, renaming, and overriding and
overridden dispatching operations that may refer to a subprogram with
an attribute-modified interface must be annotated with the same
interface-modifying attribute.  Access-to-subprogram types can be
explicitly converted to different strub modes, as long as they are
interface-compatible (i.e., adding or removing ``at-calls`` is not
allowed).  For example, a ``strub``-``disabled`` subprogram can be
turned ``callable`` through such an explicit conversion:

.. code-block:: ada

     type TBar is access procedure;

     type TBar_Callable is access procedure;
     pragma Machine_Attribute (TBar_Callable, "strub", "callable");
     --  The attribute modifies the procedure type, rather than the
     --  access type, because of the extra argument after "strub",
     --  only applicable to subprogram types.

     Bar_Callable_Ptr : constant TBar_Callable
		:= TBar_Callable (TBar'(Bar'Access));

     procedure Bar_Callable renames Bar_Callable_Ptr.all;
     pragma Machine_Attribute (Bar_Callable, "strub", "callable");


Note that the renaming declaration is expanded to a full subprogram
body, it won't be just an alias.  Only if it is inlined will it be as
efficient as a call by dereferencing the access-to-subprogram constant
Bar_Callable_Ptr.


.. Hardened Conditionals:

Hardened Conditionals
=====================

GNAT can harden conditionals to protect against control-flow attacks.

This is accomplished by two complementary transformations, each
activated by a separate command-line option.

The option :switch:`-fharden-compares` enables hardening of compares
that compute results stored in variables, adding verification that the
reversed compare yields the opposite result, turning:

.. code-block:: ada

    B := X = Y;


into:

.. code-block:: ada

    B := X = Y;
    declare
      NotB : Boolean := X /= Y; -- Computed independently of B.
    begin
      if B = NotB then
        <__builtin_trap>;
      end if;
    end;


The option :switch:`-fharden-conditional-branches` enables hardening
of compares that guard conditional branches, adding verification of
the reversed compare to both execution paths, turning:

.. code-block:: ada

    if X = Y then
      X := Z + 1;
    else
      Y := Z - 1;
    end if;


into:

.. code-block:: ada

    if X = Y then
      if X /= Y then -- Computed independently of X = Y.
        <__builtin_trap>;
      end if;
      X := Z + 1;
    else
      if X /= Y then -- Computed independently of X = Y.
        null;
      else
        <__builtin_trap>;
      end if;
      Y := Z - 1;
    end if;


These transformations are introduced late in the compilation pipeline,
long after boolean expressions are decomposed into separate compares,
each one turned into either a conditional branch or a compare whose
result is stored in a boolean variable or temporary.  Compiler
optimizations, if enabled, may also turn conditional branches into
stored compares, and vice-versa, or into operations with implied
conditionals (e.g. MIN and MAX).  Conditionals may also be optimized
out entirely, if their value can be determined at compile time, and
occasionally multiple compares can be combined into one.

It is thus difficult to predict which of these two options will affect
a specific compare operation expressed in source code.  Using both
options ensures that every compare that is neither optimized out nor
optimized into implied conditionals will be hardened.

The addition of reversed compares can be observed by enabling the dump
files of the corresponding passes, through command-line options
:switch:`-fdump-tree-hardcmp` and :switch:`-fdump-tree-hardcbr`,
respectively.

They are separate options, however, because of the significantly
different performance impact of the hardening transformations.

For usage and more details on the command-line options, see
:title:`Using the GNU Compiler Collection (GCC)`.  These options can
be used with other programming languages supported by GCC.


.. Hardened Booleans:

Hardened Booleans
=================

Ada has built-in support for introducing boolean types with
alternative representations, using representation clauses:

.. code-block:: ada

   type HBool is new Boolean;
   for HBool use (16#5a#, 16#a5#);
   for HBool'Size use 8;


When validity checking is enabled, the compiler will check that
variables of such types hold values corresponding to the selected
representations.

There are multiple strategies for where to introduce validity checking
(see :switch:`-gnatV` options).  Their goal is to guard against
various kinds of programming errors, and GNAT strives to omit checks
when program logic rules out an invalid value, and optimizers may
further remove checks found to be redundant.

For additional hardening, the ``hardbool`` :samp:`Machine_Attribute`
pragma can be used to annotate boolean types with representation
clauses, so that expressions of such types used as conditions are
checked even when compiling with :switch:`-gnatVT`:

.. code-block:: ada

   pragma Machine_Attribute (HBool, "hardbool");

   function To_Boolean (X : HBool) returns Boolean is (Boolean (X));


is compiled roughly like:

.. code-block:: ada

   function To_Boolean (X : HBool) returns Boolean is
   begin
     if X not in True | False then
       raise Constraint_Error;
     elsif X in True then
       return True;
     else
       return False;
     end if;
   end To_Boolean;


Note that :switch:`-gnatVn` will disable even ``hardbool`` testing.

Analogous behavior is available as a GCC extension to the C and
Objective C programming languages, through the ``hardbool`` attribute,
with the difference that, instead of raising a Constraint_Error
exception, when a hardened boolean variable is found to hold a value
that stands for neither True nor False, the program traps.  For usage
and more details on that attribute, see :title:`Using the GNU Compiler
Collection (GCC)`.


.. Control Flow Redundancy:

Control Flow Redundancy
=======================

GNAT can guard against unexpected execution flows, such as branching
into the middle of subprograms, as in Return Oriented Programming
exploits.

In units compiled with :switch:`-fharden-control-flow-redundancy`,
subprograms are instrumented so that, every time they are called,
basic blocks take note as control flows through them, and, before
returning, subprograms verify that the taken notes are consistent with
the control-flow graph.

The performance impact of verification on leaf subprograms can be much
higher, while the averted risks are much lower on them.
Instrumentation can be disabled for leaf subprograms with
:switch:`-fhardcfr-skip-leaf`.

Functions with too many basic blocks, or with multiple return points,
call a run-time function to perform the verification.  Other functions
perform the verification inline before returning.

Optimizing the inlined verification can be quite time consuming, so
the default upper limit for the inline mode is set at 16 blocks.
Command-line option :switch:`--param hardcfr-max-inline-blocks=` can
override it.

Even though typically sparse control-flow graphs exhibit run-time
verification time nearly proportional to the block count of a
subprogram, it may become very significant for generated subprograms
with thousands of blocks.  Command-line option
:switch:`--param hardcfr-max-blocks=` can set an upper limit for
instrumentation.

For each block that is marked as visited, the mechanism checks that at
least one of its predecessors, and at least one of its successors, are
also marked as visited.

Verification is performed just before a subprogram returns.  The
following fragment:

.. code-block:: ada

   if X then
     Y := F (Z);
     return;
   end if;


gets turned into:

.. code-block:: ada

   type Visited_Bitmap is array (1..N) of Boolean with Pack;
   Visited : aliased Visited_Bitmap := (others => False);
   --  Bitmap of visited blocks.  N is the basic block count.
   [...]
   --  Basic block #I
   Visited(I) := True;
   if X then
     --  Basic block #J
     Visited(J) := True;
     Y := F (Z);
     CFR.Check (N, Visited'Access, CFG'Access);
     --  CFR is a hypothetical package whose Check procedure calls
     --  libgcc's __hardcfr_check, that traps if the Visited bitmap
     --  does not hold a valid path in CFG, the run-time
     --  representation of the control flow graph in the enclosing
     --  subprogram.
     return;
   end if;
   --  Basic block #K
   Visited(K) := True;


Verification would also be performed before tail calls, if any
front-ends marked them as mandatory or desirable, but none do.
Regular calls are optimized into tail calls too late for this
transformation to act on it.

In order to avoid adding verification after potential tail calls,
which would prevent tail-call optimization, we recognize returning
calls, i.e., calls whose result, if any, is returned by the calling
subprogram to its caller immediately after the call returns.
Verification is performed before such calls, whether or not they are
ultimately optimized to tail calls.  This behavior is enabled by
default whenever sibcall optimization is enabled (see
:switch:`-foptimize-sibling-calls`); it may be disabled with
:switch:`-fno-hardcfr-check-returning-calls`, or enabled with
:switch:`-fhardcfr-check-returning-calls`, regardless of the
optimization, but the lack of other optimizations may prevent calls
from being recognized as returning calls:

.. code-block:: ada

     --  CFR.Check here, with -fhardcfr-check-returning-calls.
     P (X);
     --  CFR.Check here, with -fno-hardcfr-check-returning-calls.
     return;

or:

.. code-block:: ada

     --  CFR.Check here, with -fhardcfr-check-returning-calls.
     R := F (X);
     --  CFR.Check here, with -fno-hardcfr-check-returning-calls.
     return R;


Any subprogram from which an exception may escape, i.e., that may
raise or propagate an exception that isn't handled internally, is
conceptually enclosed by a cleanup handler that performs verification,
unless this is disabled with :switch:`-fno-hardcfr-check-exceptions`.
With this feature enabled, a subprogram body containing:

.. code-block:: ada

     --  ...
       Y := F (X);  -- May raise exceptions.
     --  ...
       raise E;  -- Not handled internally.
     --  ...


gets modified as follows:

.. code-block:: ada

   begin
     --  ...
       Y := F (X);  -- May raise exceptions.
     --  ...
       raise E;  -- Not handled internally.
     --  ...
   exception
     when others =>
       CFR.Check (N, Visited'Access, CFG'Access);
       raise;
   end;


Verification may also be performed before No_Return calls, whether all
of them, with :switch:`-fhardcfr-check-noreturn-calls=always`; all but
internal subprograms involved in exception-raising or -reraising or
subprograms explicitly marked with both :samp:`No_Return` and
:samp:`Machine_Attribute` :samp:`expected_throw` pragmas, with
:switch:`-fhardcfr-check-noreturn-calls=no-xthrow` (default); only
nothrow ones, with :switch:`-fhardcfr-check-noreturn-calls=nothrow`;
or none, with :switch:`-fhardcfr-check-noreturn-calls=never`.

When a No_Return call returns control to its caller through an
exception, verification may have already been performed before the
call, if :switch:`-fhardcfr-check-noreturn-calls=always` or
:switch:`-fhardcfr-check-noreturn-calls=no-xthrow` is in effect.  The
compiler arranges for already-checked No_Return calls without a
preexisting handler to bypass the implicitly-added cleanup handler and
thus the redundant check, but a local exception or cleanup handler, if
present, will modify the set of visited blocks, and checking will take
place again when the caller reaches the next verification point,
whether it is a return or reraise statement after the exception is
otherwise handled, or even another No_Return call.

The instrumentation for hardening with control flow redundancy can be
observed in dump files generated by the command-line option
:switch:`-fdump-tree-hardcfr`.

For more details on the control flow redundancy command-line options,
see :title:`Using the GNU Compiler Collection (GCC)`.  These options
can be used with other programming languages supported by GCC.

---

### Gcc Ada Doc Gnat Rm Specialized Needs Annexes (`gcc/ada/doc/gnat_rm/specialized_needs_annexes.rst`)

.. _Specialized_Needs_Annexes:

*************************
Specialized Needs Annexes
*************************

Ada 95, Ada 2005, Ada 2012, and Ada 2022 define a number of Specialized Needs Annexes, which are not required in all implementations.  However, as described in this chapter, GNAT implements all of these annexes:

*Systems Programming (Annex C)*
  The Systems Programming Annex is fully implemented.


*Real-Time Systems (Annex D)*
  The Real-Time Systems Annex is fully implemented.


*Distributed Systems (Annex E)*
  Stub generation is fully implemented in the GNAT compiler.  In addition,
  a complete compatible PCS is available as part of ``PolyORB``,
  a separate product. **NB!** See the note in :ref:`polyORB` regarding the lifetime of this product.


*Information Systems (Annex F)*
  The Information Systems annex is fully implemented.


*Numerics (Annex G)*
  The Numerics Annex is fully implemented.


*Safety and Security / High-Integrity Systems (Annex H)*
  The Safety and Security Annex (termed the High-Integrity Systems Annex
  in Ada 2005) is fully implemented.

---

### Gcc Ada Doc Gnat Rm Standard And Implementation Defined Restrictions (`gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst`)

.. _Standard_and_Implementation_Defined_Restrictions:

************************************************
Standard and Implementation Defined Restrictions
************************************************

All Ada Reference Manual-defined Restriction identifiers are implemented:

* language-defined restrictions (see 13.12.1)
* tasking restrictions (see D.7)
* high integrity restrictions (see H.4)

GNAT implements additional restriction identifiers. All restrictions, whether
language defined or GNAT-specific, are listed in the following.

.. _Partition-Wide_Restrictions:

Partition-Wide Restrictions
===========================

There are two separate lists of restriction identifiers. The first
set requires consistency throughout a partition (in other words, if the
restriction identifier is used for any compilation unit in the partition,
then all compilation units in the partition must obey the restriction).

Immediate_Reclamation
---------------------
.. index:: Immediate_Reclamation

[RM H.4] This restriction ensures that, except for storage occupied by
objects created by allocators and not deallocated via unchecked
deallocation, any storage reserved at run time for an object is
immediately reclaimed when the object no longer exists.

Max_Asynchronous_Select_Nesting
-------------------------------
.. index:: Max_Asynchronous_Select_Nesting

[RM D.7] Specifies the maximum dynamic nesting level of asynchronous
selects. Violations of this restriction with a value of zero are
detected at compile time. Violations of this restriction with values
other than zero cause Storage_Error to be raised.

Max_Entry_Queue_Length
----------------------
.. index:: Max_Entry_Queue_Length

[RM D.7] This restriction is a declaration that any protected entry compiled in
the scope of the restriction has at most the specified number of
tasks waiting on the entry at any one time, and so no queue is required.
Note that this restriction is checked at run time. Violation of this
restriction results in the raising of Program_Error exception at the point of
the call.

.. index:: Max_Entry_Queue_Depth

The restriction ``Max_Entry_Queue_Depth`` is recognized as a
synonym for ``Max_Entry_Queue_Length``. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).

Max_Protected_Entries
---------------------
.. index:: Max_Protected_Entries

[RM D.7] Specifies the maximum number of entries per protected type. The
bounds of every entry family of a protected unit shall be static, or shall be
defined by a discriminant of a subtype whose corresponding bound is static.

Max_Select_Alternatives
-----------------------
.. index:: Max_Select_Alternatives

[RM D.7] Specifies the maximum number of alternatives in a selective accept.

Max_Storage_At_Blocking
-----------------------
.. index:: Max_Storage_At_Blocking

[RM D.7] Specifies the maximum portion (in storage elements) of a task's
Storage_Size that can be retained by a blocked task. A violation of this
restriction causes Storage_Error to be raised.

Max_Task_Entries
----------------
.. index:: Max_Task_Entries

[RM D.7] Specifies the maximum number of entries
per task.  The bounds of every entry family
of a task unit shall be static, or shall be
defined by a discriminant of a subtype whose
corresponding bound is static.

Max_Tasks
---------
.. index:: Max_Tasks

[RM D.7] Specifies the maximum number of tasks that may be created, not
counting the creation of the environment task.  Violations of this
restriction with a value of zero are detected at compile time in all
contexts.  Violations of this restriction with a value greater than
zero are detected for library-level tasks at compile time, but are
not detected for local tasks at all.

No_Abort_Statements
-------------------
.. index:: No_Abort_Statements

[RM D.7] There are no abort_statements, and there are
no calls to Task_Identification.Abort_Task.

No_Access_Parameter_Allocators
------------------------------
.. index:: No_Access_Parameter_Allocators

[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator as the actual parameter to an access
parameter.

No_Access_Subprograms
---------------------
.. index:: No_Access_Subprograms

[RM H.4] This restriction ensures at compile time that there are no
declarations of access-to-subprogram types.

No_Allocators
-------------
.. index:: No_Allocators

[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator.

No_Anonymous_Allocators
-----------------------
.. index:: No_Anonymous_Allocators

[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator of anonymous access type.

No_Asynchronous_Control
-----------------------
.. index:: No_Asynchronous_Control

[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined package Asynchronous_Task_Control.

No_Calendar
-----------
.. index:: No_Calendar

[GNAT] This restriction ensures at compile time that there are no semantic
dependences on package Calendar.

No_Coextensions
---------------
.. index:: No_Coextensions

[RM H.4] This restriction ensures at compile time that there are no
coextensions. See 3.10.2.

No_Default_Initialization
-------------------------
.. index:: No_Default_Initialization

[GNAT] This restriction prohibits any instance of default initialization
of variables or components. The binder implements a consistency check that
prevents any unit without the restriction from with'ing a unit with the
restriction (this allows the generation of initialization procedures to
be skipped, since you can be sure that no call is ever generated to an
initialization procedure in a unit with the restriction active). If used
in conjunction with Initialize_Scalars or Normalize_Scalars, the effect
is to prohibit all cases of variables declared without a specific
initializer (including the case of OUT scalar parameters).

No_Delay
--------
.. index:: No_Delay

[RM H.4] This restriction ensures at compile time that there are no
delay statements and no semantic dependences on package Calendar.

No_Dependence
-------------
.. index:: No_Dependence

[RM 13.12.1] This restriction ensures at compile time that there are no
dependences on a library unit. For GNAT, this includes implicit implementation
dependences on units of the runtime library that are created by the compiler
to support specific constructs of the language. Here are some examples:

* ``System.Arith_64``: 64-bit arithmetics for 32-bit platforms,
* ``System.Arith_128``: 128-bit arithmetics for 64-bit platforms,
* ``System.Memory``: heap memory allocation routines,
* ``System.Memory_Compare``: memory comparison routine (aka ``memcmp`` for C),
* ``System.Memory_Copy``: memory copy routine (aka ``memcpy`` for C),
* ``System.Memory_Move``: memory move routine (aka ``memmove`` for C),
* ``System.Memory_Set``: memory set routine (aka ``memset`` for C),
* ``System.Stack_Checking[.Operations]``: stack checking without MMU,
* ``System.GCC``: support routines from the GCC library.

No_Direct_Boolean_Operators
---------------------------
.. index:: No_Direct_Boolean_Operators

[GNAT] This restriction ensures that no logical operators (and/or/xor)
are used on operands of type Boolean (or any type derived from Boolean).
This is intended for use in safety critical programs where the certification
protocol requires the use of short-circuit (and then, or else) forms for all
composite boolean operations.

No_Dispatch
-----------
.. index:: No_Dispatch

[RM H.4] This restriction ensures at compile time that there are no
occurrences of ``T'Class``, for any (tagged) subtype ``T``.

No_Dispatching_Calls
--------------------
.. index:: No_Dispatching_Calls

[GNAT] This restriction ensures at compile time that the code generated by the
compiler involves no dispatching calls. The use of this restriction allows the
safe use of record extensions, classwide membership tests and other classwide
features not involving implicit dispatching. This restriction ensures that
the code contains no indirect calls through a dispatching mechanism. Note that
this includes internally-generated calls created by the compiler, for example
in the implementation of class-wide objects assignments. The
membership test is allowed in the presence of this restriction, because its
implementation requires no dispatching.
This restriction is comparable to the official Ada restriction
``No_Dispatch`` except that it is a bit less restrictive in that it allows
all classwide constructs that do not imply dispatching.
The following example indicates constructs that violate this restriction.


.. code-block:: ada

  package Pkg is
    type T is tagged record
      Data : Natural;
    end record;
    procedure P (X : T);

    type DT is new T with record
      More_Data : Natural;
    end record;
    procedure Q (X : DT);
  end Pkg;

  with Pkg; use Pkg;
  procedure Example is
    procedure Test (O : T'Class) is
      N : Natural := O'Size; --  Error: Dispatching call
      C : T'Class := O;      --  Error: implicit Dispatching Call
    begin
      if O in DT'Class then  --  OK   : Membership test
         Q (DT (O));         --  OK   : Type conversion plus direct call
      else
         P (O);              --  Error: Dispatching call
      end if;
    end Test;

    Obj : DT;
  begin
    P (Obj);                 --  OK   : Direct call
    P (T (Obj));             --  OK   : Type conversion plus direct call
    P (T'Class (Obj));       --  Error: Dispatching call

    Test (Obj);              --  OK   : Type conversion

    if Obj in T'Class then   --  OK   : Membership test
       null;
    end if;
  end Example;


No_Dynamic_Attachment
---------------------
.. index:: No_Dynamic_Attachment

[RM D.7] This restriction ensures that there is no call to any of the
operations defined in package Ada.Interrupts
(Is_Reserved, Is_Attached, Current_Handler, Attach_Handler, Exchange_Handler,
Detach_Handler, and Reference).

.. index:: No_Dynamic_Interrupts

The restriction ``No_Dynamic_Interrupts`` is recognized as a
synonym for ``No_Dynamic_Attachment``. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).

No_Dynamic_Priorities
---------------------
.. index:: No_Dynamic_Priorities

[RM D.7] There are no semantic dependencies on the package Dynamic_Priorities.

No_Entry_Calls_In_Elaboration_Code
----------------------------------
.. index:: No_Entry_Calls_In_Elaboration_Code

[GNAT] This restriction ensures at compile time that no task or protected entry
calls are made during elaboration code.  As a result of the use of this
restriction, the compiler can assume that no code past an accept statement
in a task can be executed at elaboration time.

No_Enumeration_Maps
-------------------
.. index:: No_Enumeration_Maps

[GNAT] This restriction ensures at compile time that no operations requiring
enumeration maps are used (that is Image and Value attributes applied
to enumeration types).

No_Exception_Handlers
---------------------
.. index:: No_Exception_Handlers

[GNAT] This restriction ensures at compile time that there are no explicit
exception handlers. It also indicates that no exception propagation will
be provided. In this mode, exceptions may be raised but will result in
an immediate call to the last chance handler, a routine that the user
must define with the following profile:


.. code-block:: ada

  procedure Last_Chance_Handler
    (Source_Location : System.Address; Line : Integer);
  pragma Export (C, Last_Chance_Handler,
                 "__gnat_last_chance_handler");


The ``Source_Location`` parameter is a C null-terminated string representing a
message to be associated with the exception (typically the source location of
the raise statement generated by the compiler). The Line parameter when nonzero
represents the line number in the source program where the raise occurs.

No_Exception_Propagation
------------------------
.. index:: No_Exception_Propagation

[GNAT] This restriction guarantees that exceptions are never propagated
to an outer subprogram scope. The only case in which an exception may
be raised is when the handler is statically in the same subprogram, so
that the effect of a raise is essentially like a goto statement. Any
other raise statement (implicit or explicit) will be considered
unhandled. Exception handlers are allowed, but may not contain an
exception occurrence identifier (exception choice). In addition, use of
the package GNAT.Current_Exception is not permitted, and reraise
statements (raise with no operand) are not permitted.

No_Exception_Registration
-------------------------
.. index:: No_Exception_Registration

[GNAT] This restriction ensures at compile time that no stream operations for
types Exception_Id or Exception_Occurrence are used. This also makes it
impossible to pass exceptions to or from a partition with this restriction
in a distributed environment. If this restriction is active, the generated
code is simplified by omitting the otherwise-required global registration
of exceptions when they are declared.

No_Exceptions
-------------
.. index:: No_Exceptions

[RM H.4] This restriction ensures at compile time that there are no
raise statements and no exception handlers and also suppresses the
generation of language-defined run-time checks.


No_Finalization
---------------
.. index:: No_Finalization

[GNAT] This restriction disables the language features described in
chapter 7.6 of the Ada 2005 RM as well as all form of code generation
performed by the compiler to support these features. The following types
are no longer considered controlled when this restriction is in effect:

*
  ``Ada.Finalization.Controlled``
*
  ``Ada.Finalization.Limited_Controlled``
*
  Derivations from ``Controlled`` or ``Limited_Controlled``
*
  Class-wide types
*
  Protected types
*
  Task types
*
  Array and record types with controlled components

The compiler no longer generates code to initialize, finalize or adjust an
object or a nested component, either declared on the stack or on the heap. The
deallocation of a controlled object no longer finalizes its contents.

No_Fixed_Point
--------------
.. index:: No_Fixed_Point

[RM H.4] This restriction ensures at compile time that there are no
occurrences of fixed point types and operations.

No_Floating_Point
-----------------
.. index:: No_Floating_Point

[RM H.4] This restriction ensures at compile time that there are no
occurrences of floating point types and operations.

No_Implicit_Conditionals
------------------------
.. index:: No_Implicit_Conditionals

[GNAT] This restriction ensures that the generated code does not contain any
implicit conditionals, either by modifying the generated code where possible,
or by rejecting any construct that would otherwise generate an implicit
conditional. Note that this check does not include run time constraint
checks, which on some targets may generate implicit conditionals as
well. To control the latter, constraint checks can be suppressed in the
normal manner. Constructs generating implicit conditionals include comparisons
of composite objects and the Max/Min attributes.

No_Implicit_Dynamic_Code
------------------------
.. index:: No_Implicit_Dynamic_Code
.. index:: trampoline

[GNAT] This restriction prevents the compiler from building 'trampolines'.
This is a structure that is built on the stack and contains dynamic
code to be executed at run time. On some targets, a trampoline is
built for the following features: ``Access``,
``Unrestricted_Access``, or ``Address`` of a nested subprogram;
nested task bodies; primitive operations of nested tagged types.
Trampolines do not work on machines that prevent execution of stack
data. For example, on windows systems, enabling DEP (data execution
protection) will cause trampolines to raise an exception.
Trampolines are also quite slow at run time.

On many targets, trampolines have been largely eliminated. Look at the
version of system.ads for your target --- if it has
Always_Compatible_Rep equal to False, then trampolines are largely
eliminated. In particular, a trampoline is built for the following
features: ``Address`` of a nested subprogram;
``Access`` or ``Unrestricted_Access`` of a nested subprogram,
but only if pragma Favor_Top_Level applies, or the access type has a
foreign-language convention; primitive operations of nested tagged
types.

No_Implicit_Heap_Allocations
----------------------------
.. index:: No_Implicit_Heap_Allocations

[RM D.7] No constructs are allowed to cause implicit heap allocation.

No_Implicit_Protected_Object_Allocations
----------------------------------------
.. index:: No_Implicit_Protected_Object_Allocations

[GNAT] No constructs are allowed to cause implicit heap allocation of a
protected object.

No_Implicit_Task_Allocations
----------------------------
.. index:: No_Implicit_Task_Allocations

[GNAT] No constructs are allowed to cause implicit heap allocation of a task.

No_Initialize_Scalars
---------------------
.. index:: No_Initialize_Scalars

[GNAT] This restriction ensures that no unit in the partition is compiled with
pragma Initialize_Scalars. This allows the generation of more efficient
code, and in particular eliminates dummy null initialization routines that
are otherwise generated for some record and array types.

No_IO
-----
.. index:: No_IO

[RM H.4] This restriction ensures at compile time that there are no
dependences on any of the library units Sequential_IO, Direct_IO,
Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, or Stream_IO.

No_Local_Allocators
-------------------
.. index:: No_Local_Allocators

[RM H.4] This restriction ensures at compile time that there are no
occurrences of an allocator in subprograms, generic subprograms, tasks,
and entry bodies.

No_Local_Protected_Objects
--------------------------
.. index:: No_Local_Protected_Objects

[RM D.7] This restriction ensures at compile time that protected objects are
only declared at the library level.

No_Local_Tagged_Types
---------------------
.. index:: No_Local_Tagged_Types

[GNAT] This restriction ensures at compile time that tagged types are only
declared at the library level.

No_Local_Timing_Events
----------------------
.. index:: No_Local_Timing_Events

[RM D.7] All objects of type Ada.Real_Time.Timing_Events.Timing_Event are
declared at the library level.

No_Long_Long_Integers
---------------------
.. index:: No_Long_Long_Integers

[GNAT] This partition-wide restriction forbids any explicit reference to
type Standard.Long_Long_Integer, and also forbids declaring range types whose
implicit base type is Long_Long_Integer, and modular types whose size exceeds
Long_Integer'Size.

No_Multiple_Elaboration
-----------------------
.. index:: No_Multiple_Elaboration

[GNAT] When this restriction is active and the static elaboration model is
used, and -fpreserve-control-flow is not used, the compiler is allowed to
suppress the elaboration counter normally associated with the unit, even if
the unit has elaboration code. This counter is typically used to check for
access before elaboration and to control multiple elaboration attempts. If the
restriction is used, then the situations in which multiple elaboration is
possible, including non-Ada main programs and Stand Alone libraries, are not
permitted and will be diagnosed by the binder.

No_Nested_Finalization
----------------------
.. index:: No_Nested_Finalization

[RM D.7] All objects requiring finalization are declared at the library level.

No_Protected_Type_Allocators
----------------------------
.. index:: No_Protected_Type_Allocators

[RM D.7] This restriction ensures at compile time that there are no allocator
expressions that attempt to allocate protected objects.

No_Protected_Types
------------------
.. index:: No_Protected_Types

[RM H.4] This restriction ensures at compile time that there are no
declarations of protected types or protected objects.

No_Recursion
------------
.. index:: No_Recursion

[RM H.4] A program execution is erroneous if a subprogram is invoked as
part of its execution.

No_Reentrancy
-------------
.. index:: No_Reentrancy

[RM H.4] A program execution is erroneous if a subprogram is executed by
two tasks at the same time.

No_Relative_Delay
-----------------
.. index:: No_Relative_Delay

[RM D.7] This restriction ensures at compile time that there are no delay
relative statements and prevents expressions such as ``delay 1.23;`` from
appearing in source code.

No_Requeue_Statements
---------------------
.. index:: No_Requeue_Statements

[RM D.7] This restriction ensures at compile time that no requeue statements
are permitted and prevents keyword ``requeue`` from being used in source
code.

.. index:: No_Requeue

The restriction ``No_Requeue`` is recognized as a
synonym for ``No_Requeue_Statements``. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on oNobsolescent features are activated).

No_Secondary_Stack
------------------
.. index:: No_Secondary_Stack

[GNAT] This restriction ensures at compile time that the generated code
does not contain any reference to the secondary stack.  The secondary
stack is used to implement functions returning unconstrained objects
(arrays or records) on some targets. Suppresses the allocation of
secondary stacks for tasks (excluding the environment task) at run time.

No_Select_Statements
--------------------
.. index:: No_Select_Statements

[RM D.7] This restriction ensures at compile time no select statements of any
kind are permitted, that is the keyword ``select`` may not appear.

No_Specific_Termination_Handlers
--------------------------------
.. index:: No_Specific_Termination_Handlers

[RM D.7] There are no calls to Ada.Task_Termination.Set_Specific_Handler
or to Ada.Task_Termination.Specific_Handler.

No_Specification_of_Aspect
--------------------------
.. index:: No_Specification_of_Aspect

[RM 13.12.1] This restriction checks at compile time that no aspect
specification, attribute definition clause, or pragma is given for a
given aspect.

No_Standard_Allocators_After_Elaboration
----------------------------------------
.. index:: No_Standard_Allocators_After_Elaboration

[RM D.7] Specifies that an allocator using a standard storage pool
should never be evaluated at run time after the elaboration of the
library items of the partition has completed. Otherwise, Storage_Error
is raised.

No_Standard_Storage_Pools
-------------------------
.. index:: No_Standard_Storage_Pools

[GNAT] This restriction ensures at compile time that no access types
use the standard default storage pool.  Any access type declared must
have an explicit Storage_Pool attribute defined specifying a
user-defined storage pool.

No_Stream_Optimizations
-----------------------
.. index:: No_Stream_Optimizations

[GNAT] This restriction affects the performance of stream operations on types
``String``, ``Wide_String`` and ``Wide_Wide_String``. By default, the
compiler uses block reads and writes when manipulating ``String`` objects
due to their superior performance. When this restriction is in effect, the
compiler performs all IO operations on a per-character basis.

No_Streams
----------
.. index:: No_Streams

[GNAT] This restriction ensures at compile/bind time that there are no
stream objects created and no use of stream attributes.
This restriction does not forbid dependences on the package
``Ada.Streams``. So it is permissible to with
``Ada.Streams`` (or another package that does so itself)
as long as no actual stream objects are created and no
stream attributes are used.

Note that the use of restriction allows optimization of tagged types,
since they do not need to worry about dispatching stream operations.
To take maximum advantage of this space-saving optimization, any
unit declaring a tagged type should be compiled with the restriction,
though this is not required.

When pragmas ``Discard_Names`` and ``Restrictions (No_Streams)`` simultaneously
apply to a tagged type, its Expanded_Name and External_Tag are also initialized
with empty strings. In particular, both these pragmas can be applied as
configuration pragmas to avoid exposing entity names at binary level for the
entire partition.

No_Tagged_Type_Registration
---------------------------
.. index:: No_Tagged_Type_Registration

[GNAT] If this restriction is active, then class-wide streaming
attributes are not supported. In addition, the subprograms in
Ada.Tags are not supported.
If this restriction is active, the generated code is simplified by
omitting the otherwise-required global registration of tagged types when they
are declared. This restriction may be necessary in order to also apply
the No_Elaboration_Code restriction.

No_Task_Allocators
------------------
.. index:: No_Task_Allocators

[RM D.7] There are no allocators for task types
or types containing task subcomponents.

No_Task_At_Interrupt_Priority
-----------------------------
.. index:: No_Task_At_Interrupt_Priority

[GNAT] This restriction ensures at compile time that there is no
Interrupt_Priority aspect or pragma for a task or a task type. As
a consequence, the tasks are always created with a priority below
that an interrupt priority.

No_Task_Attributes_Package
--------------------------
.. index:: No_Task_Attributes_Package

[GNAT] This restriction ensures at compile time that there are no implicit or
explicit dependencies on the package ``Ada.Task_Attributes``.

.. index:: No_Task_Attributes

The restriction ``No_Task_Attributes`` is recognized as a synonym
for ``No_Task_Attributes_Package``. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).

No_Task_Hierarchy
-----------------
.. index:: No_Task_Hierarchy

[RM D.7] All (non-environment) tasks depend
directly on the environment task of the partition.

No_Task_Termination
-------------------
.. index:: No_Task_Termination

[RM D.7] Tasks that terminate are erroneous.

No_Tasking
----------
.. index:: No_Tasking

[GNAT] This restriction prevents the declaration of tasks or task types
throughout the partition.  It is similar in effect to the use of
``Max_Tasks => 0`` except that violations are caught at compile time
and cause an error message to be output either by the compiler or
binder.

No_Terminate_Alternatives
-------------------------
.. index:: No_Terminate_Alternatives

[RM D.7] There are no selective accepts with terminate alternatives.

No_Unchecked_Access
-------------------
.. index:: No_Unchecked_Access

[RM H.4] This restriction ensures at compile time that there are no
occurrences of the Unchecked_Access attribute.

No_Unchecked_Conversion
-----------------------
.. index:: No_Unchecked_Conversion

[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined generic function Unchecked_Conversion.

No_Unchecked_Deallocation
-------------------------
.. index:: No_Unchecked_Deallocation

[RM J.13] This restriction ensures at compile time that there are no semantic
dependences on the predefined generic procedure Unchecked_Deallocation.

No_Use_Of_Attribute
-------------------
.. index:: No_Use_Of_Attribute

[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
earlier versions of Ada.

No_Use_Of_Entity
----------------
.. index:: No_Use_Of_Entity

[GNAT] This restriction ensures at compile time that there are no references
to the entity given in the form ::

   No_Use_Of_Entity => Name

where ``Name`` is the fully qualified entity, for example ::

   No_Use_Of_Entity => Ada.Text_IO.Put_Line

No_Use_Of_Pragma
----------------
.. index:: No_Use_Of_Pragma

[RM 13.12.1] This is a standard Ada 2012 restriction that is GNAT defined in
earlier versions of Ada.

Pure_Barriers
-------------
.. index:: Pure_Barriers

[GNAT] This restriction ensures at compile time that protected entry
barriers are restricted to:

* components of the protected object (excluding selection from dereferences),
* constant declarations,
* named numbers,
* enumeration literals,
* integer literals,
* real literals,
* character literals,
* implicitly defined comparison operators,
* uses of the Standard."not" operator,
* short-circuit operator,
* the Count attribute

This restriction is a relaxation of the Simple_Barriers restriction,
but still ensures absence of side effects, exceptions, and recursion
during the evaluation of the barriers.

Simple_Barriers
---------------
.. index:: Simple_Barriers

[RM D.7] This restriction ensures at compile time that barriers in entry
declarations for protected types are restricted to either static boolean
expressions or references to simple boolean variables defined in the private
part of the protected type.  No other form of entry barriers is permitted.

.. index:: Boolean_Entry_Barriers

The restriction ``Boolean_Entry_Barriers`` is recognized as a
synonym for ``Simple_Barriers``. This is retained for historical
compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).

Static_Priorities
-----------------
.. index:: Static_Priorities

[GNAT] This restriction ensures at compile time that all priority expressions
are static, and that there are no dependences on the package
``Ada.Dynamic_Priorities``.

Static_Storage_Size
-------------------
.. index:: Static_Storage_Size

[GNAT] This restriction ensures at compile time that any expression appearing
in a Storage_Size pragma or attribute definition clause is static.

.. _Program_Unit_Level_Restrictions:


Program Unit Level Restrictions
===============================

The second set of restriction identifiers
does not require partition-wide consistency.
The restriction may be enforced for a single
compilation unit without any effect on any of the
other compilation units in the partition.

No_Elaboration_Code
-------------------
.. index:: No_Elaboration_Code

[GNAT] This restriction ensures at compile time that no elaboration code is
generated.  Note that this is not the same condition as is enforced
by pragma ``Preelaborate``.  There are cases in which pragma
``Preelaborate`` still permits code to be generated (e.g., code
to initialize a large array to all zeroes), and there are cases of units
which do not meet the requirements for pragma ``Preelaborate``,
but for which no elaboration code is generated.  Generally, it is
the case that preelaborable units will meet the restrictions, with
the exception of large aggregates initialized with an others_clause,
and exception declarations (which generate calls to a run-time
registry procedure).  This restriction is enforced on
a unit by unit basis, it need not be obeyed consistently
throughout a partition.

In the case of aggregates with others, if the aggregate has a dynamic
size, there is no way to eliminate the elaboration code (such dynamic
bounds would be incompatible with ``Preelaborate`` in any case). If
the bounds are static, then use of this restriction actually modifies
the code choice of the compiler to avoid generating a loop, and instead
generate the aggregate statically if possible, no matter how many times
the data for the others clause must be repeatedly generated.

It is not possible to precisely document
the constructs which are compatible with this restriction, since,
unlike most other restrictions, this is not a restriction on the
source code, but a restriction on the generated object code. For
example, if the source contains a declaration:


.. code-block:: ada

     Val : constant Integer := X;


where X is not a static constant, it may be possible, depending
on complex optimization circuitry, for the compiler to figure
out the value of X at compile time, in which case this initialization
can be done by the loader, and requires no initialization code. It
is not possible to document the precise conditions under which the
optimizer can figure this out.

Note that this the implementation of this restriction requires full
code generation. If it is used in conjunction with "semantics only"
checking, then some cases of violations may be missed.

When this restriction is active, we are not requesting control-flow
preservation with -fpreserve-control-flow, and the static elaboration model is
used, the compiler is allowed to suppress the elaboration counter normally
associated with the unit. This counter is typically used to check for access
before elaboration and to control multiple elaboration attempts.

No_Dynamic_Accessibility_Checks
-------------------------------
.. index:: No_Dynamic_Accessibility_Checks

[GNAT] No dynamic accessibility checks are generated when this restriction is
in effect. Instead, dangling references are prevented via more conservative
compile-time checking. More specifically, existing compile-time checks are
enforced but with more conservative assumptions about the accessibility levels
of the relevant entities. These conservative assumptions eliminate the need for
dynamic accessibility checks.

These new rules for computing (at compile-time) the accessibility level of an
anonymous access type T are as follows:

*
 If T is a function result type then, from the caller's perspective, its level
 is that of the innermost master enclosing the function call. From the callee's
 perspective, the level of parameters and local variables of the callee is
 statically deeper than the level of T.

 For any other accessibility level L such that the level of parameters and local
 variables of the callee is statically deeper than L, the level of T (from the
 callee's perspective) is also statically deeper than L.
*
 If T is the type of a formal parameter then, from the caller's perspective,
 its level is at least as deep as that of the type of the corresponding actual
 parameter (whatever that actual parameter might be). From the callee's
 perspective, the level of parameters and local variables of the callee is
 statically deeper than the level of T.
*
 If T is the type of a discriminant then its level is that of the discriminated
 type.
*
 If T is the type of a stand-alone object then its level is the level of the
 object.
*
 In all other cases, the level of T is as defined by the existing rules of Ada.

No_Dynamic_Sized_Objects
------------------------
.. index:: No_Dynamic_Sized_Objects

[GNAT] This restriction disallows certain constructs that might lead to the
creation of dynamic-sized composite objects (or array or discriminated type).
An array subtype indication is illegal if the bounds are not static
or references to discriminants of an enclosing type.
A discriminated subtype indication is illegal if the type has
discriminant-dependent array components or a variant part, and the
discriminants are not static. In addition, array and record aggregates are
illegal in corresponding cases. Note that this restriction does not forbid
access discriminants. It is often a good idea to combine this restriction
with No_Secondary_Stack.

No_Entry_Queue
--------------
.. index:: No_Entry_Queue

[GNAT] This restriction is a declaration that any protected entry compiled in
the scope of the restriction has at most one task waiting on the entry
at any one time, and so no queue is required.  This restriction is not
checked at compile time.  A program execution is erroneous if an attempt
is made to queue a second task on such an entry.

No_Implementation_Aspect_Specifications
---------------------------------------
.. index:: No_Implementation_Aspect_Specifications

[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined aspects are present.  With this restriction, the only
aspects that can be used are those defined in the Ada Reference Manual.

No_Implementation_Attributes
----------------------------
.. index:: No_Implementation_Attributes

[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined attributes are present.  With this restriction, the only
attributes that can be used are those defined in the Ada Reference
Manual.

No_Implementation_Identifiers
-----------------------------
.. index:: No_Implementation_Identifiers

[RM 13.12.1] This restriction checks at compile time that no
implementation-defined identifiers (marked with pragma Implementation_Defined)
occur within language-defined packages.

No_Implementation_Pragmas
-------------------------
.. index:: No_Implementation_Pragmas

[RM 13.12.1] This restriction checks at compile time that no
GNAT-defined pragmas are present.  With this restriction, the only
pragmas that can be used are those defined in the Ada Reference Manual.

No_Implementation_Restrictions
------------------------------
.. index:: No_Implementation_Restrictions

[GNAT] This restriction checks at compile time that no GNAT-defined restriction
identifiers (other than ``No_Implementation_Restrictions`` itself)
are present.  With this restriction, the only other restriction identifiers
that can be used are those defined in the Ada Reference Manual.

No_Implementation_Units
-----------------------
.. index:: No_Implementation_Units

[RM 13.12.1] This restriction checks at compile time that there is no
mention in the context clause of any implementation-defined descendants
of packages Ada, Interfaces, or System.

No_Implicit_Aliasing
--------------------
.. index:: No_Implicit_Aliasing

[GNAT] This restriction, which is not required to be partition-wide consistent,
requires an explicit aliased keyword for an object to which 'Access,
'Unchecked_Access, or 'Address is applied, and forbids entirely the use of
the 'Unrestricted_Access attribute for objects. Note: the reason that
Unrestricted_Access is forbidden is that it would require the prefix
to be aliased, and in such cases, it can always be replaced by
the standard attribute Unchecked_Access which is preferable.

No_Implicit_Loops
-----------------
.. index:: No_Implicit_Loops

[GNAT] This restriction ensures that the generated code of the unit marked
with this restriction does not contain any implicit ``for`` loops, either by
modifying the generated code where possible, or by rejecting any construct
that would otherwise generate an implicit ``for`` loop. If this restriction is
active, it is possible to build large array aggregates with all static
components without generating an intermediate temporary, and without generating
a loop to initialize individual components. Otherwise, a loop is created for
arrays larger than about 5000 scalar components. Note that if this restriction
is set in the spec of a package, it will not apply to its body.

No_Obsolescent_Features
-----------------------
.. index:: No_Obsolescent_Features

[RM 13.12.1] This restriction checks at compile time that no obsolescent
features are used, as defined in Annex J of the Ada Reference Manual.

No_Wide_Characters
------------------
.. index:: No_Wide_Characters

[GNAT] This restriction ensures at compile time that no uses of the types
``Wide_Character`` or ``Wide_String`` or corresponding wide
wide types
appear, and that no wide or wide wide string or character literals
appear in the program (that is literals representing characters not in
type ``Character``).

Static_Dispatch_Tables
----------------------
.. index:: Static_Dispatch_Tables

[GNAT] This restriction checks at compile time that all the artifacts
associated with dispatch tables can be placed in read-only memory.

SPARK_05
--------
.. index:: SPARK_05

[GNAT] This restriction no longer has any effect and is superseded by
SPARK 2014, whose restrictions are checked by the tool GNATprove. To check that
a codebase respects SPARK 2014 restrictions, mark the code with pragma or
aspect ``SPARK_Mode``, and run the tool GNATprove at Stone assurance level, as
follows::

  gnatprove -P project.gpr --mode=stone

or equivalently::

  gnatprove -P project.gpr --mode=check_all

---

### Gcc Ada Doc Gnat Rm Standard Library Routines (`gcc/ada/doc/gnat_rm/standard_library_routines.rst`)

.. _Standard_Library_Routines:

*************************
Standard Library Routines
*************************

The Ada Reference Manual contains in Annex A a full description of an
extensive set of standard library routines that can be used in any Ada
program, and which must be provided by all Ada compilers.  They are
analogous to the standard C library used by C programs.

GNAT implements all of the facilities described in annex A, and for most
purposes the description in the Ada Reference Manual, or appropriate Ada
text book, will be sufficient for making use of these facilities.

In the case of the input-output facilities,
:ref:`The_Implementation_of_Standard_I/O`,
gives details on exactly how GNAT interfaces to the
file system.  For the remaining packages, the Ada Reference Manual
should be sufficient.  The following is a list of the packages included,
together with a brief description of the functionality that is provided.

For completeness, references are included to other predefined library
routines defined in other sections of the Ada Reference Manual (these are
cross-indexed from Annex A). For further details see the relevant
package declarations in the run-time library. In particular, a few units
are not implemented, as marked by the presence of pragma Unimplemented_Unit,
and in this case the package declaration contains comments explaining why
the unit is not implemented.



``Ada`` *(A.2)*
  This is a parent package for all the standard library packages.  It is
  usually included implicitly in your program, and itself contains no
  useful data or routines.


``Ada.Assertions`` *(11.4.2)*
  ``Assertions`` provides the ``Assert`` subprograms, and also
  the declaration of the ``Assertion_Error`` exception.


``Ada.Asynchronous_Task_Control`` *(D.11)*
  ``Asynchronous_Task_Control`` provides low level facilities for task
  synchronization. It is typically not implemented. See package spec for details.


``Ada.Calendar`` *(9.6)*
  ``Calendar`` provides time of day access, and routines for
  manipulating times and durations.


``Ada.Calendar.Arithmetic`` *(9.6.1)*
  This package provides additional arithmetic
  operations for ``Calendar``.


``Ada.Calendar.Formatting`` *(9.6.1)*
  This package provides formatting operations for ``Calendar``.


``Ada.Calendar.Time_Zones`` *(9.6.1)*
  This package provides additional ``Calendar`` facilities
  for handling time zones.


``Ada.Characters`` *(A.3.1)*
  This is a dummy parent package that contains no useful entities


``Ada.Characters.Conversions`` *(A.3.2)*
  This package provides character conversion functions.


``Ada.Characters.Handling`` *(A.3.2)*
  This package provides some basic character handling capabilities,
  including classification functions for classes of characters (e.g., test
  for letters, or digits).


``Ada.Characters.Latin_1`` *(A.3.3)*
  This package includes a complete set of definitions of the characters
  that appear in type CHARACTER.  It is useful for writing programs that
  will run in international environments.  For example, if you want an
  upper case E with an acute accent in a string, it is often better to use
  the definition of ``UC_E_Acute`` in this package.  Then your program
  will print in an understandable manner even if your environment does not
  support these extended characters.


``Ada.Command_Line`` *(A.15)*
  This package provides access to the command line parameters and the name
  of the current program (analogous to the use of ``argc`` and ``argv``
  in C), and also allows the exit status for the program to be set in a
  system-independent manner.


``Ada.Complex_Text_IO`` *(G.1.3)*
  This package provides text input and output of complex numbers.


``Ada.Containers`` *(A.18.1)*
  A top level package providing a few basic definitions used by all the
  following specific child packages that provide specific kinds of
  containers.

``Ada.Containers.Bounded_Priority_Queues`` *(A.18.31)*

``Ada.Containers.Bounded_Synchronized_Queues`` *(A.18.29)*

``Ada.Containers.Doubly_Linked_Lists`` *(A.18.3)*

``Ada.Containers.Generic_Array_Sort`` *(A.18.26)*

``Ada.Containers.Generic_Constrained_Array_Sort`` *(A.18.26)*

``Ada.Containers.Generic_Sort`` *(A.18.26)*

``Ada.Containers.Hashed_Maps`` *(A.18.5)*

``Ada.Containers.Hashed_Sets`` *(A.18.8)*

``Ada.Containers.Indefinite_Doubly_Linked_Lists`` *(A.18.12)*

``Ada.Containers.Indefinite_Hashed_Maps`` *(A.18.13)*

``Ada.Containers.Indefinite_Hashed_Sets`` *(A.18.15)*

``Ada.Containers.Indefinite_Holders`` *(A.18.18)*

``Ada.Containers.Indefinite_Multiway_Trees`` *(A.18.17)*

``Ada.Containers.Indefinite_Ordered_Maps`` *(A.18.14)*

``Ada.Containers.Indefinite_Ordered_Sets`` *(A.18.16)*

``Ada.Containers.Indefinite_Vectors`` *(A.18.11)*

``Ada.Containers.Multiway_Trees`` *(A.18.10)*

``Ada.Containers.Ordered_Maps`` *(A.18.6)*

``Ada.Containers.Ordered_Sets`` *(A.18.9)*

``Ada.Containers.Synchronized_Queue_Interfaces`` *(A.18.27)*

``Ada.Containers.Unbounded_Priority_Queues`` *(A.18.30)*

``Ada.Containers.Unbounded_Synchronized_Queues`` *(A.18.28)*

``Ada.Containers.Vectors`` *(A.18.2)*

``Ada.Directories`` *(A.16)*
  This package provides operations on directories.


``Ada.Directories.Hierarchical_File_Names`` *(A.16.1)*
  This package provides additional directory operations handling
  hierarchical file names.


``Ada.Directories.Information`` *(A.16)*
  This is an implementation defined package for additional directory
  operations, which is not implemented in GNAT.


``Ada.Decimal`` *(F.2)*
  This package provides constants describing the range of decimal numbers
  implemented, and also a decimal divide routine (analogous to the COBOL
  verb DIVIDE ... GIVING ... REMAINDER ...)


``Ada.Direct_IO`` *(A.8.4)*
  This package provides input-output using a model of a set of records of
  fixed-length, containing an arbitrary definite Ada type, indexed by an
  integer record number.


``Ada.Dispatching`` *(D.2.1)*
  A parent package containing definitions for task dispatching operations.


``Ada.Dispatching.EDF`` *(D.2.6)*
  Not implemented in GNAT.


``Ada.Dispatching.Non_Preemptive`` *(D.2.4)*
  Not implemented in GNAT.


``Ada.Dispatching.Round_Robin`` *(D.2.5)*
  Not implemented in GNAT.


``Ada.Dynamic_Priorities`` *(D.5)*
  This package allows the priorities of a task to be adjusted dynamically
  as the task is running.


``Ada.Environment_Variables`` *(A.17)*
  This package provides facilities for accessing environment variables.


``Ada.Exceptions`` *(11.4.1)*
  This package provides additional information on exceptions, and also
  contains facilities for treating exceptions as data objects, and raising
  exceptions with associated messages.


``Ada.Execution_Time`` *(D.14)*
  This package provides CPU clock functionalities. It is not implemented on
  all targets (see package spec for details).


``Ada.Execution_Time.Group_Budgets`` *(D.14.2)*
  Not implemented in GNAT.


``Ada.Execution_Time.Timers`` *(D.14.1)'*
  Not implemented in GNAT.


``Ada.Finalization`` *(7.6)*
  This package contains the declarations and subprograms to support the
  use of controlled types, providing for automatic initialization and
  finalization (analogous to the constructors and destructors of C++).


``Ada.Float_Text_IO`` *(A.10.9)*
  A library level instantiation of Text_IO.Float_IO for type Float.


``Ada.Float_Wide_Text_IO`` *(A.10.9)*
  A library level instantiation of Wide_Text_IO.Float_IO for type Float.


``Ada.Float_Wide_Wide_Text_IO`` *(A.10.9)*
  A library level instantiation of Wide_Wide_Text_IO.Float_IO for type Float.


``Ada.Integer_Text_IO`` *(A.10.9)*
  A library level instantiation of Text_IO.Integer_IO for type Integer.


``Ada.Integer_Wide_Text_IO`` *(A.10.9)*
  A library level instantiation of Wide_Text_IO.Integer_IO for type Integer.


``Ada.Integer_Wide_Wide_Text_IO`` *(A.10.9)*
  A library level instantiation of Wide_Wide_Text_IO.Integer_IO for type Integer.


``Ada.Interrupts`` *(C.3.2)*
  This package provides facilities for interfacing to interrupts, which
  includes the set of signals or conditions that can be raised and
  recognized as interrupts.


``Ada.Interrupts.Names`` *(C.3.2)*
  This package provides the set of interrupt names (actually signal
  or condition names) that can be handled by GNAT.


``Ada.IO_Exceptions`` *(A.13)*
  This package defines the set of exceptions that can be raised by use of
  the standard IO packages.


``Ada.Iterator_Interfaces`` *(5.5.1)*
  This package provides a generic interface to generalized iterators.


``Ada.Locales`` *(A.19)*
  This package provides declarations providing information (Language
  and Country) about the current locale.


``Ada.Numerics``
  This package contains some standard constants and exceptions used
  throughout the numerics packages.  Note that the constants pi and e are
  defined here, and it is better to use these definitions than rolling
  your own.


``Ada.Numerics.Complex_Arrays`` *(G.3.2)*
  Provides operations on arrays of complex numbers.


``Ada.Numerics.Complex_Elementary_Functions``
  Provides the implementation of standard elementary functions (such as
  log and trigonometric functions) operating on complex numbers using the
  standard ``Float`` and the ``Complex`` and ``Imaginary`` types
  created by the package ``Numerics.Complex_Types``.


``Ada.Numerics.Complex_Types``
  This is a predefined instantiation of
  ``Numerics.Generic_Complex_Types`` using ``Standard.Float`` to
  build the type ``Complex`` and ``Imaginary``.


``Ada.Numerics.Discrete_Random``
  This generic package provides a random number generator suitable for generating
  uniformly distributed values of a specified discrete subtype. It should not be
  used as a cryptographic pseudo-random source.


``Ada.Numerics.Float_Random``
  This package provides a random number generator suitable for generating
  uniformly distributed floating point values in the unit interval. It should not
  be used as a cryptographic pseudo-random source.


``Ada.Numerics.Generic_Complex_Elementary_Functions``
  This is a generic version of the package that provides the
  implementation of standard elementary functions (such as log and
  trigonometric functions) for an arbitrary complex type.

  The following predefined instantiations of this package are provided:

  * ``Short_Float``

    ``Ada.Numerics.Short_Complex_Elementary_Functions``

  * ``Float``

    ``Ada.Numerics.Complex_Elementary_Functions``

  * ``Long_Float``

    ``Ada.Numerics.Long_Complex_Elementary_Functions``

``Ada.Numerics.Generic_Complex_Types``
  This is a generic package that allows the creation of complex types,
  with associated complex arithmetic operations.

  The following predefined instantiations of this package exist

  * ``Short_Float``

    ``Ada.Numerics.Short_Complex_Complex_Types``

  * ``Float``

    ``Ada.Numerics.Complex_Complex_Types``

  * ``Long_Float``

    ``Ada.Numerics.Long_Complex_Complex_Types``

``Ada.Numerics.Generic_Elementary_Functions``
  This is a generic package that provides the implementation of standard
  elementary functions (such as log an trigonometric functions) for an
  arbitrary float type.

  The following predefined instantiations of this package exist

  * ``Short_Float``

    ``Ada.Numerics.Short_Elementary_Functions``

  * ``Float``

    ``Ada.Numerics.Elementary_Functions``

  * ``Long_Float``

    ``Ada.Numerics.Long_Elementary_Functions``

``Ada.Numerics.Generic_Real_Arrays`` *(G.3.1)*
  Generic operations on arrays of reals

``Ada.Numerics.Real_Arrays`` *(G.3.1)*
  Preinstantiation of Ada.Numerics.Generic_Real_Arrays (Float).

``Ada.Real_Time`` *(D.8)*
  This package provides facilities similar to those of ``Calendar``, but
  operating with a finer clock suitable for real time control. Note that
  annex D requires that there be no backward clock jumps, and GNAT generally
  guarantees this behavior, but of course if the external clock on which
  the GNAT runtime depends is deliberately reset by some external event,
  then such a backward jump may occur.

``Ada.Real_Time.Timing_Events`` *(D.15)*
  This package allows procedures to be executed at a specified time without
  the use of a task or a delay statement.

``Ada.Sequential_IO`` *(A.8.1)*
  This package provides input-output facilities for sequential files,
  which can contain a sequence of values of a single type, which can be
  any Ada type, including indefinite (unconstrained) types.

``Ada.Storage_IO`` *(A.9)*
  This package provides a facility for mapping arbitrary Ada types to and
  from a storage buffer.  It is primarily intended for the creation of new
  IO packages.

``Ada.Streams`` *(13.13.1)*
  This is a generic package that provides the basic support for the
  concept of streams as used by the stream attributes (``Input``,
  ``Output``, ``Read`` and ``Write``).

``Ada.Streams.Stream_IO`` *(A.12.1)*
  This package is a specialization of the type ``Streams`` defined in
  package ``Streams`` together with a set of operations providing
  Stream_IO capability.  The Stream_IO model permits both random and
  sequential access to a file which can contain an arbitrary set of values
  of one or more Ada types.

``Ada.Strings`` *(A.4.1)*
  This package provides some basic constants used by the string handling
  packages.


``Ada.Strings.Bounded`` *(A.4.4)*
  This package provides facilities for handling variable length
  strings.  The bounded model requires a maximum length.  It is thus
  somewhat more limited than the unbounded model, but avoids the use of
  dynamic allocation or finalization.

``Ada.Strings.Bounded.Equal_Case_Insensitive`` *(A.4.10)*
  Provides case-insensitive comparisons of bounded strings

``Ada.Strings.Bounded.Hash`` *(A.4.9)*
  This package provides a generic hash function for bounded strings

``Ada.Strings.Bounded.Hash_Case_Insensitive`` *(A.4.9)*
  This package provides a generic hash function for bounded strings that
  converts the string to be hashed to lower case.

``Ada.Strings.Bounded.Less_Case_Insensitive`` *(A.4.10)*
  This package provides a comparison function for bounded strings that works
  in a case insensitive manner by converting to lower case before the comparison.

``Ada.Strings.Fixed`` *(A.4.3)*
  This package provides facilities for handling fixed length strings.

``Ada.Strings.Fixed.Equal_Case_Insensitive`` *(A.4.10)*
  This package provides an equality function for fixed strings that compares
  the strings after converting both to lower case.

``Ada.Strings.Fixed.Hash_Case_Insensitive`` *(A.4.9)*
  This package provides a case insensitive hash function for fixed strings that
  converts the string to lower case before computing the hash.

``Ada.Strings.Fixed.Less_Case_Insensitive`` *(A.4.10)*
  This package provides a comparison function for fixed strings that works
  in a case insensitive manner by converting to lower case before the comparison.

``Ada.Strings.Hash`` *(A.4.9)*
  This package provides a hash function for strings.

``Ada.Strings.Hash_Case_Insensitive`` *(A.4.9)*
  This package provides a hash function for strings that is case insensitive.
  The string is converted to lower case before computing the hash.

``Ada.Strings.Less_Case_Insensitive`` *(A.4.10)*
  This package provides a comparison function for\\strings that works
  in a case insensitive manner by converting to lower case before the comparison.

``Ada.Strings.Maps`` *(A.4.2)*
  This package provides facilities for handling character mappings and
  arbitrarily defined subsets of characters.  For instance it is useful in
  defining specialized translation tables.

``Ada.Strings.Maps.Constants`` *(A.4.6)*
  This package provides a standard set of predefined mappings and
  predefined character sets.  For example, the standard upper to lower case
  conversion table is found in this package.  Note that upper to lower case
  conversion is non-trivial if you want to take the entire set of
  characters, including extended characters like E with an acute accent,
  into account.  You should use the mappings in this package (rather than
  adding 32 yourself) to do case mappings.

``Ada.Strings.Unbounded`` *(A.4.5)*
  This package provides facilities for handling variable length
  strings.  The unbounded model allows arbitrary length strings, but
  requires the use of dynamic allocation and finalization.

``Ada.Strings.Unbounded.Equal_Case_Insensitive`` *(A.4.10)*
  Provides case-insensitive comparisons of unbounded strings

``Ada.Strings.Unbounded.Hash`` *(A.4.9)*
  This package provides a generic hash function for unbounded strings

``Ada.Strings.Unbounded.Hash_Case_Insensitive`` *(A.4.9)*
  This package provides a generic hash function for unbounded strings that
  converts the string to be hashed to lower case.

``Ada.Strings.Unbounded.Less_Case_Insensitive`` *(A.4.10)*
  This package provides a comparison function for unbounded strings that works
  in a case insensitive manner by converting to lower case before the comparison.

``Ada.Strings.UTF_Encoding`` *(A.4.11)*
  This package provides basic definitions for dealing with UTF-encoded strings.

``Ada.Strings.UTF_Encoding.Conversions`` *(A.4.11)*
  This package provides conversion functions for UTF-encoded strings.

``Ada.Strings.UTF_Encoding.Strings`` *(A.4.11)*

``Ada.Strings.UTF_Encoding.Wide_Strings`` *(A.4.11)*

``Ada.Strings.UTF_Encoding.Wide_Wide_Strings`` *(A.4.11)*
  These packages provide facilities for handling UTF encodings for
  Strings, Wide_Strings and Wide_Wide_Strings.

``Ada.Strings.Wide_Bounded`` *(A.4.7)*

``Ada.Strings.Wide_Fixed`` *(A.4.7)*

``Ada.Strings.Wide_Maps`` *(A.4.7)*

``Ada.Strings.Wide_Unbounded`` *(A.4.7)*
  These packages provide analogous capabilities to the corresponding
  packages without ``Wide_`` in the name, but operate with the types
  ``Wide_String`` and ``Wide_Character`` instead of ``String``
  and ``Character``. Versions of all the child packages are available.

``Ada.Strings.Wide_Wide_Bounded`` *(A.4.7)*

``Ada.Strings.Wide_Wide_Fixed`` *(A.4.7)*

``Ada.Strings.Wide_Wide_Maps`` *(A.4.7)*

``Ada.Strings.Wide_Wide_Unbounded`` *(A.4.7)*
  These packages provide analogous capabilities to the corresponding
  packages without ``Wide_`` in the name, but operate with the types
  ``Wide_Wide_String`` and ``Wide_Wide_Character`` instead
  of ``String`` and ``Character``.

``Ada.Synchronous_Barriers`` *(D.10.1)*
  This package provides facilities for synchronizing tasks at a low level
  with barriers.

``Ada.Synchronous_Task_Control`` *(D.10)*
  This package provides some standard facilities for controlling task
  communication in a synchronous manner.

``Ada.Synchronous_Task_Control.EDF`` *(D.10)*
  Not implemented in GNAT.

``Ada.Tags``
  This package contains definitions for manipulation of the tags of tagged
  values.

``Ada.Tags.Generic_Dispatching_Constructor`` *(3.9)*
  This package provides a way of constructing tagged class-wide values given
  only the tag value.

``Ada.Task_Attributes`` *(C.7.2)*
  This package provides the capability of associating arbitrary
  task-specific data with separate tasks.

``Ada.Task_Identification`` *(C.7.1)*
  This package provides capabilities for task identification.

``Ada.Task_Termination`` *(C.7.3)*
  This package provides control over task termination.

``Ada.Text_IO``
  This package provides basic text input-output capabilities for
  character, string and numeric data.  The subpackages of this
  package are listed next. Note that although these are defined
  as subpackages in the RM, they are actually transparently
  implemented as child packages in GNAT, meaning that they
  are only loaded if needed.

``Ada.Text_IO.Decimal_IO``
  Provides input-output facilities for decimal fixed-point types

``Ada.Text_IO.Enumeration_IO``
  Provides input-output facilities for enumeration types.

``Ada.Text_IO.Fixed_IO``
  Provides input-output facilities for ordinary fixed-point types.

``Ada.Text_IO.Float_IO``
  Provides input-output facilities for float types.  The following
  predefined instantiations of this generic package are available:

  * ``Short_Float``

    ``Short_Float_Text_IO``

  * ``Float``

    ``Float_Text_IO``

  * ``Long_Float``

    ``Long_Float_Text_IO``

``Ada.Text_IO.Integer_IO``
  Provides input-output facilities for integer types.  The following
  predefined instantiations of this generic package are available:

  * ``Short_Short_Integer``

    ``Ada.Short_Short_Integer_Text_IO``

  * ``Short_Integer``

    ``Ada.Short_Integer_Text_IO``

  * ``Integer``

    ``Ada.Integer_Text_IO``

  * ``Long_Integer``

    ``Ada.Long_Integer_Text_IO``

  * ``Long_Long_Integer``

    ``Ada.Long_Long_Integer_Text_IO``

``Ada.Text_IO.Modular_IO``
  Provides input-output facilities for modular (unsigned) types.

``Ada.Text_IO.Bounded_IO (A.10.11)``
  Provides input-output facilities for bounded strings.

``Ada.Text_IO.Complex_IO (G.1.3)``
  This package provides basic text input-output capabilities for complex
  data.

``Ada.Text_IO.Editing (F.3.3)``
  This package contains routines for edited output, analogous to the use
  of pictures in COBOL.  The picture formats used by this package are a
  close copy of the facility in COBOL.

``Ada.Text_IO.Text_Streams (A.12.2)``
  This package provides a facility that allows Text_IO files to be treated
  as streams, so that the stream attributes can be used for writing
  arbitrary data, including binary data, to Text_IO files.

``Ada.Text_IO.Unbounded_IO (A.10.12)``
  This package provides input-output facilities for unbounded strings.

``Ada.Unchecked_Conversion (13.9)``
  This generic package allows arbitrary conversion from one type to
  another of the same size, providing for breaking the type safety in
  special circumstances.

  If the types have the same Size (more accurately the same Value_Size),
  then the effect is simply to transfer the bits from the source to the
  target type without any modification.  This usage is well defined, and
  for simple types whose representation is typically the same across
  all implementations, gives a portable method of performing such
  conversions.

  If the types do not have the same size, then the result is implementation
  defined, and thus may be non-portable.  The following describes how GNAT
  handles such unchecked conversion cases.

  If the types are of different sizes, and are both discrete types, then
  the effect is of a normal type conversion without any constraint checking.
  In particular if the result type has a larger size, the result will be
  zero or sign extended.  If the result type has a smaller size, the result
  will be truncated by ignoring high order bits.

  If the types are of different sizes, and are not both discrete types,
  then the conversion works as though pointers were created to the source
  and target, and the pointer value is converted.  The effect is that bits
  are copied from successive low order storage units and bits of the source
  up to the length of the target type.

  A warning is issued if the lengths differ, since the effect in this
  case is implementation dependent, and the above behavior may not match
  that of some other compiler.

  A pointer to one type may be converted to a pointer to another type using
  unchecked conversion.  The only case in which the effect is undefined is
  when one or both pointers are pointers to unconstrained array types.  In
  this case, the bounds information may get incorrectly transferred, and in
  particular, GNAT uses double size pointers for such types, and it is
  meaningless to convert between such pointer types.  GNAT will issue a
  warning if the alignment of the target designated type is more strict
  than the alignment of the source designated type (since the result may
  be unaligned in this case).

  A pointer other than a pointer to an unconstrained array type may be
  converted to and from System.Address.  Such usage is common in Ada 83
  programs, but note that Ada.Address_To_Access_Conversions is the
  preferred method of performing such conversions in Ada 95 and Ada 2005.
  Neither
  unchecked conversion nor Ada.Address_To_Access_Conversions should be
  used in conjunction with pointers to unconstrained objects, since
  the bounds information cannot be handled correctly in this case.

``Ada.Unchecked_Deallocation`` *(13.11.2)*
  This generic package allows explicit freeing of storage previously
  allocated by use of an allocator.

``Ada.Wide_Text_IO`` *(A.11)*
  This package is similar to ``Ada.Text_IO``, except that the external
  file supports wide character representations, and the internal types are
  ``Wide_Character`` and ``Wide_String`` instead of ``Character``
  and ``String``. The corresponding set of nested packages and child
  packages are defined.

``Ada.Wide_Wide_Text_IO`` *(A.11)*
  This package is similar to ``Ada.Text_IO``, except that the external
  file supports wide character representations, and the internal types are
  ``Wide_Character`` and ``Wide_String`` instead of ``Character``
  and ``String``. The corresponding set of nested packages and child
  packages are defined.

For packages in Interfaces and System, all the RM defined packages are
available in GNAT, see the Ada 2012 RM for full details.

---

### Gcc Ada Doc Gnat Rm The Gnat Library (`gcc/ada/doc/gnat_rm/the_gnat_library.rst`)

.. role:: switch(samp)

.. _The_GNAT_Library:

****************
The GNAT Library
****************

The GNAT library contains a number of general and special purpose packages.
It represents functionality that the GNAT developers have found useful, and
which is made available to GNAT users.  The packages described here are fully
supported, and upwards compatibility will be maintained in future releases,
so you can use these facilities with the confidence that the same functionality
will be available in future releases.

The chapter here simply gives a brief summary of the facilities available.
The full documentation is found in the spec file for the package.  The full
sources of these library packages, including both spec and body, are provided
with all GNAT releases.  For example, to find out the full specifications of
the SPITBOL pattern matching capability, including a full tutorial and
extensive examples, look in the :file:`g-spipat.ads` file in the library.

For each entry here, the package name (as it would appear in a ``with``
clause) is given, followed by the name of the corresponding spec file in
parentheses.  The packages are children in four hierarchies, ``Ada``,
``Interfaces``, ``System``, and ``GNAT``, the latter being a
GNAT-specific hierarchy.

Note that an application program should only use packages in one of these
four hierarchies if the package is defined in the Ada Reference Manual,
or is listed in this section of the GNAT Programmers Reference Manual.
All other units should be considered internal implementation units and
should not be directly ``with``\ ed by application code.  The use of
a ``with`` clause that references one of these internal implementation
units makes an application potentially dependent on changes in versions
of GNAT, and will generate a warning message.

.. _`Ada.Characters.Latin_9_(a-chlat9.ads)`:

``Ada.Characters.Latin_9`` (:file:`a-chlat9.ads`)
=================================================

.. index:: Ada.Characters.Latin_9 (a-chlat9.ads)

.. index:: Latin_9 constants for Character

This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
RM-defined package ``Ada.Characters.Latin_1`` but with the
few modifications required for ``Latin-9``.
The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).

.. _`Ada.Characters.Wide_Latin_1_(a-cwila1.ads)`:

``Ada.Characters.Wide_Latin_1`` (:file:`a-cwila1.ads`)
======================================================

.. index:: Ada.Characters.Wide_Latin_1 (a-cwila1.ads)

.. index:: Latin_1 constants for Wide_Character

This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
RM-defined package ``Ada.Characters.Latin_1`` but with the
types of the constants being ``Wide_Character``
instead of ``Character``.  The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).

.. _`Ada.Characters.Wide_Latin_9_(a-cwila9.ads)`:

``Ada.Characters.Wide_Latin_9`` (:file:`a-cwila9.ads`)
======================================================

.. index:: Ada.Characters.Wide_Latin_9 (a-cwila9.ads)

.. index:: Latin_9 constants for Wide_Character

This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
GNAT defined package ``Ada.Characters.Latin_9`` but with the
types of the constants being ``Wide_Character``
instead of ``Character``.  The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).

.. _`Ada.Characters.Wide_Wide_Latin_1_(a-chzla1.ads)`:

``Ada.Characters.Wide_Wide_Latin_1`` (:file:`a-chzla1.ads`)
===========================================================

.. index:: Ada.Characters.Wide_Wide_Latin_1 (a-chzla1.ads)

.. index:: Latin_1 constants for Wide_Wide_Character

This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
RM-defined package ``Ada.Characters.Latin_1`` but with the
types of the constants being ``Wide_Wide_Character``
instead of ``Character``.  The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).

.. _`Ada.Characters.Wide_Wide_Latin_9_(a-chzla9.ads)`:

``Ada.Characters.Wide_Wide_Latin_9`` (:file:`a-chzla9.ads`)
===========================================================

.. index:: Ada.Characters.Wide_Wide_Latin_9 (a-chzla9.ads)

.. index:: Latin_9 constants for Wide_Wide_Character

This child of ``Ada.Characters``
provides a set of definitions corresponding to those in the
GNAT defined package ``Ada.Characters.Latin_9`` but with the
types of the constants being ``Wide_Wide_Character``
instead of ``Character``.  The provision of such a package
is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).

.. _`Ada.Containers.Bounded_Holders_(a-coboho.ads)`:

``Ada.Containers.Bounded_Holders`` (:file:`a-coboho.ads`)
=========================================================

.. index:: Ada.Containers.Bounded_Holders (a-coboho.ads)

.. index:: Formal container for vectors

This child of ``Ada.Containers`` defines a modified version of
Indefinite_Holders that avoids heap allocation.

.. _`Ada.Command_Line.Environment_(a-colien.ads)`:

``Ada.Command_Line.Environment`` (:file:`a-colien.ads`)
=======================================================

.. index:: Ada.Command_Line.Environment (a-colien.ads)

.. index:: Environment entries

This child of ``Ada.Command_Line``
provides a mechanism for obtaining environment values on systems
where this concept makes sense.

.. _`Ada.Command_Line.Remove_(a-colire.ads)`:

``Ada.Command_Line.Remove`` (:file:`a-colire.ads`)
==================================================

.. index:: Ada.Command_Line.Remove (a-colire.ads)

.. index:: Removing command line arguments

.. index:: Command line, argument removal

This child of ``Ada.Command_Line``
provides a mechanism for logically removing
arguments from the argument list.  Once removed, an argument is not visible
to further calls to the subprograms in ``Ada.Command_Line``. These calls
will not see the removed argument.

.. _`Ada.Command_Line.Response_File_(a-clrefi.ads)`:

``Ada.Command_Line.Response_File`` (:file:`a-clrefi.ads`)
=========================================================

.. index:: Ada.Command_Line.Response_File (a-clrefi.ads)

.. index:: Response file for command line

.. index:: Command line, response file

.. index:: Command line, handling long command lines

This child of ``Ada.Command_Line`` provides a mechanism facilities for
getting command line arguments from a text file, called a "response file".
Using a response file allow passing a set of arguments to an executable longer
than the maximum allowed by the system on the command line.

.. _`Ada.Direct_IO.C_Streams_(a-diocst.ads)`:

``Ada.Direct_IO.C_Streams`` (:file:`a-diocst.ads`)
==================================================

.. index:: Ada.Direct_IO.C_Streams (a-diocst.ads)

.. index:: C Streams, Interfacing with Direct_IO

This package provides subprograms that allow interfacing between
C streams and ``Direct_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Exceptions.Is_Null_Occurrence_(a-einuoc.ads)`:

``Ada.Exceptions.Is_Null_Occurrence`` (:file:`a-einuoc.ads`)
============================================================

.. index:: Ada.Exceptions.Is_Null_Occurrence (a-einuoc.ads)

.. index:: Null_Occurrence, testing for

This child subprogram provides a way of testing for the null
exception occurrence (``Null_Occurrence``) without raising
an exception.

.. _`Ada.Exceptions.Last_Chance_Handler_(a-elchha.ads)`:

``Ada.Exceptions.Last_Chance_Handler`` (:file:`a-elchha.ads`)
=============================================================

.. index:: Ada.Exceptions.Last_Chance_Handler (a-elchha.ads)

.. index:: Null_Occurrence, testing for

This child subprogram is used for handling otherwise unhandled
exceptions (hence the name last chance), and perform clean ups before
terminating the program. Note that this subprogram never returns.

.. _`Ada.Exceptions.Traceback_(a-exctra.ads)`:

``Ada.Exceptions.Traceback`` (:file:`a-exctra.ads`)
===================================================

.. index:: Ada.Exceptions.Traceback (a-exctra.ads)

.. index:: Traceback for Exception Occurrence

This child package provides the subprogram (``Tracebacks``) to
give a traceback array of addresses based on an exception
occurrence.

.. _`Ada.Sequential_IO.C_Streams_(a-siocst.ads)`:

``Ada.Sequential_IO.C_Streams`` (:file:`a-siocst.ads`)
======================================================

.. index:: Ada.Sequential_IO.C_Streams (a-siocst.ads)

.. index:: C Streams, Interfacing with Sequential_IO

This package provides subprograms that allow interfacing between
C streams and ``Sequential_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Streams.Stream_IO.C_Streams_(a-ssicst.ads)`:

``Ada.Streams.Stream_IO.C_Streams`` (:file:`a-ssicst.ads`)
==========================================================

.. index:: Ada.Streams.Stream_IO.C_Streams (a-ssicst.ads)

.. index:: C Streams, Interfacing with Stream_IO

This package provides subprograms that allow interfacing between
C streams and ``Stream_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Strings.Unbounded.Text_IO_(a-suteio.ads)`:

``Ada.Strings.Unbounded.Text_IO`` (:file:`a-suteio.ads`)
========================================================

.. index:: Ada.Strings.Unbounded.Text_IO (a-suteio.ads)

.. index:: Unbounded_String, IO support

.. index:: Text_IO, extensions for unbounded strings

This package provides subprograms for Text_IO for unbounded
strings, avoiding the necessity for an intermediate operation
with ordinary strings.

.. _`Ada.Strings.Wide_Unbounded.Wide_Text_IO_(a-swuwti.ads)`:

``Ada.Strings.Wide_Unbounded.Wide_Text_IO`` (:file:`a-swuwti.ads`)
==================================================================

.. index:: Ada.Strings.Wide_Unbounded.Wide_Text_IO (a-swuwti.ads)

.. index:: Unbounded_Wide_String, IO support

.. index:: Text_IO, extensions for unbounded wide strings

This package provides subprograms for Text_IO for unbounded
wide strings, avoiding the necessity for an intermediate operation
with ordinary wide strings.

.. _`Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO_(a-szuzti.ads)`:

``Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO`` (:file:`a-szuzti.ads`)
============================================================================

.. index:: Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO (a-szuzti.ads)

.. index:: Unbounded_Wide_Wide_String, IO support

.. index:: Text_IO, extensions for unbounded wide wide strings

This package provides subprograms for Text_IO for unbounded
wide wide strings, avoiding the necessity for an intermediate operation
with ordinary wide wide strings.

.. _`Ada.Task_Initialization_(a-tasini.ads)`:

``Ada.Task_Initialization`` (:file:`a-tasini.ads`)
==================================================

.. index:: Ada.Task_Initialization (a-tasini.ads)

This package provides a way to set a global initialization handler that
is automatically invoked whenever a task is activated. Handlers are
parameterless procedures. Note that such a handler is only invoked for
those tasks activated after the handler is set.

.. _`Ada.Text_IO.C_Streams_(a-tiocst.ads)`:

``Ada.Text_IO.C_Streams`` (:file:`a-tiocst.ads`)
================================================

.. index:: Ada.Text_IO.C_Streams (a-tiocst.ads)

.. index:: C Streams, Interfacing with ``Text_IO``

This package provides subprograms that allow interfacing between
C streams and ``Text_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Text_IO.Reset_Standard_Files_(a-tirsfi.ads)`:

``Ada.Text_IO.Reset_Standard_Files`` (:file:`a-tirsfi.ads`)
===========================================================

.. index:: Ada.Text_IO.Reset_Standard_Files (a-tirsfi.ads)

.. index:: Text_IO resetting standard files

This procedure is used to reset the status of the standard files used
by Ada.Text_IO.  This is useful in a situation (such as a restart in an
embedded application) where the status of the files may change during
execution (for example a standard input file may be redefined to be
interactive).

.. _`Ada.Wide_Characters.Unicode_(a-wichun.ads)`:

``Ada.Wide_Characters.Unicode`` (:file:`a-wichun.ads`)
======================================================

.. index:: Ada.Wide_Characters.Unicode (a-wichun.ads)

.. index:: Unicode categorization, Wide_Character

This package provides subprograms that allow categorization of
Wide_Character values according to Unicode categories.

.. _`Ada.Wide_Text_IO.C_Streams_(a-wtcstr.ads)`:

``Ada.Wide_Text_IO.C_Streams`` (:file:`a-wtcstr.ads`)
=====================================================

.. index:: Ada.Wide_Text_IO.C_Streams (a-wtcstr.ads)

.. index:: C Streams, Interfacing with ``Wide_Text_IO``

This package provides subprograms that allow interfacing between
C streams and ``Wide_Text_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Wide_Text_IO.Reset_Standard_Files_(a-wrstfi.ads)`:

``Ada.Wide_Text_IO.Reset_Standard_Files`` (:file:`a-wrstfi.ads`)
================================================================

.. index:: Ada.Wide_Text_IO.Reset_Standard_Files (a-wrstfi.ads)

.. index:: Wide_Text_IO resetting standard files

This procedure is used to reset the status of the standard files used
by Ada.Wide_Text_IO.  This is useful in a situation (such as a restart in an
embedded application) where the status of the files may change during
execution (for example a standard input file may be redefined to be
interactive).

.. _`Ada.Wide_Wide_Characters.Unicode_(a-zchuni.ads)`:

``Ada.Wide_Wide_Characters.Unicode`` (:file:`a-zchuni.ads`)
===========================================================

.. index:: Ada.Wide_Wide_Characters.Unicode (a-zchuni.ads)

.. index:: Unicode categorization, Wide_Wide_Character

This package provides subprograms that allow categorization of
Wide_Wide_Character values according to Unicode categories.

.. _`Ada.Wide_Wide_Text_IO.C_Streams_(a-ztcstr.ads)`:

``Ada.Wide_Wide_Text_IO.C_Streams`` (:file:`a-ztcstr.ads`)
==========================================================

.. index:: Ada.Wide_Wide_Text_IO.C_Streams (a-ztcstr.ads)

.. index:: C Streams, Interfacing with ``Wide_Wide_Text_IO``

This package provides subprograms that allow interfacing between
C streams and ``Wide_Wide_Text_IO``.  The stream identifier can be
extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.

.. _`Ada.Wide_Wide_Text_IO.Reset_Standard_Files_(a-zrstfi.ads)`:

``Ada.Wide_Wide_Text_IO.Reset_Standard_Files`` (:file:`a-zrstfi.ads`)
=====================================================================

.. index:: Ada.Wide_Wide_Text_IO.Reset_Standard_Files (a-zrstfi.ads)

.. index:: Wide_Wide_Text_IO resetting standard files

This procedure is used to reset the status of the standard files used
by Ada.Wide_Wide_Text_IO. This is useful in a situation (such as a
restart in an embedded application) where the status of the files may
change during execution (for example a standard input file may be
redefined to be interactive).

.. _`GNAT.Altivec_(g-altive.ads)`:

``GNAT.Altivec`` (:file:`g-altive.ads`)
=======================================

.. index:: GNAT.Altivec (g-altive.ads)

.. index:: AltiVec

This is the root package of the GNAT AltiVec binding. It provides
definitions of constants and types common to all the versions of the
binding.

.. _`GNAT.Altivec.Conversions_(g-altcon.ads)`:

``GNAT.Altivec.Conversions`` (:file:`g-altcon.ads`)
===================================================

.. index:: GNAT.Altivec.Conversions (g-altcon.ads)

.. index:: AltiVec

This package provides the Vector/View conversion routines.

.. _`GNAT.Altivec.Vector_Operations_(g-alveop.ads)`:

``GNAT.Altivec.Vector_Operations`` (:file:`g-alveop.ads`)
=========================================================

.. index:: GNAT.Altivec.Vector_Operations (g-alveop.ads)

.. index:: AltiVec

This package exposes the Ada interface to the AltiVec operations on
vector objects. A soft emulation is included by default in the GNAT
library. The hard binding is provided as a separate package. This unit
is common to both bindings.

.. _`GNAT.Altivec.Vector_Types_(g-alvety.ads)`:

``GNAT.Altivec.Vector_Types`` (:file:`g-alvety.ads`)
====================================================

.. index:: GNAT.Altivec.Vector_Types (g-alvety.ads)

.. index:: AltiVec

This package exposes the various vector types part of the Ada binding
to AltiVec facilities.

.. _`GNAT.Altivec.Vector_Views_(g-alvevi.ads)`:

``GNAT.Altivec.Vector_Views`` (:file:`g-alvevi.ads`)
====================================================

.. index:: GNAT.Altivec.Vector_Views (g-alvevi.ads)

.. index:: AltiVec

This package provides public 'View' data types from/to which private
vector representations can be converted via
GNAT.Altivec.Conversions. This allows convenient access to individual
vector elements and provides a simple way to initialize vector
objects.

.. _`GNAT.Array_Split_(g-arrspl.ads)`:

``GNAT.Array_Split`` (:file:`g-arrspl.ads`)
===========================================

.. index:: GNAT.Array_Split (g-arrspl.ads)

.. index:: Array splitter

Useful array-manipulation routines: given a set of separators, split
an array wherever the separators appear, and provide direct access
to the resulting slices.

.. _`GNAT.AWK_(g-awk.ads)`:

``GNAT.AWK`` (:file:`g-awk.ads`)
================================

.. index:: GNAT.AWK (g-awk.ads)

.. index:: Parsing

.. index:: AWK

Provides AWK-like parsing functions, with an easy interface for parsing one
or more files containing formatted data.  The file is viewed as a database
where each record is a line and a field is a data element in this line.

.. _`GNAT.Binary_Search_(g-binsea.ads)`:

``GNAT.Binary_Search`` (:file:`g-binsea.ads`)
================================================

.. index:: GNAT.Binary_Search (g-binsea.ads)

.. index:: Binary search

Allow binary search of a sorted array (or of an array-like container;
the generic does not reference the array directly).

.. _`GNAT.Bind_Environment_(g-binenv.ads)`:

``GNAT.Bind_Environment`` (:file:`g-binenv.ads`)
================================================

.. index:: GNAT.Bind_Environment (g-binenv.ads)

.. index:: Bind environment

Provides access to key=value associations captured at bind time.
These associations can be specified using the :switch:`-V` binder command
line switch.

.. _`GNAT.Branch_Prediction_(g-brapre.ads)`:

``GNAT.Branch_Prediction`` (:file:`g-brapre.ads`)
=================================================

.. index:: GNAT.Branch_Prediction (g-brapre.ads)

.. index:: Branch Prediction

Provides routines giving hints to the branch predictor of the code generator.

.. _`GNAT.Bounded_Buffers_(g-boubuf.ads)`:

``GNAT.Bounded_Buffers`` (:file:`g-boubuf.ads`)
===============================================

.. index:: GNAT.Bounded_Buffers (g-boubuf.ads)

.. index:: Parsing

.. index:: Bounded Buffers

Provides a concurrent generic bounded buffer abstraction.  Instances are
useful directly or as parts of the implementations of other abstractions,
such as mailboxes.

.. _`GNAT.Bounded_Mailboxes_(g-boumai.ads)`:

``GNAT.Bounded_Mailboxes`` (:file:`g-boumai.ads`)
=================================================

.. index:: GNAT.Bounded_Mailboxes (g-boumai.ads)

.. index:: Parsing

.. index:: Mailboxes

Provides a thread-safe asynchronous intertask mailbox communication facility.

.. _`GNAT.Bubble_Sort_(g-bubsor.ads)`:

``GNAT.Bubble_Sort`` (:file:`g-bubsor.ads`)
===========================================

.. index:: GNAT.Bubble_Sort (g-bubsor.ads)

.. index:: Sorting

.. index:: Bubble sort

Provides a general implementation of bubble sort usable for sorting arbitrary
data items.  Exchange and comparison procedures are provided by passing
access-to-procedure values.

.. _`GNAT.Bubble_Sort_A_(g-busora.ads)`:

``GNAT.Bubble_Sort_A`` (:file:`g-busora.ads`)
=============================================

.. index:: GNAT.Bubble_Sort_A (g-busora.ads)

.. index:: Sorting

.. index:: Bubble sort

Provides a general implementation of bubble sort usable for sorting arbitrary
data items.  Move and comparison procedures are provided by passing
access-to-procedure values. This is an older version, retained for
compatibility. Usually ``GNAT.Bubble_Sort`` will be preferable.

.. _`GNAT.Bubble_Sort_G_(g-busorg.ads)`:

``GNAT.Bubble_Sort_G`` (:file:`g-busorg.ads`)
=============================================

.. index:: GNAT.Bubble_Sort_G (g-busorg.ads)

.. index:: Sorting

.. index:: Bubble sort

Similar to ``Bubble_Sort_A`` except that the move and sorting procedures
are provided as generic parameters, this improves efficiency, especially
if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.

.. _`GNAT.Byte_Order_Mark_(g-byorma.ads)`:

``GNAT.Byte_Order_Mark`` (:file:`g-byorma.ads`)
===============================================

.. index:: GNAT.Byte_Order_Mark (g-byorma.ads)

.. index:: UTF-8 representation

.. index:: Wide character representations

Provides a routine which given a string, reads the start of the string to
see whether it is one of the standard byte order marks (BOM's) which signal
the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.

.. _`GNAT.Byte_Swapping_(g-bytswa.ads)`:

``GNAT.Byte_Swapping`` (:file:`g-bytswa.ads`)
=============================================

.. index:: GNAT.Byte_Swapping (g-bytswa.ads)

.. index:: Byte swapping

.. index:: Endianness

General routines for swapping the bytes in 2-, 4-, and 8-byte quantities.
Machine-specific implementations are available in some cases.

.. _`GNAT.C_Time_(g-c_time.ads)`:

``GNAT.C_Time`` (:file:`g-c_time.ads`)
======================================

.. index:: GNAT.C_Time (g-c_time.ads)

.. index:: Time

Provides the time_t, timeval and timespec types corresponding to the C
types defined by the OS, as well as various conversion functions.

.. _`GNAT.Calendar_(g-calend.ads)`:

``GNAT.Calendar`` (:file:`g-calend.ads`)
========================================

.. index:: GNAT.Calendar (g-calend.ads)

.. index:: Calendar

Extends the facilities provided by ``Ada.Calendar`` to include handling
of days of the week, an extended ``Split`` and ``Time_Of`` capability.

.. _`GNAT.Calendar.Time_IO_(g-catiio.ads)`:

``GNAT.Calendar.Time_IO`` (:file:`g-catiio.ads`)
================================================

.. index:: Calendar

.. index:: Time

.. index:: GNAT.Calendar.Time_IO (g-catiio.ads)

.. _`GNAT.CRC32_(g-crc32.ads)`:

``GNAT.CRC32`` (:file:`g-crc32.ads`)
====================================

.. index:: GNAT.CRC32 (g-crc32.ads)

.. index:: CRC32

.. index:: Cyclic Redundancy Check

This package implements the CRC-32 algorithm.  For a full description
of this algorithm see
*Computation of Cyclic Redundancy Checks via Table Look-Up*,
:title:`Communications of the ACM`, Vol. 31 No. 8, pp. 1008-1013,
Aug. 1988.  Sarwate, D.V.

.. _`GNAT.Case_Util_(g-casuti.ads)`:

``GNAT.Case_Util`` (:file:`g-casuti.ads`)
=========================================

.. index:: GNAT.Case_Util (g-casuti.ads)

.. index:: Casing utilities

.. index:: Character handling (``GNAT.Case_Util``)

A set of simple routines for handling upper and lower casing of strings
without the overhead of the full casing tables
in ``Ada.Characters.Handling``.

.. _`GNAT.CGI_(g-cgi.ads)`:

``GNAT.CGI`` (:file:`g-cgi.ads`)
================================

.. index:: GNAT.CGI (g-cgi.ads)

.. index:: CGI (Common Gateway Interface)

This is a package for interfacing a GNAT program with a Web server via the
Common Gateway Interface (CGI).  Basically this package parses the CGI
parameters, which are a set of key/value pairs sent by the Web server.  It
builds a table whose index is the key and provides some services to deal
with this table.

.. _`GNAT.CGI.Cookie_(g-cgicoo.ads)`:

``GNAT.CGI.Cookie`` (:file:`g-cgicoo.ads`)
==========================================

.. index:: GNAT.CGI.Cookie (g-cgicoo.ads)

.. index:: CGI (Common Gateway Interface) cookie support

.. index:: Cookie support in CGI

This is a package to interface a GNAT program with a Web server via the
Common Gateway Interface (CGI).  It exports services to deal with Web
cookies (piece of information kept in the Web client software).

.. _`GNAT.CGI.Debug_(g-cgideb.ads)`:

``GNAT.CGI.Debug`` (:file:`g-cgideb.ads`)
=========================================

.. index:: GNAT.CGI.Debug (g-cgideb.ads)

.. index:: CGI (Common Gateway Interface) debugging

This is a package to help debugging CGI (Common Gateway Interface)
programs written in Ada.

.. _`GNAT.Command_Line_(g-comlin.ads)`:

``GNAT.Command_Line`` (:file:`g-comlin.ads`)
============================================

.. index:: GNAT.Command_Line (g-comlin.ads)

.. index:: Command line

Provides a high level interface to ``Ada.Command_Line`` facilities,
including the ability to scan for named switches with optional parameters
and expand file names using wildcard notations.

.. _`GNAT.Compiler_Version_(g-comver.ads)`:

``GNAT.Compiler_Version`` (:file:`g-comver.ads`)
================================================

.. index:: GNAT.Compiler_Version (g-comver.ads)

.. index:: Compiler Version

.. index:: Version, of compiler

Provides a routine for obtaining the version of the compiler used to
compile the program. More accurately this is the version of the binder
used to bind the program (this will normally be the same as the version
of the compiler if a consistent tool set is used to compile all units
of a partition).

.. _`GNAT.Ctrl_C_(g-ctrl_c.ads)`:

``GNAT.Ctrl_C`` (:file:`g-ctrl_c.ads`)
======================================

.. index:: GNAT.Ctrl_C (g-ctrl_c.ads)

.. index:: Interrupt

Provides a simple interface to handle Ctrl-C keyboard events.

.. _`GNAT.Current_Exception_(g-curexc.ads)`:

``GNAT.Current_Exception`` (:file:`g-curexc.ads`)
=================================================

.. index:: GNAT.Current_Exception (g-curexc.ads)

.. index:: Current exception

.. index:: Exception retrieval

Provides access to information on the current exception that has been raised
without the need for using the Ada 95 / Ada 2005 exception choice parameter
specification syntax.
This is particularly useful in simulating typical facilities for
obtaining information about exceptions provided by Ada 83 compilers.

.. _`GNAT.Debug_Pools_(g-debpoo.ads)`:

``GNAT.Debug_Pools`` (:file:`g-debpoo.ads`)
===========================================

.. index:: GNAT.Debug_Pools (g-debpoo.ads)

.. index:: Debugging

.. index:: Debug pools

.. index:: Memory corruption debugging

Provides a debugging storage pools that helps tracking memory corruption
problems.
See ``The GNAT Debug_Pool Facility`` section in the :title:`GNAT User's Guide`.

.. _`GNAT.Debug_Utilities_(g-debuti.ads)`:

``GNAT.Debug_Utilities`` (:file:`g-debuti.ads`)
===============================================

.. index:: GNAT.Debug_Utilities (g-debuti.ads)

.. index:: Debugging

Provides a few useful utilities for debugging purposes, including conversion
to and from string images of address values. Supports both C and Ada formats
for hexadecimal literals.

.. _`GNAT.Decode_String_(g-decstr.ads)`:

``GNAT.Decode_String`` (:file:`g-decstr.ads`)
=============================================

.. index:: GNAT.Decode_String (g-decstr.ads)

.. index:: Decoding strings

.. index:: String decoding

.. index:: Wide character encoding

.. index:: UTF-8

.. index:: Unicode

A generic package providing routines for decoding wide character and wide wide
character strings encoded as sequences of 8-bit characters using a specified
encoding method. Includes validation routines, and also routines for stepping
to next or previous encoded character in an encoded string.
Useful in conjunction with Unicode character coding. Note there is a
preinstantiation for UTF-8. See next entry.

.. _`GNAT.Decode_UTF8_String_(g-deutst.ads)`:

``GNAT.Decode_UTF8_String`` (:file:`g-deutst.ads`)
==================================================

.. index:: GNAT.Decode_UTF8_String (g-deutst.ads)

.. index:: Decoding strings

.. index:: Decoding UTF-8 strings

.. index:: UTF-8 string decoding

.. index:: Wide character decoding

.. index:: UTF-8

.. index:: Unicode

A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding.

.. _`GNAT.Directory_Operations_(g-dirope.ads)`:

``GNAT.Directory_Operations`` (:file:`g-dirope.ads`)
====================================================

.. index:: GNAT.Directory_Operations (g-dirope.ads)

.. index:: Directory operations

Provides a set of routines for manipulating directories, including changing
the current directory, making new directories, and scanning the files in a
directory.

.. _`GNAT.Directory_Operations.Iteration_(g-diopit.ads)`:

``GNAT.Directory_Operations.Iteration`` (:file:`g-diopit.ads`)
==============================================================

.. index:: GNAT.Directory_Operations.Iteration (g-diopit.ads)

.. index:: Directory operations iteration

A child unit of GNAT.Directory_Operations providing additional operations
for iterating through directories.

.. _`GNAT.Dynamic_HTables_(g-dynhta.ads)`:

``GNAT.Dynamic_HTables`` (:file:`g-dynhta.ads`)
===============================================

.. index:: GNAT.Dynamic_HTables (g-dynhta.ads)

.. index:: Hash tables

A generic implementation of hash tables that can be used to hash arbitrary
data.  Provided in two forms, a simple form with built in hash functions,
and a more complex form in which the hash function is supplied.

This package provides a facility similar to that of ``GNAT.HTable``,
except that this package declares a type that can be used to define
dynamic instances of the hash table, while an instantiation of
``GNAT.HTable`` creates a single instance of the hash table.

.. _`GNAT.Dynamic_Tables_(g-dyntab.ads)`:

``GNAT.Dynamic_Tables`` (:file:`g-dyntab.ads`)
==============================================

.. index:: GNAT.Dynamic_Tables (g-dyntab.ads)

.. index:: Table implementation

.. index:: Arrays, extendable

A generic package providing a single dimension array abstraction where the
length of the array can be dynamically modified.

This package provides a facility similar to that of ``GNAT.Table``,
except that this package declares a type that can be used to define
dynamic instances of the table, while an instantiation of
``GNAT.Table`` creates a single instance of the table type.

.. _`GNAT.Encode_String_(g-encstr.ads)`:

``GNAT.Encode_String`` (:file:`g-encstr.ads`)
=============================================

.. index:: GNAT.Encode_String (g-encstr.ads)

.. index:: Encoding strings

.. index:: String encoding

.. index:: Wide character encoding

.. index:: UTF-8

.. index:: Unicode

A generic package providing routines for encoding wide character and wide
wide character strings as sequences of 8-bit characters using a specified
encoding method. Useful in conjunction with Unicode character coding.
Note there is a preinstantiation for UTF-8. See next entry.

.. _`GNAT.Encode_UTF8_String_(g-enutst.ads)`:

``GNAT.Encode_UTF8_String`` (:file:`g-enutst.ads`)
==================================================

.. index:: GNAT.Encode_UTF8_String (g-enutst.ads)

.. index:: Encoding strings

.. index:: Encoding UTF-8 strings

.. index:: UTF-8 string encoding

.. index:: Wide character encoding

.. index:: UTF-8

.. index:: Unicode

A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding.

.. _`GNAT.Exception_Actions_(g-excact.ads)`:

``GNAT.Exception_Actions`` (:file:`g-excact.ads`)
=================================================

.. index:: GNAT.Exception_Actions (g-excact.ads)

.. index:: Exception actions

Provides callbacks when an exception is raised. Callbacks can be registered
for specific exceptions, or when any exception is raised. This
can be used for instance to force a core dump to ease debugging.

.. _`GNAT.Exception_Traces_(g-exctra.ads)`:

``GNAT.Exception_Traces`` (:file:`g-exctra.ads`)
================================================

.. index:: GNAT.Exception_Traces (g-exctra.ads)

.. index:: Exception traces

.. index:: Debugging

Provides an interface allowing to control automatic output upon exception
occurrences.

.. _`GNAT.Exceptions_(g-except.ads)`:

``GNAT.Exceptions`` (:file:`g-except.ads`)
==========================================

.. index:: GNAT.Exceptions (g-except.ads)

.. index:: Exceptions, Pure

.. index:: Pure packages, exceptions

Normally it is not possible to raise an exception with
a message from a subprogram in a pure package, since the
necessary types and subprograms are in ``Ada.Exceptions``
which is not a pure unit. ``GNAT.Exceptions`` provides a
facility for getting around this limitation for a few
predefined exceptions, and for example allows raising
``Constraint_Error`` with a message from a pure subprogram.

.. _`GNAT.Expect_(g-expect.ads)`:

``GNAT.Expect`` (:file:`g-expect.ads`)
======================================

.. index:: GNAT.Expect (g-expect.ads)

Provides a set of subprograms similar to what is available
with the standard Tcl Expect tool.
It allows you to easily spawn and communicate with an external process.
You can send commands or inputs to the process, and compare the output
with some expected regular expression. Currently ``GNAT.Expect``
is implemented on all native GNAT ports.
It is not implemented for cross ports, and in particular is not
implemented for VxWorks or LynxOS.

.. _`GNAT.Expect.TTY_(g-exptty.ads)`:

``GNAT.Expect.TTY`` (:file:`g-exptty.ads`)
==========================================

.. index:: GNAT.Expect.TTY (g-exptty.ads)

As GNAT.Expect but using pseudo-terminal.
Currently ``GNAT.Expect.TTY`` is implemented on all native GNAT
ports. It is not implemented for cross ports, and
in particular is not implemented for VxWorks or LynxOS.

.. _`GNAT.Float_Control_(g-flocon.ads)`:

``GNAT.Float_Control`` (:file:`g-flocon.ads`)
=============================================

.. index:: GNAT.Float_Control (g-flocon.ads)

.. index:: Floating-Point Processor

Provides an interface for resetting the floating-point processor into the
mode required for correct semantic operation in Ada.  Some third party
library calls may cause this mode to be modified, and the Reset procedure
in this package can be used to reestablish the required mode.

.. _`GNAT.Formatted_String_(g-forstr.ads)`:

``GNAT.Formatted_String`` (:file:`g-forstr.ads`)
================================================

.. index:: GNAT.Formatted_String (g-forstr.ads)

.. index:: Formatted String

Provides support for C/C++ printf() formatted strings. The format is
copied from the printf() routine and should therefore give identical
output. Some generic routines are provided to be able to use types
derived from Integer, Float or enumerations as values for the
formatted string.

.. _`GNAT.Generic_Fast_Math_Functions_(g-gfmafu.ads)`:

``GNAT.Generic_Fast_Math_Functions`` (:file:`g-gfmafu.ads`)
===========================================================

.. index:: GNAT.Generic_Fast_Math_Functions (g-gfmafu.ads)

.. index:: Mathematical functions

Provides direct access to the underlying implementation of the common
mathematical functions, generally from the system mathematical library.
This differs from ``Ada.Numerics.Generic_Elementary_Functions`` in that
the implementation may deviate from the semantics specified for these
functions in the Reference Manual, for example ``Numerics.Argument_Error``
is not raised. On selected platforms, some of these functions may also
have a vector implementation that can be automatically used by the
compiler when auto-vectorization is enabled.

.. _`GNAT.Heap_Sort_(g-heasor.ads)`:

``GNAT.Heap_Sort`` (:file:`g-heasor.ads`)
=========================================

.. index:: GNAT.Heap_Sort (g-heasor.ads)

.. index:: Sorting

Provides a general implementation of heap sort usable for sorting arbitrary
data items. Exchange and comparison procedures are provided by passing
access-to-procedure values.  The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.

.. _`GNAT.Heap_Sort_A_(g-hesora.ads)`:

``GNAT.Heap_Sort_A`` (:file:`g-hesora.ads`)
===========================================

.. index:: GNAT.Heap_Sort_A (g-hesora.ads)

.. index:: Sorting

Provides a general implementation of heap sort usable for sorting arbitrary
data items. Move and comparison procedures are provided by passing
access-to-procedure values.  The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
This differs from ``GNAT.Heap_Sort`` in having a less convenient
interface, but may be slightly more efficient.

.. _`GNAT.Heap_Sort_G_(g-hesorg.ads)`:

``GNAT.Heap_Sort_G`` (:file:`g-hesorg.ads`)
===========================================

.. index:: GNAT.Heap_Sort_G (g-hesorg.ads)

.. index:: Sorting

Similar to ``Heap_Sort_A`` except that the move and sorting procedures
are provided as generic parameters, this improves efficiency, especially
if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.

.. _`GNAT.HTable_(g-htable.ads)`:

``GNAT.HTable`` (:file:`g-htable.ads`)
======================================

.. index:: GNAT.HTable (g-htable.ads)

.. index:: Hash tables

A generic implementation of hash tables that can be used to hash arbitrary
data.  Provides two approaches, one a simple static approach, and the other
allowing arbitrary dynamic hash tables.

.. _`GNAT.IO_(g-io.ads)`:

``GNAT.IO`` (:file:`g-io.ads`)
==============================

.. index:: GNAT.IO (g-io.ads)

.. index:: Simple I/O

.. index:: Input/Output facilities

A simple preelaborable input-output package that provides a subset of
simple Text_IO functions for reading characters and strings from
Standard_Input, and writing characters, strings and integers to either
Standard_Output or Standard_Error.

.. _`GNAT.IO_Aux_(g-io_aux.ads)`:

``GNAT.IO_Aux`` (:file:`g-io_aux.ads`)
======================================

.. index:: GNAT.IO_Aux (g-io_aux.ads)

.. index:: Text_IO

.. index:: Input/Output facilities

Provides some auxiliary functions for use with Text_IO, including a test
for whether a file exists, and functions for reading a line of text.

.. _`GNAT.Lock_Files_(g-locfil.ads)`:

``GNAT.Lock_Files`` (:file:`g-locfil.ads`)
==========================================

.. index:: GNAT.Lock_Files (g-locfil.ads)

.. index:: File locking

.. index:: Locking using files

Provides a general interface for using files as locks.  Can be used for
providing program level synchronization.

.. _`GNAT.MBBS_Discrete_Random_(g-mbdira.ads)`:

``GNAT.MBBS_Discrete_Random`` (:file:`g-mbdira.ads`)
====================================================

.. index:: GNAT.MBBS_Discrete_Random (g-mbdira.ads)

.. index:: Random number generation

The original implementation of ``Ada.Numerics.Discrete_Random``.  Uses
a modified version of the Blum-Blum-Shub generator.

.. _`GNAT.MBBS_Float_Random_(g-mbflra.ads)`:

``GNAT.MBBS_Float_Random`` (:file:`g-mbflra.ads`)
=================================================

.. index:: GNAT.MBBS_Float_Random (g-mbflra.ads)

.. index:: Random number generation

The original implementation of ``Ada.Numerics.Float_Random``.  Uses
a modified version of the Blum-Blum-Shub generator.

.. _`GNAT.MD5_(g-md5.ads)`:

``GNAT.MD5`` (:file:`g-md5.ads`)
================================

.. index:: GNAT.MD5 (g-md5.ads)

.. index:: Message Digest MD5

Implements the MD5 Message-Digest Algorithm as described in RFC 1321, and
the HMAC-MD5 message authentication function as described in RFC 2104 and
FIPS PUB 198.

.. _`GNAT.Memory_Dump_(g-memdum.ads)`:

``GNAT.Memory_Dump`` (:file:`g-memdum.ads`)
===========================================

.. index:: GNAT.Memory_Dump (g-memdum.ads)

.. index:: Dump Memory

Provides a convenient routine for dumping raw memory to either the
standard output or standard error files. Uses GNAT.IO for actual
output.

.. _`GNAT.Most_Recent_Exception_(g-moreex.ads)`:

``GNAT.Most_Recent_Exception`` (:file:`g-moreex.ads`)
=====================================================

.. index:: GNAT.Most_Recent_Exception (g-moreex.ads)

.. index:: Exception, obtaining most recent

Provides access to the most recently raised exception.  Can be used for
various logging purposes, including duplicating functionality of some
Ada 83 implementation dependent extensions.

.. _`GNAT.OS_Lib_(g-os_lib.ads)`:

``GNAT.OS_Lib`` (:file:`g-os_lib.ads`)
======================================

.. index:: GNAT.OS_Lib (g-os_lib.ads)

.. index:: Operating System interface

.. index:: Spawn capability

Provides a range of target independent operating system interface functions,
including time/date management, file operations, subprocess management,
including a portable spawn procedure, and access to environment variables
and error return codes.

.. _`GNAT.Perfect_Hash_Generators_(g-pehage.ads)`:

``GNAT.Perfect_Hash_Generators`` (:file:`g-pehage.ads`)
=======================================================

.. index:: GNAT.Perfect_Hash_Generators (g-pehage.ads)

.. index:: Hash functions

Provides a generator of static minimal perfect hash functions. No
collisions occur and each item can be retrieved from the table in one
probe (perfect property). The hash table size corresponds to the exact
size of the key set and no larger (minimal property). The key set has to
be known in advance (static property). The hash functions are also order
preserving. If w2 is inserted after w1 in the generator, their
hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.

.. _`GNAT.Random_Numbers_(g-rannum.ads)`:

``GNAT.Random_Numbers`` (:file:`g-rannum.ads`)
==============================================

.. index:: GNAT.Random_Numbers (g-rannum.ads)

.. index:: Random number generation

Provides random number capabilities which extend those available in the
standard Ada library and are more convenient to use. This package is
however NOT suitable for situations requiring cryptographically secure
randomness.

.. _`GNAT.Regexp_(g-regexp.ads)`:

``GNAT.Regexp`` (:file:`g-regexp.ads`)
======================================

.. index:: GNAT.Regexp (g-regexp.ads)

.. index:: Regular expressions

.. index:: Pattern matching

A simple implementation of regular expressions, using a subset of regular
expression syntax copied from familiar Unix style utilities.  This is the
simplest of the three pattern matching packages provided, and is particularly
suitable for 'file globbing' applications.

.. _`GNAT.Registry_(g-regist.ads)`:

``GNAT.Registry`` (:file:`g-regist.ads`)
========================================

.. index:: GNAT.Registry (g-regist.ads)

.. index:: Windows Registry

This is a high level binding to the Windows registry.  It is possible to
do simple things like reading a key value, creating a new key.  For full
registry API, but at a lower level of abstraction, refer to the Win32.Winreg
package provided with the Win32Ada binding

.. _`GNAT.Regpat_(g-regpat.ads)`:

``GNAT.Regpat`` (:file:`g-regpat.ads`)
======================================

.. index:: GNAT.Regpat (g-regpat.ads)

.. index:: Regular expressions

.. index:: Pattern matching

A complete implementation of Unix-style regular expression matching, copied
from the original V7 style regular expression library written in C by
Henry Spencer (and binary compatible with this C library).

.. _`GNAT.Rewrite_Data_(g-rewdat.ads)`:

``GNAT.Rewrite_Data`` (:file:`g-rewdat.ads`)
============================================

.. index:: GNAT.Rewrite_Data (g-rewdat.ads)

.. index:: Rewrite data

A unit to rewrite on-the-fly string occurrences in a stream of
data. The implementation has a very minimal memory footprint as the
full content to be processed is not loaded into memory all at once. This makes
this interface usable for large files or socket streams.

.. _`GNAT.Secondary_Stack_Info_(g-sestin.ads)`:

``GNAT.Secondary_Stack_Info`` (:file:`g-sestin.ads`)
====================================================

.. index:: GNAT.Secondary_Stack_Info (g-sestin.ads)

.. index:: Secondary Stack Info

Provides the capability to query the high water mark of the current task's
secondary stack.

.. _`GNAT.Semaphores_(g-semaph.ads)`:

``GNAT.Semaphores`` (:file:`g-semaph.ads`)
==========================================

.. index:: GNAT.Semaphores (g-semaph.ads)

.. index:: Semaphores

Provides classic counting and binary semaphores using protected types.

.. _`GNAT.Serial_Communications_(g-sercom.ads)`:

``GNAT.Serial_Communications`` (:file:`g-sercom.ads`)
=====================================================

.. index:: GNAT.Serial_Communications (g-sercom.ads)

.. index:: Serial_Communications

Provides a simple interface to send and receive data over a serial
port. This is only supported on GNU/Linux and Windows.

.. _`GNAT.SHA1_(g-sha1.ads)`:

``GNAT.SHA1`` (:file:`g-sha1.ads`)
==================================

.. index:: GNAT.SHA1 (g-sha1.ads)

.. index:: Secure Hash Algorithm SHA-1

Implements the SHA-1 Secure Hash Algorithm as described in FIPS PUB 180-3
and RFC 3174, and the HMAC-SHA1 message authentication function as described
in RFC 2104 and FIPS PUB 198.

.. _`GNAT.SHA224_(g-sha224.ads)`:

``GNAT.SHA224`` (:file:`g-sha224.ads`)
======================================

.. index:: GNAT.SHA224 (g-sha224.ads)

.. index:: Secure Hash Algorithm SHA-224

Implements the SHA-224 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA224 message authentication function as described
in RFC 2104 and FIPS PUB 198.

.. _`GNAT.SHA256_(g-sha256.ads)`:

``GNAT.SHA256`` (:file:`g-sha256.ads`)
======================================

.. index:: GNAT.SHA256 (g-sha256.ads)

.. index:: Secure Hash Algorithm SHA-256

Implements the SHA-256 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA256 message authentication function as described
in RFC 2104 and FIPS PUB 198.

.. _`GNAT.SHA384_(g-sha384.ads)`:

``GNAT.SHA384`` (:file:`g-sha384.ads`)
======================================

.. index:: GNAT.SHA384 (g-sha384.ads)

.. index:: Secure Hash Algorithm SHA-384

Implements the SHA-384 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA384 message authentication function as described
in RFC 2104 and FIPS PUB 198.

.. _`GNAT.SHA512_(g-sha512.ads)`:

``GNAT.SHA512`` (:file:`g-sha512.ads`)
======================================

.. index:: GNAT.SHA512 (g-sha512.ads)

.. index:: Secure Hash Algorithm SHA-512

Implements the SHA-512 Secure Hash Algorithm as described in FIPS PUB 180-3,
and the HMAC-SHA512 message authentication function as described
in RFC 2104 and FIPS PUB 198.

.. _`GNAT.Signals_(g-signal.ads)`:

``GNAT.Signals`` (:file:`g-signal.ads`)
=======================================

.. index:: GNAT.Signals (g-signal.ads)

.. index:: Signals

Provides the ability to manipulate the blocked status of signals on supported
targets.

.. _`GNAT.Sockets_(g-socket.ads)`:

``GNAT.Sockets`` (:file:`g-socket.ads`)
=======================================

.. index:: GNAT.Sockets (g-socket.ads)

.. index:: Sockets

A high level and portable interface to develop sockets based applications.
This package is based on the sockets thin binding found in
``GNAT.Sockets.Thin``. Currently ``GNAT.Sockets`` is implemented
on all native GNAT ports and on VxWorks cross ports.  It is not implemented for
the LynxOS cross port.

.. _`GNAT.Source_Info_(g-souinf.ads)`:

``GNAT.Source_Info`` (:file:`g-souinf.ads`)
===========================================

.. index:: GNAT.Source_Info (g-souinf.ads)

.. index:: Source Information

Provides subprograms that give access to source code information known at
compile time, such as the current file name and line number. Also provides
subprograms yielding the date and time of the current compilation (like the
C macros ``__DATE__`` and ``__TIME__``)

.. _`GNAT.Spelling_Checker_(g-speche.ads)`:

``GNAT.Spelling_Checker`` (:file:`g-speche.ads`)
================================================

.. index:: GNAT.Spelling_Checker (g-speche.ads)

.. index:: Spell checking

Provides a function for determining whether one string is a plausible
near misspelling of another string.

.. _`GNAT.Spelling_Checker_Generic_(g-spchge.ads)`:

``GNAT.Spelling_Checker_Generic`` (:file:`g-spchge.ads`)
========================================================

.. index:: GNAT.Spelling_Checker_Generic (g-spchge.ads)

.. index:: Spell checking

Provides a generic function that can be instantiated with a string type for
determining whether one string is a plausible near misspelling of another
string.

.. _`GNAT.Spitbol.Patterns_(g-spipat.ads)`:

``GNAT.Spitbol.Patterns`` (:file:`g-spipat.ads`)
================================================

.. index:: GNAT.Spitbol.Patterns (g-spipat.ads)

.. index:: SPITBOL pattern matching

.. index:: Pattern matching

A complete implementation of SNOBOL4 style pattern matching.  This is the
most elaborate of the pattern matching packages provided.  It fully duplicates
the SNOBOL4 dynamic pattern construction and matching capabilities, using the
efficient algorithm developed by Robert Dewar for the SPITBOL system.

.. _`GNAT.Spitbol_(g-spitbo.ads)`:

``GNAT.Spitbol`` (:file:`g-spitbo.ads`)
=======================================

.. index:: GNAT.Spitbol (g-spitbo.ads)

.. index:: SPITBOL interface

The top level package of the collection of SPITBOL-style functionality, this
package provides basic SNOBOL4 string manipulation functions, such as
Pad, Reverse, Trim, Substr capability, as well as a generic table function
useful for constructing arbitrary mappings from strings in the style of
the SNOBOL4 TABLE function.

.. _`GNAT.Spitbol.Table_Boolean_(g-sptabo.ads)`:

``GNAT.Spitbol.Table_Boolean`` (:file:`g-sptabo.ads`)
=====================================================

.. index:: GNAT.Spitbol.Table_Boolean (g-sptabo.ads)

.. index:: Sets of strings

.. index:: SPITBOL Tables

A library level of instantiation of ``GNAT.Spitbol.Patterns.Table``
for type ``Standard.Boolean``, giving an implementation of sets of
string values.

.. _`GNAT.Spitbol.Table_Integer_(g-sptain.ads)`:

``GNAT.Spitbol.Table_Integer`` (:file:`g-sptain.ads`)
=====================================================

.. index:: GNAT.Spitbol.Table_Integer (g-sptain.ads)

.. index:: Integer maps

.. index:: Maps

.. index:: SPITBOL Tables

A library level of instantiation of ``GNAT.Spitbol.Patterns.Table``
for type ``Standard.Integer``, giving an implementation of maps
from string to integer values.

.. _`GNAT.Spitbol.Table_VString_(g-sptavs.ads)`:

``GNAT.Spitbol.Table_VString`` (:file:`g-sptavs.ads`)
=====================================================

.. index:: GNAT.Spitbol.Table_VString (g-sptavs.ads)

.. index:: String maps

.. index:: Maps

.. index:: SPITBOL Tables

A library level of instantiation of ``GNAT.Spitbol.Patterns.Table`` for
a variable length string type, giving an implementation of general
maps from strings to strings.

.. _`GNAT.SSE_(g-sse.ads)`:

``GNAT.SSE`` (:file:`g-sse.ads`)
================================

.. index:: GNAT.SSE (g-sse.ads)

Root of a set of units aimed at offering Ada bindings to a subset of
the Intel(r) Streaming SIMD Extensions with GNAT on the x86 family of
targets.  It exposes vector component types together with a general
introduction to the binding contents and use.

.. _`GNAT.SSE.Vector_Types_(g-ssvety.ads)`:

``GNAT.SSE.Vector_Types`` (:file:`g-ssvety.ads`)
================================================

.. index:: GNAT.SSE.Vector_Types (g-ssvety.ads)

SSE vector types for use with SSE related intrinsics.

.. _`GNAT.String_Hash(g-strhas.ads)`:

``GNAT.String_Hash`` (:file:`g-strhas.ads`)
===========================================

.. index:: GNAT.String_Hash (g-strhas.ads)

.. index:: Hash functions

Provides a generic hash function working on arrays of scalars. Both the scalar
type and the hash result type are parameters.

.. _`GNAT.Strings_(g-string.ads)`:

``GNAT.Strings`` (:file:`g-string.ads`)
=======================================

.. index:: GNAT.Strings (g-string.ads)

Common String access types and related subprograms. Basically it
defines a string access and an array of string access types.

.. _`GNAT.String_Split_(g-strspl.ads)`:

``GNAT.String_Split`` (:file:`g-strspl.ads`)
============================================

.. index:: GNAT.String_Split (g-strspl.ads)

.. index:: String splitter

Useful string manipulation routines: given a set of separators, split
a string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
``GNAT.Array_Split``.

.. _`GNAT.Table_(g-table.ads)`:

``GNAT.Table`` (:file:`g-table.ads`)
====================================

.. index:: GNAT.Table (g-table.ads)

.. index:: Table implementation

.. index:: Arrays, extendable

A generic package providing a single dimension array abstraction where the
length of the array can be dynamically modified.

This package provides a facility similar to that of ``GNAT.Dynamic_Tables``,
except that this package declares a single instance of the table type,
while an instantiation of ``GNAT.Dynamic_Tables`` creates a type that can be
used to define dynamic instances of the table.

.. _`GNAT.Task_Lock_(g-tasloc.ads)`:

``GNAT.Task_Lock`` (:file:`g-tasloc.ads`)
=========================================

.. index:: GNAT.Task_Lock (g-tasloc.ads)

.. index:: Task synchronization

.. index:: Task locking

.. index:: Locking

A very simple facility for locking and unlocking sections of code using a
single global task lock.  Appropriate for use in situations where contention
between tasks is very rarely expected.

.. _`GNAT.Time_Stamp_(g-timsta.ads)`:

``GNAT.Time_Stamp`` (:file:`g-timsta.ads`)
==========================================

.. index:: GNAT.Time_Stamp (g-timsta.ads)

.. index:: Time stamp

.. index:: Current time

Provides a simple function that returns a string YYYY-MM-DD HH:MM:SS.SS that
represents the current date and time in ISO 8601 format. This is a very simple
routine with minimal code and there are no dependencies on any other unit.

.. _`GNAT.Threads_(g-thread.ads)`:

``GNAT.Threads`` (:file:`g-thread.ads`)
=======================================

.. index:: GNAT.Threads (g-thread.ads)

.. index:: Foreign threads

.. index:: Threads, foreign

Provides facilities for dealing with foreign threads which need to be known
by the GNAT run-time system. Consult the documentation of this package for
further details if your program has threads that are created by a non-Ada
environment which then accesses Ada code.

.. _`GNAT.Traceback_(g-traceb.ads)`:

``GNAT.Traceback`` (:file:`g-traceb.ads`)
=========================================

.. index:: GNAT.Traceback (g-traceb.ads)

.. index:: Trace back facilities

Provides a facility for obtaining non-symbolic traceback information, useful
in various debugging situations.

.. _`GNAT.Traceback.Symbolic_(g-trasym.ads)`:

``GNAT.Traceback.Symbolic`` (:file:`g-trasym.ads`)
==================================================

.. index:: GNAT.Traceback.Symbolic (g-trasym.ads)

.. index:: Trace back facilities

.. _`GNAT.UTF_32_(g-utf_32.ads)`:

``GNAT.UTF_32`` (:file:`g-utf_32.ads`)
======================================

.. index:: GNAT.UTF_32 (g-utf_32.ads)

.. index:: Wide character codes

This is a package intended to be used in conjunction with the
``Wide_Character`` type in Ada 95 and the
``Wide_Wide_Character`` type in Ada 2005 (available
in ``GNAT`` in Ada 2005 mode). This package contains
Unicode categorization routines, as well as lexical
categorization routines corresponding to the Ada 2005
lexical rules for identifiers and strings, and also a
lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.

.. _`GNAT.UTF_32_Spelling_Checker_(g-u3spch.ads)`:

``GNAT.UTF_32_Spelling_Checker`` (:file:`g-u3spch.ads`)
=======================================================

.. index:: GNAT.UTF_32_Spelling_Checker (g-u3spch.ads)

.. index:: Spell checking

Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.

.. _`GNAT.Wide_Spelling_Checker_(g-wispch.ads)`:

``GNAT.Wide_Spelling_Checker`` (:file:`g-wispch.ads`)
=====================================================

.. index:: GNAT.Wide_Spelling_Checker (g-wispch.ads)

.. index:: Spell checking

Provides a function for determining whether one wide string is a plausible
near misspelling of another wide string.

.. _`GNAT.Wide_String_Split_(g-wistsp.ads)`:

``GNAT.Wide_String_Split`` (:file:`g-wistsp.ads`)
=================================================

.. index:: GNAT.Wide_String_Split (g-wistsp.ads)

.. index:: Wide_String splitter

Useful wide string manipulation routines: given a set of separators, split
a wide string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
``GNAT.Array_Split``.

.. _`GNAT.Wide_Wide_Spelling_Checker_(g-zspche.ads)`:

``GNAT.Wide_Wide_Spelling_Checker`` (:file:`g-zspche.ads`)
==========================================================

.. index:: GNAT.Wide_Wide_Spelling_Checker (g-zspche.ads)

.. index:: Spell checking

Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string.

.. _`GNAT.Wide_Wide_String_Split_(g-zistsp.ads)`:

``GNAT.Wide_Wide_String_Split`` (:file:`g-zistsp.ads`)
======================================================

.. index:: GNAT.Wide_Wide_String_Split (g-zistsp.ads)

.. index:: Wide_Wide_String splitter

Useful wide wide string manipulation routines: given a set of separators, split
a wide wide string wherever the separators appear, and provide direct access
to the resulting slices. This package is instantiated from
``GNAT.Array_Split``.

.. _`Interfaces.C.Extensions_(i-cexten.ads)`:

``Interfaces.C.Extensions`` (:file:`i-cexten.ads`)
==================================================

.. index:: Interfaces.C.Extensions (i-cexten.ads)

This package contains additional C-related definitions, intended
for use with either manually or automatically generated bindings
to C libraries.

.. _`Interfaces.C.Streams_(i-cstrea.ads)`:

``Interfaces.C.Streams`` (:file:`i-cstrea.ads`)
===============================================

.. index:: Interfaces.C.Streams (i-cstrea.ads)

.. index::  C streams, interfacing

This package is a binding for the most commonly used operations
on C streams.

.. _`Interfaces.Packed_Decimal_(i-pacdec.ads)`:

``Interfaces.Packed_Decimal`` (:file:`i-pacdec.ads`)
====================================================

.. index:: Interfaces.Packed_Decimal (i-pacdec.ads)

.. index::  IBM Packed Format

.. index::  Packed Decimal

This package provides a set of routines for conversions to and
from a packed decimal format compatible with that used on IBM
mainframes.

.. _`Interfaces.VxWorks_(i-vxwork.ads)`:

``Interfaces.VxWorks`` (:file:`i-vxwork.ads`)
=============================================

.. index:: Interfaces.VxWorks (i-vxwork.ads)

.. index:: Interfacing to VxWorks

.. index:: VxWorks, interfacing

This package provides a limited binding to the VxWorks API.

.. _`Interfaces.VxWorks.IO_(i-vxwoio.ads)`:

``Interfaces.VxWorks.IO`` (:file:`i-vxwoio.ads`)
================================================

.. index:: Interfaces.VxWorks.IO (i-vxwoio.ads)

.. index:: Interfacing to VxWorks' I/O

.. index:: VxWorks, I/O interfacing

.. index:: VxWorks, Get_Immediate

.. index:: Get_Immediate, VxWorks

This package provides a binding to the ioctl (IO/Control)
function of VxWorks, defining a set of option values and
function codes. A particular use of this package is
to enable the use of Get_Immediate under VxWorks.

.. _`System.Address_Image_(s-addima.ads)`:

``System.Address_Image`` (:file:`s-addima.ads`)
===============================================

.. index:: System.Address_Image (s-addima.ads)

.. index:: Address image

.. index:: Image, of an address

This function provides a useful debugging
function that gives an (implementation dependent)
string which identifies an address.

.. _`System.Assertions_(s-assert.ads)`:

``System.Assertions`` (:file:`s-assert.ads`)
============================================

.. index:: System.Assertions (s-assert.ads)

.. index:: Assertions

.. index:: Assert_Failure, exception

This package provides the declaration of the exception raised
by an run-time assertion failure, as well as the routine that
is used internally to raise this assertion.

.. _`System.Atomic_Counters_(s-atocou.ads)`:

``System.Atomic_Counters`` (:file:`s-atocou.ads`)
=================================================

.. index:: System.Atomic_Counters (s-atocou.ads)

This package provides the declaration of an atomic counter type,
together with efficient routines (using hardware
synchronization primitives) for incrementing, decrementing,
and testing of these counters. This package is implemented
on most targets, including all Alpha, AARCH64, ARM, ia64, PowerPC, SPARC V9,
x86, and x86_64 platforms.

.. _`System.Memory_(s-memory.ads)`:

``System.Memory`` (:file:`s-memory.ads`)
========================================

.. index:: System.Memory (s-memory.ads)

.. index:: Memory allocation

This package provides the interface to the low level routines used
by the generated code for allocation and freeing storage for the
default storage pool (analogous to the C routines malloc and free).
It also provides a reallocation interface analogous to the C routine
realloc. The body of this unit may be modified to provide alternative
allocation mechanisms for the default pool, and in addition, direct
calls to this unit may be made for low level allocation uses (for
example see the body of ``GNAT.Tables``).

.. _`System.Multiprocessors_(s-multip.ads)`:

``System.Multiprocessors`` (:file:`s-multip.ads`)
=================================================

.. index:: System.Multiprocessors (s-multip.ads)

.. index:: Multiprocessor interface

This is an Ada 2012 unit defined in the Ada 2012 Reference Manual, but
in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).

.. _`System.Multiprocessors.Dispatching_Domains_(s-mudido.ads)`:

``System.Multiprocessors.Dispatching_Domains`` (:file:`s-mudido.ads`)
=====================================================================

.. index:: System.Multiprocessors.Dispatching_Domains (s-mudido.ads)

.. index:: Multiprocessor interface

This is an Ada 2012 unit defined in the Ada 2012 Reference Manual, but
in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).

.. _`System.Partition_Interface_(s-parint.ads)`:

``System.Partition_Interface`` (:file:`s-parint.ads`)
=====================================================

.. index:: System.Partition_Interface (s-parint.ads)

.. index:: Partition interfacing functions

This package provides facilities for partition interfacing.  It
is used primarily in a distribution context when using Annex E
with ``PolyORB``.  **NB!** See the note in :ref:`polyORB` regarding
the lifetime of this product.

.. _`System.Pool_Global_(s-pooglo.ads)`:

``System.Pool_Global`` (:file:`s-pooglo.ads`)
=============================================

.. index:: System.Pool_Global (s-pooglo.ads)

.. index:: Storage pool, global

.. index:: Global storage pool

This package provides a storage pool that is equivalent to the default
storage pool used for access types for which no pool is specifically
declared. It uses malloc/free to allocate/free and does not attempt to
do any automatic reclamation.

.. _`System.Pool_Local_(s-pooloc.ads)`:

``System.Pool_Local`` (:file:`s-pooloc.ads`)
============================================

.. index:: System.Pool_Local (s-pooloc.ads)

.. index:: Storage pool, local

.. index:: Local storage pool

This package provides a storage pool that is intended for use with locally
defined access types. It uses malloc/free for allocate/free, and maintains
a list of allocated blocks, so that all storage allocated for the pool can
be freed automatically when the pool is finalized.

.. _`System.Restrictions_(s-restri.ads)`:

``System.Restrictions`` (:file:`s-restri.ads`)
==============================================

.. index:: System.Restrictions (s-restri.ads)

.. index:: Run-time restrictions access

This package provides facilities for accessing at run time
the status of restrictions specified at compile time for
the partition. Information is available both with regard
to actual restrictions specified, and with regard to
compiler determined information on which restrictions
are violated by one or more packages in the partition.

.. _`System.Rident_(s-rident.ads)`:

``System.Rident`` (:file:`s-rident.ads`)
========================================

.. index:: System.Rident (s-rident.ads)

.. index:: Restrictions definitions

This package provides definitions of the restrictions
identifiers supported by GNAT, and also the format of
the restrictions provided in package System.Restrictions.
It is not normally necessary to ``with`` this generic package
since the necessary instantiation is included in
package System.Restrictions.

.. _`System.Strings.Stream_Ops_(s-ststop.ads)`:

``System.Strings.Stream_Ops`` (:file:`s-ststop.ads`)
====================================================

.. index:: System.Strings.Stream_Ops (s-ststop.ads)

.. index:: Stream operations

.. index:: String stream operations

This package provides a set of stream subprograms for standard string types.
It is intended primarily to support implicit use of such subprograms when
stream attributes are applied to string types, but the subprograms in this
package can be used directly by application programs.

.. _`System.Unsigned_Types_(s-unstyp.ads)`:

``System.Unsigned_Types`` (:file:`s-unstyp.ads`)
================================================

.. index:: System.Unsigned_Types (s-unstyp.ads)

This package contains definitions of standard unsigned types that
correspond in size to the standard signed types declared in Standard,
and (unlike the types in Interfaces) have corresponding names. It
also contains some related definitions for other specialized types
used by the compiler in connection with packed array types.

.. _`System.Wch_Cnv_(s-wchcnv.ads)`:

``System.Wch_Cnv`` (:file:`s-wchcnv.ads`)
=========================================

.. index:: System.Wch_Cnv (s-wchcnv.ads)

.. index:: Wide Character, Representation

.. index:: Wide String, Conversion

.. index:: Representation of wide characters

This package provides routines for converting between
wide and wide wide characters and a representation as a value of type
``Standard.String``, using a specified wide character
encoding method.  It uses definitions in
package ``System.Wch_Con``.

.. _`System.Wch_Con_(s-wchcon.ads)`:

``System.Wch_Con`` (:file:`s-wchcon.ads`)
=========================================

.. index:: System.Wch_Con (s-wchcon.ads)

This package provides definitions and descriptions of
the various methods used for encoding wide characters
in ordinary strings.  These definitions are used by
the package ``System.Wch_Cnv``.

---

### Gcc Ada Doc Gnat Rm The Implementation Of Standard I O (`gcc/ada/doc/gnat_rm/the_implementation_of_standard_i_o.rst`)

.. _The_Implementation_of_Standard_I/O:

**********************************
The Implementation of Standard I/O
**********************************

GNAT implements all the required input-output facilities described in
A.6 through A.14.  These sections of the Ada Reference Manual describe the
required behavior of these packages from the Ada point of view, and if
you are writing a portable Ada program that does not need to know the
exact manner in which Ada maps to the outside world when it comes to
reading or writing external files, then you do not need to read this
chapter.  As long as your files are all regular files (not pipes or
devices), and as long as you write and read the files only from Ada, the
description in the Ada Reference Manual is sufficient.

However, if you want to do input-output to pipes or other devices, such
as the keyboard or screen, or if the files you are dealing with are
either generated by some other language, or to be read by some other
language, then you need to know more about the details of how the GNAT
implementation of these input-output facilities behaves.

In this chapter we give a detailed description of exactly how GNAT
interfaces to the file system.  As always, the sources of the system are
available to you for answering questions at an even more detailed level,
but for most purposes the information in this chapter will suffice.

Another reason that you may need to know more about how input-output is
implemented arises when you have a program written in mixed languages
where, for example, files are shared between the C and Ada sections of
the same program.  GNAT provides some additional facilities, in the form
of additional child library packages, that facilitate this sharing, and
these additional facilities are also described in this chapter.

.. _Standard_I/O_Packages:

Standard I/O Packages
=====================

The Standard I/O packages described in Annex A for

*
  Ada.Text_IO
*
  Ada.Text_IO.Complex_IO
*
  Ada.Text_IO.Text_Streams
*
  Ada.Wide_Text_IO
*
  Ada.Wide_Text_IO.Complex_IO
*
  Ada.Wide_Text_IO.Text_Streams
*
  Ada.Wide_Wide_Text_IO
*
  Ada.Wide_Wide_Text_IO.Complex_IO
*
  Ada.Wide_Wide_Text_IO.Text_Streams
*
  Ada.Stream_IO
*
  Ada.Sequential_IO
*
  Ada.Direct_IO

are implemented using the C
library streams facility; where

*
  All files are opened using ``fopen``.
*
  All input/output operations use ``fread``/``fwrite``.

There is no internal buffering of any kind at the Ada library level. The only
buffering is that provided at the system level in the implementation of the
library routines that support streams. This facilitates shared use of these
streams by mixed language programs. Note though that system level buffering is
explicitly enabled at elaboration of the standard I/O packages and that can
have an impact on mixed language programs, in particular those using I/O before
calling the Ada elaboration routine (e.g., adainit). It is recommended to call
the Ada elaboration routine before performing any I/O or when impractical,
flush the common I/O streams and in particular Standard_Output before
elaborating the Ada code.

.. _FORM_Strings:

FORM Strings
============

The format of a FORM string in GNAT is:


::

  "keyword=value,keyword=value,...,keyword=value"


where letters may be in upper or lower case, and there are no spaces
between values.  The order of the entries is not important.  Currently
the following keywords defined.


::

  TEXT_TRANSLATION=[YES|NO|TEXT|BINARY|U8TEXT|WTEXT|U16TEXT]
  SHARED=[YES|NO]
  WCEM=[n|h|u|s|e|8|b]
  ENCODING=[UTF8|8BITS]


The use of these parameters is described later in this section. If an
unrecognized keyword appears in a form string, it is silently ignored
and not considered invalid.

.. _Direct_IO:

Direct_IO
=========

Direct_IO can only be instantiated for definite types.  This is a
restriction of the Ada language, which means that the records are fixed
length (the length being determined by ``type'Size``, rounded
up to the next storage unit boundary if necessary).

The records of a Direct_IO file are simply written to the file in index
sequence, with the first record starting at offset zero, and subsequent
records following.  There is no control information of any kind.  For
example, if 32-bit integers are being written, each record takes
4-bytes, so the record at index ``K`` starts at offset ``(K-1)*4``.

There is no limit on the size of Direct_IO files, they are expanded as
necessary to accommodate whatever records are written to the file.

.. _Sequential_IO:

Sequential_IO
=============

Sequential_IO may be instantiated with either a definite (constrained)
or indefinite (unconstrained) type.

For the definite type case, the elements written to the file are simply
the memory images of the data values with no control information of any
kind.  The resulting file should be read using the same type, no validity
checking is performed on input.

For the indefinite type case, the elements written consist of two
parts.  First is the size of the data item, written as the memory image
of a ``Interfaces.C.size_t`` value, followed by the memory image of
the data value.  The resulting file can only be read using the same
(unconstrained) type.  Normal assignment checks are performed on these
read operations, and if these checks fail, ``Data_Error`` is
raised.  In particular, in the array case, the lengths must match, and in
the variant record case, if the variable for a particular read operation
is constrained, the discriminants must match.

Note that it is not possible to use Sequential_IO to write variable
length array items, and then read the data back into different length
arrays.  For example, the following will raise ``Data_Error``:


.. code-block:: ada

   package IO is new Sequential_IO (String);
   F : IO.File_Type;
   S : String (1..4);
   ...
   IO.Create (F)
   IO.Write (F, "hello!")
   IO.Reset (F, Mode=>In_File);
   IO.Read (F, S);
   Put_Line (S);



On some Ada implementations, this will print ``hell``, but the program is
clearly incorrect, since there is only one element in the file, and that
element is the string ``hello!``.

In Ada 95 and Ada 2005, this kind of behavior can be legitimately achieved
using Stream_IO, and this is the preferred mechanism.  In particular, the
above program fragment rewritten to use Stream_IO will work correctly.

.. _Text_IO:

Text_IO
=======

Text_IO files consist of a stream of characters containing the following
special control characters:


::

  LF (line feed, 16#0A#) Line Mark
  FF (form feed, 16#0C#) Page Mark


A canonical Text_IO file is defined as one in which the following
conditions are met:

*
  The character ``LF`` is used only as a line mark, i.e., to mark the end
  of the line.

*
  The character ``FF`` is used only as a page mark, i.e., to mark the
  end of a page and consequently can appear only immediately following a
  ``LF`` (line mark) character.

*
  The file ends with either ``LF`` (line mark) or ``LF``-`FF`
  (line mark, page mark).  In the former case, the page mark is implicitly
  assumed to be present.

A file written using Text_IO will be in canonical form provided that no
explicit ``LF`` or ``FF`` characters are written using ``Put``
or ``Put_Line``.  There will be no ``FF`` character at the end of
the file unless an explicit ``New_Page`` operation was performed
before closing the file.

A canonical Text_IO file that is a regular file (i.e., not a device or a
pipe) can be read using any of the routines in Text_IO.  The
semantics in this case will be exactly as defined in the Ada Reference
Manual, and all the routines in Text_IO are fully implemented.

A text file that does not meet the requirements for a canonical Text_IO
file has one of the following:

*
  The file contains ``FF`` characters not immediately following a
  ``LF`` character.

*
  The file contains ``LF`` or ``FF`` characters written by
  ``Put`` or ``Put_Line``, which are not logically considered to be
  line marks or page marks.

*
  The file ends in a character other than ``LF`` or ``FF``,
  i.e., there is no explicit line mark or page mark at the end of the file.

Text_IO can be used to read such non-standard text files but subprograms
to do with line or page numbers do not have defined meanings.  In
particular, a ``FF`` character that does not follow a ``LF``
character may or may not be treated as a page mark from the point of
view of page and line numbering.  Every ``LF`` character is considered
to end a line, and there is an implied ``LF`` character at the end of
the file.

.. _Stream_Pointer_Positioning:

Stream Pointer Positioning
--------------------------

``Ada.Text_IO`` has a definition of current position for a file that
is being read.  No internal buffering occurs in Text_IO, and usually the
physical position in the stream used to implement the file corresponds
to this logical position defined by Text_IO.  There are two exceptions:

*
  After a call to ``End_Of_Page`` that returns ``True``, the stream
  is positioned past the ``LF`` (line mark) that precedes the page
  mark.  Text_IO maintains an internal flag so that subsequent read
  operations properly handle the logical position which is unchanged by
  the ``End_Of_Page`` call.

*
  After a call to ``End_Of_File`` that returns ``True``, if the
  Text_IO file was positioned before the line mark at the end of file
  before the call, then the logical position is unchanged, but the stream
  is physically positioned right at the end of file (past the line mark,
  and past a possible page mark following the line mark.  Again Text_IO
  maintains internal flags so that subsequent read operations properly
  handle the logical position.

These discrepancies have no effect on the observable behavior of
Text_IO, but if a single Ada stream is shared between a C program and
Ada program, or shared (using ``shared=yes`` in the form string)
between two Ada files, then the difference may be observable in some
situations.

.. _Reading_and_Writing_Non-Regular_Files:

Reading and Writing Non-Regular Files
-------------------------------------

A non-regular file is a device (such as a keyboard), or a pipe.  Text_IO
can be used for reading and writing.  Writing is not affected and the
sequence of characters output is identical to the normal file case, but
for reading, the behavior of Text_IO is modified to avoid undesirable
look-ahead as follows:

An input file that is not a regular file is considered to have no page
marks.  Any ``Ascii.FF`` characters (the character normally used for a
page mark) appearing in the file are considered to be data
characters.  In particular:

*
  ``Get_Line`` and ``Skip_Line`` do not test for a page mark
  following a line mark.  If a page mark appears, it will be treated as a
  data character.

*
  This avoids the need to wait for an extra character to be typed or
  entered from the pipe to complete one of these operations.

*
  ``End_Of_Page`` always returns ``False``

*
  ``End_Of_File`` will return ``False`` if there is a page mark at
  the end of the file.

Output to non-regular files is the same as for regular files.  Page marks
may be written to non-regular files using ``New_Page``, but as noted
above they will not be treated as page marks on input if the output is
piped to another Ada program.

Another important discrepancy when reading non-regular files is that the end
of file indication is not 'sticky'.  If an end of file is entered, e.g., by
pressing the :kbd:`EOT` key,
then end of file
is signaled once (i.e., the test ``End_Of_File``
will yield ``True``, or a read will
raise ``End_Error``), but then reading can resume
to read data past that end of
file indication, until another end of file indication is entered.

.. _Get_Immediate:

Get_Immediate
-------------

.. index:: Get_Immediate

Get_Immediate returns the next character (including control characters)
from the input file.  In particular, Get_Immediate will return LF or FF
characters used as line marks or page marks.  Such operations leave the
file positioned past the control character, and it is thus not treated
as having its normal function.  This means that page, line and column
counts after this kind of Get_Immediate call are set as though the mark
did not occur.  In the case where a Get_Immediate leaves the file
positioned between the line mark and page mark (which is not normally
possible), it is undefined whether the FF character will be treated as a
page mark.

.. _Treating_Text_IO_Files_as_Streams:

Treating Text_IO Files as Streams
---------------------------------

.. index:: Stream files

The package ``Text_IO.Streams`` allows a ``Text_IO`` file to be treated
as a stream.  Data written to a ``Text_IO`` file in this stream mode is
binary data.  If this binary data contains bytes 16#0A# (``LF``) or
16#0C# (``FF``), the resulting file may have non-standard
format.  Similarly if read operations are used to read from a Text_IO
file treated as a stream, then ``LF`` and ``FF`` characters may be
skipped and the effect is similar to that described above for
``Get_Immediate``.

.. _Text_IO_Extensions:

Text_IO Extensions
------------------

.. index:: Text_IO extensions

A package GNAT.IO_Aux in the GNAT library provides some useful extensions
to the standard ``Text_IO`` package:

* function File_Exists (Name : String) return Boolean;
  Determines if a file of the given name exists.

* function Get_Line return String;
  Reads a string from the standard input file.  The value returned is exactly
  the length of the line that was read.

* function Get_Line (File : Ada.Text_IO.File_Type) return String;
  Similar, except that the parameter File specifies the file from which
  the string is to be read.


.. _Text_IO_Facilities_for_Unbounded_Strings:

Text_IO Facilities for Unbounded Strings
----------------------------------------

.. index:: Text_IO for unbounded strings

.. index:: Unbounded_String, Text_IO operations

The package ``Ada.Strings.Unbounded.Text_IO``
in library files :file:`a-suteio.ads/adb` contains some GNAT-specific
subprograms useful for Text_IO operations on unbounded strings:


* function Get_Line (File : File_Type) return Unbounded_String;
  Reads a line from the specified file
  and returns the result as an unbounded string.

* procedure Put (File : File_Type; U : Unbounded_String);
  Writes the value of the given unbounded string to the specified file
  Similar to the effect of
  ``Put (To_String (U))`` except that an extra copy is avoided.

* procedure Put_Line (File : File_Type; U : Unbounded_String);
  Writes the value of the given unbounded string to the specified file,
  followed by a ``New_Line``.
  Similar to the effect of ``Put_Line (To_String (U))`` except
  that an extra copy is avoided.

In the above procedures, ``File`` is of type ``Ada.Text_IO.File_Type``
and is optional.  If the parameter is omitted, then the standard input or
output file is referenced as appropriate.

The package ``Ada.Strings.Wide_Unbounded.Wide_Text_IO`` in library
files :file:`a-swuwti.ads` and :file:`a-swuwti.adb` provides similar extended
``Wide_Text_IO`` functionality for unbounded wide strings.

The package ``Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO`` in library
files :file:`a-szuzti.ads` and :file:`a-szuzti.adb` provides similar extended
``Wide_Wide_Text_IO`` functionality for unbounded wide wide strings.

.. _Wide_Text_IO:

Wide_Text_IO
============

``Wide_Text_IO`` is similar in most respects to Text_IO, except that
both input and output files may contain special sequences that represent
wide character values.  The encoding scheme for a given file may be
specified using a FORM parameter:


::

  WCEM=`x`


as part of the FORM string (WCEM = wide character encoding method),
where ``x`` is one of the following characters

========== ====================
Character  Encoding
========== ====================
*h*        Hex ESC encoding
*u*        Upper half encoding
*s*        Shift-JIS encoding
*e*        EUC Encoding
*8*        UTF-8 encoding
*b*        Brackets encoding
========== ====================

The encoding methods match those that
can be used in a source
program, but there is no requirement that the encoding method used for
the source program be the same as the encoding method used for files,
and different files may use different encoding methods.

The default encoding method for the standard files, and for opened files
for which no WCEM parameter is given in the FORM string matches the
wide character encoding specified for the main program (the default
being brackets encoding if no coding method was specified with -gnatW).



*Hex Coding*
  In this encoding, a wide character is represented by a five character
  sequence:


::

    ESC a b c d

..

  where ``a``, ``b``, ``c``, ``d`` are the four hexadecimal
  characters (using upper case letters) of the wide character code.  For
  example, ESC A345 is used to represent the wide character with code
  16#A345#.  This scheme is compatible with use of the full
  ``Wide_Character`` set.


*Upper Half Coding*
  The wide character with encoding 16#abcd#, where the upper bit is on
  (i.e., a is in the range 8-F) is represented as two bytes 16#ab# and
  16#cd#.  The second byte may never be a format control character, but is
  not required to be in the upper half.  This method can be also used for
  shift-JIS or EUC where the internal coding matches the external coding.


*Shift JIS Coding*
  A wide character is represented by a two character sequence 16#ab# and
  16#cd#, with the restrictions described for upper half encoding as
  described above.  The internal character code is the corresponding JIS
  character according to the standard algorithm for Shift-JIS
  conversion.  Only characters defined in the JIS code set table can be
  used with this encoding method.


*EUC Coding*
  A wide character is represented by a two character sequence 16#ab# and
  16#cd#, with both characters being in the upper half.  The internal
  character code is the corresponding JIS character according to the EUC
  encoding algorithm.  Only characters defined in the JIS code set table
  can be used with this encoding method.


*UTF-8 Coding*
  A wide character is represented using
  UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
  10646-1/Am.2.  Depending on the character value, the representation
  is a one, two, or three byte sequence:


::

    16#0000#-16#007f#: 2#0xxxxxxx#
    16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx#
    16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#

..

  where the ``xxx`` bits correspond to the left-padded bits of the
  16-bit character value.  Note that all lower half ASCII characters
  are represented as ASCII bytes and all upper half characters and
  other wide characters are represented as sequences of upper-half
  (The full UTF-8 scheme allows for encoding 31-bit characters as
  6-byte sequences, but in this implementation, all UTF-8 sequences
  of four or more bytes length will raise a Constraint_Error, as
  will all invalid UTF-8 sequences.)


*Brackets Coding*
  In this encoding, a wide character is represented by the following eight
  character sequence:


::

    [ " a b c d " ]

..

  where ``a``, ``b``, ``c``, ``d`` are the four hexadecimal
  characters (using uppercase letters) of the wide character code.  For
  example, ``["A345"]`` is used to represent the wide character with code
  ``16#A345#``.
  This scheme is compatible with use of the full Wide_Character set.
  On input, brackets coding can also be used for upper half characters,
  e.g., ``["C1"]`` for lower case a.  However, on output, brackets notation
  is only used for wide characters with a code greater than ``16#FF#``.

  Note that brackets coding is not normally used in the context of
  Wide_Text_IO or Wide_Wide_Text_IO, since it is really just designed as
  a portable way of encoding source files. In the context of Wide_Text_IO
  or Wide_Wide_Text_IO, it can only be used if the file does not contain
  any instance of the left bracket character other than to encode wide
  character values using the brackets encoding method. In practice it is
  expected that some standard wide character encoding method such
  as UTF-8 will be used for text input output.

  If brackets notation is used, then any occurrence of a left bracket
  in the input file which is not the start of a valid wide character
  sequence will cause Constraint_Error to be raised. It is possible to
  encode a left bracket as ["5B"] and Wide_Text_IO and Wide_Wide_Text_IO
  input will interpret this as a left bracket.

  However, when a left bracket is output, it will be output as a left bracket
  and not as ["5B"]. We make this decision because for normal use of
  Wide_Text_IO for outputting messages, it is unpleasant to clobber left
  brackets. For example, if we write:


  .. code-block:: ada

       Put_Line ("Start of output [first run]");


  we really do not want to have the left bracket in this message clobbered so
  that the output reads:


::

       Start of output ["5B"]first run]

..

  In practice brackets encoding is reasonably useful for normal Put_Line use
  since we won't get confused between left brackets and wide character
  sequences in the output. But for input, or when files are written out
  and read back in, it really makes better sense to use one of the standard
  encoding methods such as UTF-8.


For the coding schemes other than UTF-8, Hex, or Brackets encoding,
not all wide character
values can be represented.  An attempt to output a character that cannot
be represented using the encoding scheme for the file causes
Constraint_Error to be raised.  An invalid wide character sequence on
input also causes Constraint_Error to be raised.

.. _Stream_Pointer_Positioning_1:

Stream Pointer Positioning
--------------------------

``Ada.Wide_Text_IO`` is similar to ``Ada.Text_IO`` in its handling
of stream pointer positioning (:ref:`Text_IO`).  There is one additional
case:

If ``Ada.Wide_Text_IO.Look_Ahead`` reads a character outside the
normal lower ASCII set, i.e. a character in the range:


.. code-block:: ada

  Wide_Character'Val (16#0080#) .. Wide_Character'Val (16#FFFF#)


then although the logical position of the file pointer is unchanged by
the ``Look_Ahead`` call, the stream is physically positioned past the
wide character sequence.  Again this is to avoid the need for buffering
or backup, and all ``Wide_Text_IO`` routines check the internal
indication that this situation has occurred so that this is not visible
to a normal program using ``Wide_Text_IO``.  However, this discrepancy
can be observed if the wide text file shares a stream with another file.

.. _Reading_and_Writing_Non-Regular_Files_1:

Reading and Writing Non-Regular Files
-------------------------------------

As in the case of Text_IO, when a non-regular file is read, it is
assumed that the file contains no page marks (any form characters are
treated as data characters), and ``End_Of_Page`` always returns
``False``.  Similarly, the end of file indication is not sticky, so
it is possible to read beyond an end of file.

.. _Wide_Wide_Text_IO:

Wide_Wide_Text_IO
=================

``Wide_Wide_Text_IO`` is similar in most respects to Text_IO, except that
both input and output files may contain special sequences that represent
wide wide character values.  The encoding scheme for a given file may be
specified using a FORM parameter:


::

  WCEM=`x`


as part of the FORM string (WCEM = wide character encoding method),
where ``x`` is one of the following characters

========== ====================
Character  Encoding
========== ====================
*h*        Hex ESC encoding
*u*        Upper half encoding
*s*        Shift-JIS encoding
*e*        EUC Encoding
*8*        UTF-8 encoding
*b*        Brackets encoding
========== ====================


The encoding methods match those that
can be used in a source
program, but there is no requirement that the encoding method used for
the source program be the same as the encoding method used for files,
and different files may use different encoding methods.

The default encoding method for the standard files, and for opened files
for which no WCEM parameter is given in the FORM string matches the
wide character encoding specified for the main program (the default
being brackets encoding if no coding method was specified with -gnatW).



*UTF-8 Coding*
  A wide character is represented using
  UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
  10646-1/Am.2.  Depending on the character value, the representation
  is a one, two, three, or four byte sequence:


::

    16#000000#-16#00007f#: 2#0xxxxxxx#
    16#000080#-16#0007ff#: 2#110xxxxx# 2#10xxxxxx#
    16#000800#-16#00ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#
    16#010000#-16#10ffff#: 2#11110xxx# 2#10xxxxxx# 2#10xxxxxx# 2#10xxxxxx#

..

  where the ``xxx`` bits correspond to the left-padded bits of the
  21-bit character value.  Note that all lower half ASCII characters
  are represented as ASCII bytes and all upper half characters and
  other wide characters are represented as sequences of upper-half
  characters.


*Brackets Coding*
  In this encoding, a wide wide character is represented by the following eight
  character sequence if is in wide character range


::

    [ " a b c d " ]

..

  and by the following ten character sequence if not


::

    [ " a b c d e f " ]

..

  where ``a``, ``b``, ``c``, ``d``, ``e``, and ``f``
  are the four or six hexadecimal
  characters (using uppercase letters) of the wide wide character code.  For
  example, ``["01A345"]`` is used to represent the wide wide character
  with code ``16#01A345#``.

  This scheme is compatible with use of the full Wide_Wide_Character set.
  On input, brackets coding can also be used for upper half characters,
  e.g., ``["C1"]`` for lower case a.  However, on output, brackets notation
  is only used for wide characters with a code greater than ``16#FF#``.


If is also possible to use the other Wide_Character encoding methods,
such as Shift-JIS, but the other schemes cannot support the full range
of wide wide characters.
An attempt to output a character that cannot
be represented using the encoding scheme for the file causes
Constraint_Error to be raised.  An invalid wide character sequence on
input also causes Constraint_Error to be raised.

.. _Stream_Pointer_Positioning_2:

Stream Pointer Positioning
--------------------------

``Ada.Wide_Wide_Text_IO`` is similar to ``Ada.Text_IO`` in its handling
of stream pointer positioning (:ref:`Text_IO`).  There is one additional
case:

If ``Ada.Wide_Wide_Text_IO.Look_Ahead`` reads a character outside the
normal lower ASCII set, i.e. a character in the range:


.. code-block:: ada

  Wide_Wide_Character'Val (16#0080#) .. Wide_Wide_Character'Val (16#10FFFF#)


then although the logical position of the file pointer is unchanged by
the ``Look_Ahead`` call, the stream is physically positioned past the
wide character sequence.  Again this is to avoid the need for buffering
or backup, and all ``Wide_Wide_Text_IO`` routines check the internal
indication that this situation has occurred so that this is not visible
to a normal program using ``Wide_Wide_Text_IO``.  However, this discrepancy
can be observed if the wide text file shares a stream with another file.

.. _Reading_and_Writing_Non-Regular_Files_2:

Reading and Writing Non-Regular Files
-------------------------------------

As in the case of Text_IO, when a non-regular file is read, it is
assumed that the file contains no page marks (any form characters are
treated as data characters), and ``End_Of_Page`` always returns
``False``.  Similarly, the end of file indication is not sticky, so
it is possible to read beyond an end of file.

.. _Stream_IO:

Stream_IO
=========

A stream file is a sequence of bytes, where individual elements are
written to the file as described in the Ada Reference Manual.  The type
``Stream_Element`` is simply a byte.  There are two ways to read or
write a stream file.

*
  The operations ``Read`` and ``Write`` directly read or write a
  sequence of stream elements with no control information.

*
  The stream attributes applied to a stream file transfer data in the
  manner described for stream attributes.

.. _Text_Translation:

Text Translation
================

``Text_Translation=xxx`` may be used as the Form parameter
passed to Text_IO.Create and Text_IO.Open. ``Text_Translation=xxx``
has no effect on Unix systems. Possible values are:


*
  ``Yes`` or ``Text`` is the default, which means to
  translate LF to/from CR/LF on Windows systems.

  ``No`` disables this translation; i.e. it
  uses binary mode. For output files, ``Text_Translation=No``
  may be used to create Unix-style files on
  Windows.

*
  ``wtext`` translation enabled in Unicode mode.
  (corresponds to _O_WTEXT).

*
  ``u8text`` translation enabled in Unicode UTF-8 mode.
  (corresponds to O_U8TEXT).

*
  ``u16text`` translation enabled in Unicode UTF-16
  mode. (corresponds to_O_U16TEXT).


.. _Shared_Files:

Shared Files
============

Section A.14 of the Ada Reference Manual allows implementations to
provide a wide variety of behavior if an attempt is made to access the
same external file with two or more internal files.

To provide a full range of functionality, while at the same time
minimizing the problems of portability caused by this implementation
dependence, GNAT handles file sharing as follows:

*
  In the absence of a ``shared=xxx`` form parameter, an attempt
  to open two or more files with the same full name is considered an error
  and is not supported.  The exception ``Use_Error`` will be
  raised.  Note that a file that is not explicitly closed by the program
  remains open until the program terminates.

*
  If the form parameter ``shared=no`` appears in the form string, the
  file can be opened or created with its own separate stream identifier,
  regardless of whether other files sharing the same external file are
  opened.  The exact effect depends on how the C stream routines handle
  multiple accesses to the same external files using separate streams.

*
  If the form parameter ``shared=yes`` appears in the form string for
  each of two or more files opened using the same full name, the same
  stream is shared between these files, and the semantics are as described
  in Ada Reference Manual, Section A.14.

When a program that opens multiple files with the same name is ported
from another Ada compiler to GNAT, the effect will be that
``Use_Error`` is raised.

The documentation of the original compiler and the documentation of the
program should then be examined to determine if file sharing was
expected, and ``shared=xxx`` parameters added to ``Open``
and ``Create`` calls as required.

When a program is ported from GNAT to some other Ada compiler, no
special attention is required unless the ``shared=xxx`` form
parameter is used in the program.  In this case, you must examine the
documentation of the new compiler to see if it supports the required
file sharing semantics, and form strings modified appropriately.  Of
course it may be the case that the program cannot be ported if the
target compiler does not support the required functionality.  The best
approach in writing portable code is to avoid file sharing (and hence
the use of the ``shared=xxx`` parameter in the form string)
completely.

One common use of file sharing in Ada 83 is the use of instantiations of
Sequential_IO on the same file with different types, to achieve
heterogeneous input-output.  Although this approach will work in GNAT if
``shared=yes`` is specified, it is preferable in Ada to use Stream_IO
for this purpose (using the stream attributes).

.. _Filenames_encoding:

Filenames encoding
==================

An encoding form parameter can be used to specify the filename
encoding ``encoding=xxx``.

*
  If the form parameter ``encoding=utf8`` appears in the form string, the
  filename must be encoded in UTF-8.

*
  If the form parameter ``encoding=8bits`` appears in the form
  string, the filename must be a standard 8bits string.

In the absence of a ``encoding=xxx`` form parameter, the
encoding is controlled by the ``GNAT_CODE_PAGE`` environment
variable. And if not set ``utf8`` is assumed.



*CP_ACP*
  The current system Windows ANSI code page.

*CP_UTF8*
  UTF-8 encoding

This encoding form parameter is only supported on the Windows
platform. On the other Operating Systems the run-time is supporting
UTF-8 natively.

.. _File_content_encoding:

File content encoding
=====================

For text files it is possible to specify the encoding to use. This is
controlled by the by the ``GNAT_CCS_ENCODING`` environment
variable. And if not set ``TEXT`` is assumed.

The possible values are those supported on Windows:



*TEXT*
  Translated text mode

*WTEXT*
  Translated unicode encoding

*U16TEXT*
  Unicode 16-bit encoding

*U8TEXT*
  Unicode 8-bit encoding

This encoding is only supported on the Windows platform.

.. _Open_Modes:

Open Modes
==========

``Open`` and ``Create`` calls result in a call to ``fopen``
using the mode shown in the following table:

+----------------------------+---------------+------------------+
|           ``Open`` and ``Create`` Call Modes                  |
+----------------------------+---------------+------------------+
|                            |   **OPEN**    |     **CREATE**   |
+============================+===============+==================+
| Append_File                |   "r+"        |    "w+"          |
+----------------------------+---------------+------------------+
| In_File                    |   "r"         |    "w+"          |
+----------------------------+---------------+------------------+
| Out_File (Direct_IO)       |   "r+"        |    "w"           |
+----------------------------+---------------+------------------+
| Out_File (all other cases) |   "w"         |    "w"           |
+----------------------------+---------------+------------------+
| Inout_File                 |   "r+"        |    "w+"          |
+----------------------------+---------------+------------------+


If text file translation is required, then either ``b`` or ``t``
is added to the mode, depending on the setting of Text.  Text file
translation refers to the mapping of CR/LF sequences in an external file
to LF characters internally.  This mapping only occurs in DOS and
DOS-like systems, and is not relevant to other systems.

A special case occurs with Stream_IO.  As shown in the above table, the
file is initially opened in ``r`` or ``w`` mode for the
``In_File`` and ``Out_File`` cases.  If a ``Set_Mode`` operation
subsequently requires switching from reading to writing or vice-versa,
then the file is reopened in ``r+`` mode to permit the required operation.

.. _Operations_on_C_Streams:

Operations on C Streams
=======================

The package ``Interfaces.C_Streams`` provides an Ada program with direct
access to the C library functions for operations on C streams:


.. code-block:: ada

  package Interfaces.C_Streams is
    -- Note: the reason we do not use the types that are in
    -- Interfaces.C is that we want to avoid dragging in the
    -- code in this unit if possible.
    subtype chars is System.Address;
    -- Pointer to null-terminated array of characters
    subtype FILEs is System.Address;
    -- Corresponds to the C type FILE*
    subtype voids is System.Address;
    -- Corresponds to the C type void*
    subtype int is Integer;
    subtype long is Long_Integer;
    -- Note: the above types are subtypes deliberately, and it
    -- is part of this spec that the above correspondences are
    -- guaranteed.  This means that it is legitimate to, for
    -- example, use Integer instead of int.  We provide these
    -- synonyms for clarity, but in some cases it may be
    -- convenient to use the underlying types (for example to
    -- avoid an unnecessary dependency of a spec on the spec
    -- of this unit).
    type size_t is mod 2 ** Standard'Address_Size;
    NULL_Stream : constant FILEs;
    -- Value returned (NULL in C) to indicate an
    -- fdopen/fopen/tmpfile error
    ----------------------------------
    -- Constants Defined in stdio.h --
    ----------------------------------
    EOF : constant int;
    -- Used by a number of routines to indicate error or
    -- end of file
    IOFBF : constant int;
    IOLBF : constant int;
    IONBF : constant int;
    -- Used to indicate buffering mode for setvbuf call
    SEEK_CUR : constant int;
    SEEK_END : constant int;
    SEEK_SET : constant int;
    -- Used to indicate origin for fseek call
    function stdin return FILEs;
    function stdout return FILEs;
    function stderr return FILEs;
    -- Streams associated with standard files
    --------------------------
    -- Standard C functions --
    --------------------------
    -- The functions selected below are ones that are
    -- available in UNIX (but not necessarily in ANSI C).
    -- These are very thin interfaces
    -- which copy exactly the C headers.  For more
    -- documentation on these functions, see the Microsoft C
    -- "Run-Time Library Reference" (Microsoft Press, 1990,
    -- ISBN 1-55615-225-6), which includes useful information
    -- on system compatibility.
    procedure clearerr (stream : FILEs);
    function fclose (stream : FILEs) return int;
    function fdopen (handle : int; mode : chars) return FILEs;
    function feof (stream : FILEs) return int;
    function ferror (stream : FILEs) return int;
    function fflush (stream : FILEs) return int;
    function fgetc (stream : FILEs) return int;
    function fgets (strng : chars; n : int; stream : FILEs)
        return chars;
    function fileno (stream : FILEs) return int;
    function fopen (filename : chars; Mode : chars)
        return FILEs;
    -- Note: to maintain target independence, use
    -- text_translation_required, a boolean variable defined in
    -- a-sysdep.c to deal with the target dependent text
    -- translation requirement.  If this variable is set,
    -- then  b/t should be appended to the standard mode
    -- argument to set the text translation mode off or on
    -- as required.
    function fputc (C : int; stream : FILEs) return int;
    function fputs (Strng : chars; Stream : FILEs) return int;
    function fread
       (buffer : voids;
        size : size_t;
        count : size_t;
        stream : FILEs)
        return size_t;
    function freopen
       (filename : chars;
        mode : chars;
        stream : FILEs)
        return FILEs;
    function fseek
       (stream : FILEs;
        offset : long;
        origin : int)
        return int;
    function ftell (stream : FILEs) return long;
    function fwrite
       (buffer : voids;
        size : size_t;
        count : size_t;
        stream : FILEs)
        return size_t;
    function isatty (handle : int) return int;
    procedure mktemp (template : chars);
    -- The return value (which is just a pointer to template)
    -- is discarded
    procedure rewind (stream : FILEs);
    function rmtmp return int;
    function setvbuf
       (stream : FILEs;
        buffer : chars;
        mode : int;
        size : size_t)
        return int;

    function tmpfile return FILEs;
    function ungetc (c : int; stream : FILEs) return int;
    function unlink (filename : chars) return int;
    ---------------------
    -- Extra functions --
    ---------------------
    -- These functions supply slightly thicker bindings than
    -- those above.  They are derived from functions in the
    -- C Run-Time Library, but may do a bit more work than
    -- just directly calling one of the Library functions.
    function is_regular_file (handle : int) return int;
    -- Tests if given handle is for a regular file (result 1)
    -- or for a non-regular file (pipe or device, result 0).
    ---------------------------------
    -- Control of Text/Binary Mode --
    ---------------------------------
    -- If text_translation_required is true, then the following
    -- functions may be used to dynamically switch a file from
    -- binary to text mode or vice versa.  These functions have
    -- no effect if text_translation_required is false (i.e., in
    -- normal UNIX mode).  Use fileno to get a stream handle.
    procedure set_binary_mode (handle : int);
    procedure set_text_mode (handle : int);
    ----------------------------
    -- Full Path Name support --
    ----------------------------
    procedure full_name (nam : chars; buffer : chars);
    -- Given a NUL terminated string representing a file
    -- name, returns in buffer a NUL terminated string
    -- representing the full path name for the file name.
    -- On systems where it is relevant the   drive is also
    -- part of the full path name.  It is the responsibility
    -- of the caller to pass an actual parameter for buffer
    -- that is big enough for any full path name.  Use
    -- max_path_len given below as the size of buffer.
    max_path_len : integer;
    -- Maximum length of an allowable full path name on the
    -- system, including a terminating NUL character.
  end Interfaces.C_Streams;


.. _Interfacing_to_C_Streams:

Interfacing to C Streams
========================

The packages in this section permit interfacing Ada files to C Stream
operations.


.. code-block:: ada

   with Interfaces.C_Streams;
   package Ada.Sequential_IO.C_Streams is
      function C_Stream (F : File_Type)
         return Interfaces.C_Streams.FILEs;
      procedure Open
        (File : in out File_Type;
         Mode : in File_Mode;
         C_Stream : in Interfaces.C_Streams.FILEs;
         Form : in String := "");
   end Ada.Sequential_IO.C_Streams;

    with Interfaces.C_Streams;
    package Ada.Direct_IO.C_Streams is
       function C_Stream (F : File_Type)
          return Interfaces.C_Streams.FILEs;
       procedure Open
         (File : in out File_Type;
          Mode : in File_Mode;
          C_Stream : in Interfaces.C_Streams.FILEs;
          Form : in String := "");
    end Ada.Direct_IO.C_Streams;

    with Interfaces.C_Streams;
    package Ada.Text_IO.C_Streams is
       function C_Stream (F : File_Type)
          return Interfaces.C_Streams.FILEs;
       procedure Open
         (File : in out File_Type;
          Mode : in File_Mode;
          C_Stream : in Interfaces.C_Streams.FILEs;
          Form : in String := "");
    end Ada.Text_IO.C_Streams;

    with Interfaces.C_Streams;
    package Ada.Wide_Text_IO.C_Streams is
       function C_Stream (F : File_Type)
          return Interfaces.C_Streams.FILEs;
       procedure Open
         (File : in out File_Type;
          Mode : in File_Mode;
          C_Stream : in Interfaces.C_Streams.FILEs;
          Form : in String := "");
   end Ada.Wide_Text_IO.C_Streams;

    with Interfaces.C_Streams;
    package Ada.Wide_Wide_Text_IO.C_Streams is
       function C_Stream (F : File_Type)
          return Interfaces.C_Streams.FILEs;
       procedure Open
         (File : in out File_Type;
          Mode : in File_Mode;
          C_Stream : in Interfaces.C_Streams.FILEs;
          Form : in String := "");
   end Ada.Wide_Wide_Text_IO.C_Streams;

   with Interfaces.C_Streams;
   package Ada.Stream_IO.C_Streams is
      function C_Stream (F : File_Type)
         return Interfaces.C_Streams.FILEs;
      procedure Open
        (File : in out File_Type;
         Mode : in File_Mode;
         C_Stream : in Interfaces.C_Streams.FILEs;
         Form : in String := "");
   end Ada.Stream_IO.C_Streams;


In each of these six packages, the ``C_Stream`` function obtains the
``FILE`` pointer from a currently opened Ada file.  It is then
possible to use the ``Interfaces.C_Streams`` package to operate on
this stream, or the stream can be passed to a C program which can
operate on it directly.  Of course the program is responsible for
ensuring that only appropriate sequences of operations are executed.

One particular use of relevance to an Ada program is that the
``setvbuf`` function can be used to control the buffering of the
stream used by an Ada file.  In the absence of such a call the standard
default buffering is used.

The ``Open`` procedures in these packages open a file giving an
existing C Stream instead of a file name.  Typically this stream is
imported from a C program, allowing an Ada file to operate on an
existing C file.

---

### Gcc Ada Doc Gnat Ugn About This Guide (`gcc/ada/doc/gnat_ugn/about_this_guide.rst`)

.. _About_This_Guide:

About This Guide
~~~~~~~~~~~~~~~~

.. only:: PRO

   For ease of exposition, 'GNAT Pro' will be referred to simply as
   'GNAT' in the remainder of this document.

This guide describes the use of GNAT,
a compiler and software development
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 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.

GNAT supports both the GCC and LLVM back end compilation families.
Most GNAT versions use the GCC back end, but some are now available using
the LLVM back end. In some places in this manual, we distinguish between
the two back ends, but in most cases, everything in this manual applies
to both back ends. We refer to GNAT with the LLVM back end as 'GNAT LLVM'.
See :ref:`GNATLLVM` for limitations of GNAT LLVM.

What This Guide Contains
========================

This guide contains the following chapters:

* :ref:`Getting_Started_with_GNAT` describes how to get started compiling
  and running Ada programs with the GNAT Ada programming environment.

* :ref:`The_GNAT_Compilation_Model` describes the compilation model used
  by GNAT.

* :ref:`Building_Executable_Programs_With_GNAT` describes how to use the
  main GNAT tools to build executable programs, and it also gives examples of
  using the GNU make utility with GNAT.

* :ref:`GNAT_Utility_Programs` explains the various utility programs that
  are included in the GNAT environment.

* :ref:`GNAT_and_Program_Execution` covers a number of topics related to
  running, debugging, and tuning the performance of programs developed
  with GNAT.

Appendices cover several additional topics:

* :ref:`Platform_Specific_Information` describes the different run-time
  library implementations and also presents information on how to use
  GNAT on several specific platforms.

* :ref:`Example_of_Binder_Output_File` shows the source code for the binder
  output file for a sample program.

* :ref:`Elaboration_Order_Handling_in_GNAT` describes how GNAT helps
  you deal with elaboration order issues.

* :ref:`Inline_Assembler` shows how to use the inline assembly facility
  in an Ada program.



What You Should Know before Reading This Guide
==============================================

.. index:: Ada 95 Language Reference Manual

.. index:: Ada 2005 Language Reference Manual

This guide assumes a basic familiarity with the Ada 95 language, as
described in the International Standard ANSI/ISO/IEC-8652:1995, January
1995.
Reference manuals for Ada 95, Ada 2005, Ada 2012 and Ada 2022 are included in
the GNAT documentation package.


Related Information
===================

For further information about Ada and related tools, please refer to the
following documents:

* :title:`Ada 95 Reference Manual`, :title:`Ada 2005 Reference Manual`,
  :title:`Ada 2012 Reference Manual`,  and :title:`Ada 2022 Reference Manual`,
  which contain reference material for the several revisions of the Ada language
  standard.

* :title:`GNAT Reference Manual`, which contains all reference material for the GNAT
  implementation of Ada.

* :title:`Using GNAT Studio`, which describes the GNAT Studio
  Integrated Development Environment.

* :title:`GNAT Studio Tutorial`, which introduces the
  main GNAT Studio features through examples.

* :title:`Debugging with GDB`,
  for all details on the use of the GNU source-level debugger.

Conventions
===========
.. index:: Conventions, typographical

.. index:: Typographical conventions

Following are examples of the typographical and graphic conventions used
in this guide:

* ``Functions``, ``utility program names``, ``standard names``,
  and ``classes``.

* ``Option flags``

* :file:`File names`

* ``Variables``

* *Emphasis*

* [optional information or parameters]

* Examples are described by text

  .. code-block:: text

     and then shown this way.

* 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
  you should use the '\\' character instead.

---

### Gcc Ada Doc Gnat Ugn Building Executable Programs With Gnat (`gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst`)

.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing

.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit

.. role:: switch(samp)

.. _Building_Executable_Programs_With_GNAT:

**************************************
Building Executable Programs with GNAT
**************************************

This chapter describes first the gnatmake tool
(:ref:`The_GNAT_Make_Program_gnatmake`),
which automatically determines the set of sources
needed by an Ada compilation unit and executes the necessary
(re)compilations, binding and linking.
It also explains how to use each tool individually: the
compiler (gcc, see :ref:`Compiling_with_gcc`),
binder (gnatbind, see :ref:`Binding_with_gnatbind`),
and linker (gnatlink, see :ref:`Linking_with_gnatlink`)
to build executable programs.
Finally, this chapter provides examples of
how to make use of the general GNU make mechanism
in a GNAT context (see :ref:`Using_the_GNU_make_Utility`).

.. only:: PRO or GPL

   For building large systems with components possibly written
   in different languages (such as Ada, C, C++ and Fortran)
   and organized into subsystems and libraries, the GPRbuild
   tool can be used. This tool, and the Project Manager
   facility that it is based upon, is described in
   *GPRbuild and GPR Companion Tools User's Guide*.


.. _The_GNAT_Make_Program_gnatmake:

Building with ``gnatmake``
==========================

.. index:: gnatmake

A typical development cycle when working on an Ada program consists of
the following steps:

#. Edit some sources to fix bugs;

#. Add enhancements;

#. Compile all sources affected;

#. Rebind and relink; and

#. Test.

.. index:: Dependency rules (compilation)

The third step in particular can be tricky, because not only do the modified
files have to be compiled, but any files depending on these files must also be
recompiled. The dependency rules in Ada can be quite complex, especially
in the presence of overloading, ``use`` clauses, generics and inlined
subprograms.

``gnatmake`` automatically takes care of the third and fourth steps
of this process. It determines which sources need to be compiled,
compiles them, and binds and links the resulting object files.

Unlike some other Ada make programs, the dependencies are always
accurately recomputed from the new sources. The source based approach of
the GNAT compilation model makes this possible. This means that if
changes to the source program cause corresponding changes in
dependencies, they will always be tracked exactly correctly by
``gnatmake``.

Note that for advanced forms of project structure, we recommend creating
a project file as explained in the *GNAT_Project_Manager* chapter in the
*GPRbuild User's Guide*, and using the
``gprbuild`` tool which supports building with project files and works similarly
to ``gnatmake``.

.. _Running_gnatmake:

Running ``gnatmake``
--------------------

The usual form of the ``gnatmake`` command is

.. code-block:: sh

     $ gnatmake [<switches>] <file_name> [<file_names>] [<mode_switches>]

The only required argument is one ``file_name``, which specifies
a compilation unit that is a main program. Several ``file_names`` can be
specified: this will result in several executables being built.
If ``switches`` are present, they can be placed before the first
``file_name``, between ``file_names`` or after the last ``file_name``.
If ``mode_switches`` are present, they must always be placed after
the last ``file_name`` and all ``switches``.

If you are using standard file extensions (:file:`.adb` and
:file:`.ads`), then the
extension may be omitted from the ``file_name`` arguments. However, if
you are using non-standard extensions, then it is required that the
extension be given. A relative or absolute directory path can be
specified in a ``file_name``, in which case, the input source file will
be searched for in the specified directory only. Otherwise, the input
source file will first be searched in the directory where
``gnatmake`` was invoked and if it is not found, it will be search on
the source path of the compiler as described in
:ref:`Search_Paths_and_the_Run-Time_Library_RTL`.

All ``gnatmake`` output (except when you specify :switch:`-M`) is sent to
:file:`stderr`. The output produced by the
:switch:`-M` switch is sent to :file:`stdout`.


.. _Switches_for_gnatmake:

Switches for ``gnatmake``
-------------------------

You may specify any of the following switches to ``gnatmake``:


.. index:: --version  (gnatmake)

:switch:`--version`
  Display Copyright and version, then exit disregarding all other options.


.. index:: --help  (gnatmake)

:switch:`--help`
  If ``--version`` was not used, display usage, then exit disregarding
  all other options.


.. index:: -P  (gnatmake)

:switch:`-P{project}`
  Build GNAT project file ``project`` using GPRbuild. When this switch is
  present, all other command-line switches are treated as GPRbuild switches
  and not ``gnatmake`` switches.

.. -- Comment:
  :ref:`gnatmake_and_Project_Files`.


.. index:: --GCC=compiler_name  (gnatmake)

:switch:`--GCC={compiler_name}`
  Program used for compiling. The default is ``gcc``. You need to use
  quotes around ``compiler_name`` if ``compiler_name`` contains
  spaces or other separator characters.
  As an example ``--GCC="foo -x  -y"``
  will instruct ``gnatmake`` to use ``foo -x -y`` as your
  compiler. A limitation of this syntax is that the name and path name of
  the executable itself must not include any embedded spaces. Note that
  switch :switch:`-c` is always inserted after your command name. Thus in the
  above example the compiler command that will be used by ``gnatmake``
  will be ``foo -c -x -y``. If several ``--GCC=compiler_name`` are
  used, only the last ``compiler_name`` is taken into account. However,
  all the additional switches are also taken into account. Thus,
  ``--GCC="foo -x -y" --GCC="bar -z -t"`` is equivalent to
  ``--GCC="bar -x -y -z -t"``.


.. index:: --GNATBIND=binder_name  (gnatmake)

:switch:`--GNATBIND={binder_name}`
  Program used for binding. The default is ``gnatbind``. You need to
  use quotes around ``binder_name`` if ``binder_name`` contains spaces
  or other separator characters.
  As an example ``--GNATBIND="bar -x  -y"``
  will instruct ``gnatmake`` to use ``bar -x -y`` as your
  binder. Binder switches that are normally appended by ``gnatmake``
  to ``gnatbind`` are now appended to the end of ``bar -x -y``.
  A limitation of this syntax is that the name and path name of the executable
  itself must not include any embedded spaces.

.. index:: --GNATLINK=linker_name  (gnatmake)

:switch:`--GNATLINK={linker_name}`
  Program used for linking. The default is ``gnatlink``. You need to
  use quotes around ``linker_name`` if ``linker_name`` contains spaces
  or other separator characters.
  As an example ``--GNATLINK="lan -x  -y"``
  will instruct ``gnatmake`` to use ``lan -x -y`` as your
  linker. Linker switches that are normally appended by ``gnatmake`` to
  ``gnatlink`` are now appended to the end of ``lan -x -y``.
  A limitation of this syntax is that the name and path name of the executable
  itself must not include any embedded spaces.

:switch:`--create-map-file`
  When linking an executable, create a map file. The name of the map file
  has the same name as the executable with extension ".map".

:switch:`--create-map-file={mapfile}`
  When linking an executable, create a map file with the specified name.

.. index:: --create-missing-dirs  (gnatmake)

:switch:`--create-missing-dirs`
  When using project files (:switch:`-P{project}`), automatically create
  missing object directories, library directories and exec
  directories.

:switch:`--single-compile-per-obj-dir`
  Disallow simultaneous compilations in the same object directory when
  project files are used.

:switch:`--subdirs={subdir}`
  Actual object directory of each project file is the subdirectory subdir of the
  object directory specified or defaulted in the project file.

:switch:`--unchecked-shared-lib-imports`
  By default, shared library projects are not allowed to import static library
  projects. When this switch is used on the command line, this restriction is
  relaxed.

:switch:`--source-info={source info file}`
  Specify a source info file. This switch is active only when project files
  are used. If the source info file is specified as a relative path, then it is
  relative to the object directory of the main project. If the source info file
  does not exist, then after the Project Manager has successfully parsed and
  processed the project files and found the sources, it creates the source info
  file. If the source info file already exists and can be read successfully,
  then the Project Manager will get all the needed information about the sources
  from the source info file and will not look for them. This reduces the time
  to process the project files, especially when looking for sources that take a
  long time. If the source info file exists but cannot be parsed successfully,
  the Project Manager will attempt to recreate it. If the Project Manager fails
  to create the source info file, a message is issued, but gnatmake does not
  fail. ``gnatmake`` "trusts" the source info file. This means that
  if the source files have changed (addition, deletion, moving to a different
  source directory), then the source info file need to be deleted and recreated.


.. index:: -a  (gnatmake)

:switch:`-a`
  Consider all files in the make process, even the GNAT internal system
  files (for example, the predefined Ada library files), as well as any
  locked files. Locked files are files whose ALI file is write-protected.
  By default,
  ``gnatmake`` does not check these files,
  because the assumption is that the GNAT internal files are properly up
  to date, and also that any write protected ALI files have been properly
  installed. Note that if there is an installation problem, such that one
  of these files is not up to date, it will be properly caught by the
  binder.
  You may have to specify this switch if you are working on GNAT
  itself. The switch ``-a`` is also useful
  in conjunction with ``-f``
  if you need to recompile an entire application,
  including run-time files, using special configuration pragmas,
  such as a ``Normalize_Scalars`` pragma.

  By default
  ``gnatmake -a`` compiles all GNAT
  internal files with
  ``gcc -c -gnatpg`` rather than ``gcc -c``.


.. index:: -b  (gnatmake)

:switch:`-b`
  Bind only. Can be combined with :switch:`-c` to do
  compilation and binding, but no link.
  Can be combined with :switch:`-l`
  to do binding and linking. When not combined with
  :switch:`-c`
  all the units in the closure of the main program must have been previously
  compiled and must be up to date. The root unit specified by ``file_name``
  may be given without extension, with the source extension or, if no GNAT
  Project File is specified, with the ALI file extension.


.. index:: -c  (gnatmake)

:switch:`-c`
  Compile only. Do not perform binding, except when :switch:`-b`
  is also specified. Do not perform linking, except if both
  :switch:`-b` and
  :switch:`-l` are also specified.
  If the root unit specified by ``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.


.. index:: -C  (gnatmake)

:switch:`-C`
  Use a temporary mapping file. A mapping file is a way to communicate
  to the compiler two mappings: from unit names to file names (without
  any directory information) and from file names to path names (with
  full directory information). A mapping file can make the compiler's
  file searches faster, especially if there are many source directories,
  or the sources are read over a slow network connection. If
  :switch:`-P` is used, a mapping file is always used, so
  :switch:`-C` is unnecessary; in this case the mapping file
  is initially populated based on the project file. If
  :switch:`-C` is used without
  :switch:`-P`,
  the mapping file is initially empty. Each invocation of the compiler
  will add any newly accessed sources to the mapping file.


.. index:: -C=  (gnatmake)

:switch:`-C={file}`
  Use a specific mapping file. The file, specified as a path name (absolute or
  relative) by this switch, should already exist, otherwise the switch is
  ineffective. The specified mapping file will be communicated to the compiler.
  This switch is not compatible with a project file
  (-P`file`) or with multiple compiling processes
  (-jnnn, when nnn is greater than 1).


.. index:: -d  (gnatmake)

:switch:`-d`
  Display progress for each source, up to date or not, as a single line:

  ::

      completed x out of y (zz%)

  If the file needs to be compiled this is displayed after the invocation of
  the compiler. These lines are displayed even in quiet output mode.


.. index:: -D  (gnatmake)

:switch:`-D {dir}`
  Put all object files and ALI file in directory ``dir``.
  If the :switch:`-D` switch is not used, all object files
  and ALI files go in the current working directory.

  This switch cannot be used when using a project file.


.. index:: -eI  (gnatmake)

:switch:`-eI{nnn}`
  Indicates that the main source is a multi-unit source and the rank of the unit
  in the source file is nnn. nnn needs to be a positive number and a valid
  index in the source. This switch cannot be used when ``gnatmake`` is
  invoked for several mains.


.. index:: -eL  (gnatmake)
.. index:: symbolic links

:switch:`-eL`
  Follow all symbolic links when processing project files.
  This should be used if your project uses symbolic links for files or
  directories, but is not needed in other cases.

  .. index:: naming scheme

  This also assumes that no directory matches the naming scheme for files (for
  instance that you do not have a directory called "sources.ads" when using the
  default GNAT naming scheme).

  When you do not have to use this switch (i.e., by default), gnatmake is able to
  save a lot of system calls (several per source file and object file), which
  can result in a significant speed up to load and manipulate a project file,
  especially when using source files from a remote system.


.. index:: -eS  (gnatmake)

:switch:`-eS`
  Output the commands for the compiler, the binder and the linker
  on standard output,
  instead of standard error.


.. index:: -f  (gnatmake)

:switch:`-f`
  Force recompilations. Recompile all sources, even though some object
  files may be up to date, but don't recompile predefined or GNAT internal
  files or locked files (files with a write-protected ALI file),
  unless the :switch:`-a` switch is also specified.


.. index:: -F  (gnatmake)

:switch:`-F`
  When using project files, if some errors or warnings are detected during
  parsing and verbose mode is not in effect (no use of switch
  -v), then error lines start with the full path name of the project
  file, rather than its simple file name.


.. index:: -g  (gnatmake)

:switch:`-g`
  Enable debugging. This switch is simply passed to the compiler and to the
  linker.


.. index:: -i  (gnatmake)

:switch:`-i`
  In normal mode, ``gnatmake`` compiles all object files and ALI files
  into the current directory. If the :switch:`-i` switch is used,
  then instead object files and ALI files that already exist are overwritten
  in place. This means that once a large project is organized into separate
  directories in the desired manner, then ``gnatmake`` will automatically
  maintain and update this organization. If no ALI files are found on the
  Ada object path (see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`),
  the new object and ALI files are created in the
  directory containing the source being compiled. If another organization
  is desired, where objects and sources are kept in different directories,
  a useful technique is to create dummy ALI files in the desired directories.
  When detecting such a dummy file, ``gnatmake`` will be forced to
  recompile the corresponding source file, and it will be put the resulting
  object and ALI files in the directory where it found the dummy file.


.. index:: -j  (gnatmake)
.. index:: Parallel make

:switch:`-j{n}`
  Use ``n`` processes to carry out the (re)compilations. On a multiprocessor
  machine compilations will occur in parallel. If ``n`` is 0, then the
  maximum number of parallel compilations is the number of core processors
  on the platform. 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). If this is problematic,
  rerun the make process with n set to 1 to get a clean list of messages.


.. index:: -k  (gnatmake)

:switch:`-k`
  Keep going. Continue as much as possible after a compilation error. To
  ease the programmer's task in case of compilation errors, the list of
  sources for which the compile fails is given when ``gnatmake``
  terminates.

  If ``gnatmake`` is invoked with several :file:`file_names` and with this
  switch, if there are compilation errors when building an executable,
  ``gnatmake`` will not attempt to build the following executables.


.. index:: -l  (gnatmake)

:switch:`-l`
  Link only. Can be combined with :switch:`-b` to binding
  and linking. Linking will not be performed if combined with
  :switch:`-c`
  but not with :switch:`-b`.
  When not combined with :switch:`-b`
  all the units in the closure of the main program must have been previously
  compiled and must be up to date, and the main program needs to have been bound.
  The root unit specified by ``file_name``
  may be given without extension, with the source extension or, if no GNAT
  Project File is specified, with the ALI file extension.


.. index:: -m  (gnatmake)

:switch:`-m`
  Specify that the minimum necessary amount of recompilations
  be performed. In this mode ``gnatmake`` ignores time
  stamp differences when the only
  modifications to a source file consist in adding/removing comments,
  empty lines, spaces or tabs. This means that if you have changed the
  comments in a source file or have simply reformatted it, using this
  switch will tell ``gnatmake`` not to recompile files that depend on it
  (provided other sources on which these files depend have undergone no
  semantic modifications). Note that the debugging information may be
  out of date with respect to the sources if the :switch:`-m` switch causes
  a compilation to be switched, so the use of this switch represents a
  trade-off between compilation time and accurate debugging information.


.. index:: Dependencies, producing list
.. index:: -M  (gnatmake)

:switch:`-M`
  Check if all objects are up to date. If they are, output the object
  dependences to :file:`stdout` in a form that can be directly exploited in
  a :file:`Makefile`. By default, each source file is prefixed with its
  (relative or absolute) directory name. This name is whatever you
  specified in the various :switch:`-aI`
  and :switch:`-I` switches. If you use
  ``gnatmake -M``  :switch:`-q`
  (see below), only the source file names,
  without relative paths, are output. If you just specify the  :switch:`-M`
  switch, dependencies of the GNAT internal system files are omitted. This
  is typically what you want. If you also specify
  the :switch:`-a` switch,
  dependencies of the GNAT internal files are also listed. Note that
  dependencies of the objects in external Ada libraries (see
  switch  :switch:`-aL{dir}` in the following list)
  are never reported.


.. index:: -n  (gnatmake)

:switch:`-n`
  Don't compile, bind, or link. Checks if all objects are up to date.
  If they are not, the full name of the first file that needs to be
  recompiled is printed.
  Repeated use of this option, followed by compiling the indicated source
  file, will eventually result in recompiling all required units.


.. index:: -o  (gnatmake)

:switch:`-o {exec_name}`
  Output executable name. The name of the final executable program will be
  ``exec_name``. If the :switch:`-o` switch is omitted the default
  name for the executable will be the name of the input file in appropriate form
  for an executable file on the host system.

  This switch cannot be used when invoking ``gnatmake`` with several
  :file:`file_names`.


.. index:: -p  (gnatmake)

:switch:`-p`
  Same as :switch:`--create-missing-dirs`

.. index:: -q  (gnatmake)

:switch:`-q`
  Quiet. When this flag is not set, the commands carried out by
  ``gnatmake`` are displayed.


.. index:: -s  (gnatmake)

:switch:`-s`
  Recompile if compiler switches have changed since last compilation.
  All compiler switches but -I and -o are taken into account in the
  following way:
  orders between different 'first letter' switches are ignored, but
  orders between same switches are taken into account. For example,
  :switch:`-O -O2` is different than :switch:`-O2 -O`, but :switch:`-g -O`
  is equivalent to :switch:`-O -g`.

  This switch is recommended when Integrated Preprocessing is used.


.. index:: -u  (gnatmake)

:switch:`-u`
  Unique. Recompile at most the main files. It implies -c. Combined with
  -f, it is equivalent to calling the compiler directly. Note that using
  -u with a project file and no main has a special meaning.

.. --Comment
  (See :ref:`Project_Files_and_Main_Subprograms`.)


.. index:: -U  (gnatmake)

:switch:`-U`
  When used without a project file or with one or several mains on the command
  line, is equivalent to -u. When used with a project file and no main
  on the command line, all sources of all project files are checked and compiled
  if not up to date, and libraries are rebuilt, if necessary.


.. index:: -v  (gnatmake)

:switch:`-v`
  Verbose. Display the reason for all recompilations ``gnatmake``
  decides are necessary, with the highest verbosity level.


.. index:: -vl  (gnatmake)

:switch:`-vl`
  Verbosity level Low. Display fewer lines than in verbosity Medium.


.. index:: -vm  (gnatmake)

:switch:`-vm`
  Verbosity level Medium. Potentially display fewer lines than in verbosity High.


.. index:: -vm  (gnatmake)

:switch:`-vh`
  Verbosity level High. Equivalent to -v.


:switch:`-vP{x}`
  Indicate the verbosity of the parsing of GNAT project files.
  See :ref:`Switches_Related_to_Project_Files`.


.. index:: -x  (gnatmake)

:switch:`-x`
  Indicate that sources that are not part of any Project File may be compiled.
  Normally, when using Project Files, only sources that are part of a Project
  File may be compile. When this switch is used, a source outside of all Project
  Files may be compiled. The ALI file and the object file will be put in the
  object directory of the main Project. The compilation switches used will only
  be those specified on the command line. Even when
  :switch:`-x` is used, mains specified on the
  command line need to be sources of a project file.


:switch:`-X{name}={value}`
  Indicate that external variable ``name`` has the value ``value``.
  The Project Manager will use this value for occurrences of
  ``external(name)`` when parsing the project file.
  :ref:`Switches_Related_to_Project_Files`.


.. index:: -z  (gnatmake)

:switch:`-z`
  No main subprogram. Bind and link the program even if the unit name
  given on the command line is a package name. The resulting executable
  will execute the elaboration routines of the package and its closure,
  then the finalization routines.


.. rubric:: GCC switches

Any uppercase or multi-character switch that is not a ``gnatmake`` switch
is passed to ``gcc`` (e.g., :switch:`-O`, :switch:`-gnato,` etc.)


.. rubric:: Source and library search path switches

.. index:: -aI  (gnatmake)

:switch:`-aI{dir}`
  When looking for source files also look in directory ``dir``.
  The order in which source files search is undertaken is
  described in :ref:`Search_Paths_and_the_Run-Time_Library_RTL`.


.. index:: -aL  (gnatmake)

:switch:`-aL{dir}`
  Consider ``dir`` as being an externally provided Ada library.
  Instructs ``gnatmake`` to skip compilation units whose :file:`.ALI`
  files have been located in directory ``dir``. This allows you to have
  missing bodies for the units in ``dir`` and to ignore out of date bodies
  for the same units. You still need to specify
  the location of the specs for these units by using the switches
  :switch:`-aI{dir}`  or :switch:`-I{dir}`.
  Note: this switch is provided for compatibility with previous versions
  of ``gnatmake``. The easier method of causing standard libraries
  to be excluded from consideration is to write-protect the corresponding
  ALI files.


.. index:: -aO  (gnatmake)

:switch:`-aO{dir}`
  When searching for library and object files, look in directory
  ``dir``. The order in which library files are searched is described in
  :ref:`Search_Paths_for_gnatbind`.


.. index:: Search paths, for gnatmake
.. index:: -A  (gnatmake)

:switch:`-A{dir}`
  Equivalent to :switch:`-aL{dir}` :switch:`-aI{dir}`.


  .. index:: -I  (gnatmake)

:switch:`-I{dir}`
  Equivalent to :switch:`-aO{dir} -aI{dir}`.


.. index:: -I-  (gnatmake)
.. index:: Source files, suppressing search

:switch:`-I-`
  Do not look for source files in the directory containing the source
  file named in the command line.
  Do not look for ALI or object files in the directory
  where ``gnatmake`` was invoked.


.. index:: -L  (gnatmake)
.. index:: Linker libraries

:switch:`-L{dir}`
  Add directory ``dir`` to the list of directories in which the linker
  will search for libraries. This is equivalent to
  :switch:`-largs` :switch:`-L{dir}`.
  Furthermore, under Windows, the sources pointed to by the libraries path
  set in the registry are not searched for.


.. index:: -nostdinc  (gnatmake)

:switch:`-nostdinc`
  Do not look for source files in the system default directory.


.. index:: -nostdlib  (gnatmake)

:switch:`-nostdlib`
  Do not look for library files in the system default directory.


.. index:: --RTS  (gnatmake)

:switch:`--RTS={rts-path}`
  Specifies the default location of the run-time library. GNAT looks for the
  run-time
  in the following directories, and stops as soon as a valid run-time is found
  (:file:`adainclude` or :file:`ada_source_path`, and :file:`adalib` or
  :file:`ada_object_path` present):

  * *<current directory>/$rts_path*

  * *<default-search-dir>/$rts_path*

  * *<default-search-dir>/rts-$rts_path*

  * The selected path is handled like a normal RTS path.


.. _Mode_Switches_for_gnatmake:

Mode Switches for ``gnatmake``
------------------------------

The mode switches (referred to as ``mode_switches``) allow the
inclusion of switches that are to be passed to the compiler itself, the
binder or the linker. The effect of a mode switch is to cause all
subsequent switches up to the end of the switch list, or up to the next
mode switch, to be interpreted as switches to be passed on to the
designated component of GNAT.

.. index:: -cargs  (gnatmake)

:switch:`-cargs {switches}`
  Compiler switches. Here ``switches`` is a list of switches
  that are valid switches for ``gcc``. They will be passed on to
  all compile steps performed by ``gnatmake``.


.. index:: -bargs  (gnatmake)

:switch:`-bargs {switches}`
  Binder switches. Here ``switches`` is a list of switches
  that are valid switches for ``gnatbind``. They will be passed on to
  all bind steps performed by ``gnatmake``.


.. index:: -largs  (gnatmake)

:switch:`-largs {switches}`
  Linker switches. Here ``switches`` is a list of switches
  that are valid switches for ``gnatlink``. They will be passed on to
  all link steps performed by ``gnatmake``.


.. index:: -margs  (gnatmake)

:switch:`-margs {switches}`
  Make switches. The switches are directly interpreted by ``gnatmake``,
  regardless of any previous occurrence of :switch:`-cargs`, :switch:`-bargs`
  or :switch:`-largs`.


.. _Notes_on_the_Command_Line:

Notes on the Command Line
-------------------------

This section contains some additional useful notes on the operation
of the ``gnatmake`` command.

.. index:: Recompilation (by gnatmake)

* If ``gnatmake`` finds no ALI files, it recompiles the main program
  and all other units required by the main program.
  This means that ``gnatmake``
  can be used for the initial compile, as well as during subsequent steps of
  the development cycle.

* If you enter ``gnatmake foo.adb``, where ``foo``
  is a subunit or body of a generic unit, ``gnatmake`` recompiles
  :file:`foo.adb` (because it finds no ALI) and stops, issuing a
  warning.

* In ``gnatmake`` the switch :switch:`-I`
  is used to specify both source and
  library file paths. Use :switch:`-aI`
  instead if you just want to specify
  source paths only and :switch:`-aO`
  if you want to specify library paths
  only.

* ``gnatmake`` will ignore any files whose ALI file is write-protected.
  This may conveniently be used to exclude standard libraries from
  consideration and in particular it means that the use of the
  :switch:`-f` switch will not recompile these files
  unless :switch:`-a` is also specified.

* ``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 files 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:

  .. code-block:: sh

      $ gnatmake -aI`include-dir`  -aL`obj-dir`  main

* Using ``gnatmake`` along with the :switch:`-m (minimal recompilation)`
  switch provides a mechanism for avoiding unnecessary recompilations. Using
  this switch,
  you can update the comments/format of your
  source files without having to recompile everything. Note, however, that
  adding or deleting lines in a source files may render its debugging
  info obsolete. If the file in question is a spec, the impact is rather
  limited, as that debugging info will only be useful during the
  elaboration phase of your program. For bodies the impact can be more
  significant. In all events, your debugger will warn you if a source file
  is more recent than the corresponding object, and alert you to the fact
  that the debugging information may be out of date.


.. _How_gnatmake_Works:

How ``gnatmake`` Works
----------------------

Generally ``gnatmake`` automatically performs all necessary
recompilations and you don't need to worry about how it works. However,
it may be useful to have some basic understanding of the ``gnatmake``
approach and in particular to understand how it uses the results of
previous compilations without incorrectly depending on them.

First a definition: an object file is considered *up to date* if the
corresponding ALI file exists and if all the source files listed in the
dependency section of this ALI file have time stamps matching those in
the ALI file. This means that neither the source file itself nor any
files that it depends on have been modified, and hence there is no need
to recompile this file.

``gnatmake`` works by first checking if the specified main unit is up
to date. If so, no compilations are required for the main unit. If not,
``gnatmake`` compiles the main program to build a new ALI file that
reflects the latest sources. Then the ALI file of the main unit is
examined to find all the source files on which the main program depends,
and ``gnatmake`` recursively applies the above procedure on all these
files.

This process ensures that ``gnatmake`` only trusts the dependencies
in an existing ALI file if they are known to be correct. Otherwise it
always recompiles to determine a new, guaranteed accurate set of
dependencies. As a result the program is compiled 'upside down' from what may
be more familiar as the required order of compilation in some other Ada
systems. In particular, clients are compiled before the units on which
they depend. The ability of GNAT to compile in any order is critical in
allowing an order of compilation to be chosen that guarantees that
``gnatmake`` will recompute a correct set of new dependencies if
necessary.

When invoking ``gnatmake`` with several ``file_names``, if a unit is
imported by several of the executables, it will be recompiled at most once.

Note: when using non-standard naming conventions
(:ref:`Using_Other_File_Names`), changing through a configuration pragmas
file the version of a source and invoking ``gnatmake`` to recompile may
have no effect, if the previous version of the source is still accessible
by ``gnatmake``. It may be necessary to use the switch
-f.


.. _Examples_of_gnatmake_Usage:

Examples of ``gnatmake`` Usage
------------------------------

``gnatmake hello.adb``
  Compile all files necessary to bind and link the main program
  :file:`hello.adb` (containing unit ``Hello``) and bind and link the
  resulting object files to generate an executable file :file:`hello`.

``gnatmake main1 main2 main3``
  Compile all files necessary to bind and link the main programs
  :file:`main1.adb` (containing unit ``Main1``), :file:`main2.adb`
  (containing unit ``Main2``) and :file:`main3.adb`
  (containing unit ``Main3``) and bind and link the resulting object files
  to generate three executable files :file:`main1`,
  :file:`main2`  and :file:`main3`.

``gnatmake -q Main_Unit -cargs -O2 -bargs -l``
  Compile all files necessary to bind and link the main program unit
  ``Main_Unit`` (from file :file:`main_unit.adb`). All compilations will
  be done with optimization level 2 and the order of elaboration will be
  listed by the binder. ``gnatmake`` will operate in quiet mode, not
  displaying commands it is executing.


.. _Compiling_with_gcc:

Compiling with ``gcc``
======================

This section discusses how to compile Ada programs using the ``gcc``
command. It also describes the set of switches
that can be used to control the behavior of the compiler.

.. _Compiling_Programs:

Compiling Programs
------------------

The first step in creating an executable program is to compile the units
of the program using the ``gcc`` command. You must compile the
following files:

* the body file (:file:`.adb`) for a library level subprogram or generic
  subprogram

* the spec file (:file:`.ads`) for a library level package or generic
  package that has no body

* the body file (:file:`.adb`) for a library level package
  or generic package that has a body

You need *not* compile the following files

* the spec of a library unit which has a body

* subunits

because they are compiled as part of compiling related units. GNAT compiles
package specs
when the corresponding body is compiled, and subunits when the parent is
compiled.

.. index:: cannot generate code

If you attempt to compile any of these files, you will get one of the
following error messages (where :file:`fff` is the name of the file you
compiled):

.. code-block:: text

   cannot generate code for file fff (package spec)

   cannot generate code for file fff (missing subunits)

   cannot generate code for file fff (subprogram spec)

   cannot generate code for file fff (subunit)


As indicated by the above error messages, if you want to submit
one of these files to the compiler to check for correct semantics
without generating code, then use the :switch:`-gnatc` switch.

The basic command for compiling a file containing an Ada unit is:

.. code-block:: sh

  $ gcc -c [switches] <file name>

where ``file name`` is the name of the Ada file (usually
having an extension :file:`.ads` for a spec or :file:`.adb` for a body).
You specify the
:switch:`-c` switch to tell ``gcc`` to compile, but not link, the file.
The result of a successful compilation is an object file, which has the
same name as the source file but an extension of :file:`.o` and an Ada
Library Information (ALI) file, which also has the same name as the
source file, but with :file:`.ali` as the extension. GNAT creates these
two output files in the current directory, but you may specify a source
file in any directory using an absolute or relative path specification
containing the directory information.

.. index::  gnat1

``gcc`` is actually a driver program that looks at the extensions of
the file arguments and loads the appropriate compiler. For example, the
GNU C compiler is :file:`cc1`, and the Ada compiler is :file:`gnat1`.
These programs are in directories known to the driver program (in some
configurations via environment variables you set), but need not be in
your path. The ``gcc`` driver also calls the assembler and any other
utilities needed to complete the generation of the required object
files.

It is possible to supply several file names on the same ``gcc``
command. This causes ``gcc`` to call the appropriate compiler for
each file. For example, the following command lists two separate
files to be compiled:

.. code-block:: sh

  $ gcc -c x.adb y.adb


calls ``gnat1`` (the Ada compiler) twice to compile :file:`x.adb` and
:file:`y.adb`.
The compiler generates two object files :file:`x.o` and :file:`y.o`
and the two ALI files :file:`x.ali` and :file:`y.ali`.

Any switches apply to all the files listed, see :ref:`Switches_for_gcc` for a
list of available ``gcc`` switches.

.. _Search_Paths_and_the_Run-Time_Library_RTL:

Search Paths and the Run-Time Library (RTL)
-------------------------------------------

With the GNAT source-based library system, the compiler must be able to
find source files for units that are needed by the unit being compiled.
Search paths are used to guide this process.

The compiler compiles one source file whose name must be given
explicitly on the command line. In other words, no searching is done
for this file. To find all other source files that are needed (the most
common being the specs of units), the compiler examines the following
directories, in the following order:

* The directory containing the source file of the main unit being compiled
  (the file name on the command line).

* Each directory named by an :switch:`-I` switch given on the ``gcc``
  command line, in the order given.

  .. index:: ADA_PRJ_INCLUDE_FILE

* Each of the directories listed in the text file whose name is given
  by the :envvar:`ADA_PRJ_INCLUDE_FILE` environment variable.
  :envvar:`ADA_PRJ_INCLUDE_FILE` is normally set by gnatmake or by the gnat
  driver when project files are used. It should not normally be set
  by other means.

  .. index:: ADA_INCLUDE_PATH

* Each of the directories listed in the value of the
  :envvar:`ADA_INCLUDE_PATH` environment variable.
  Construct this value
  exactly as the :envvar:`PATH` environment variable: a list of directory
  names separated by colons (semicolons when working with the NT version).

* The content of the :file:`ada_source_path` file which is part of the GNAT
  installation tree and is used to store standard libraries such as the
  GNAT Run Time Library (RTL) source files.
  See also :ref:`Installing_a_library`.

Specifying the switch :switch:`-I-`
inhibits the use of the directory
containing the source file named in the command line. You can still
have this directory on your search path, but in this case it must be
explicitly requested with a :switch:`-I` switch.

Specifying the switch :switch:`-nostdinc`
inhibits the search of the default location for the GNAT Run Time
Library (RTL) source files.

The compiler outputs its object files and ALI files in the current
working directory.
Caution: The object file can be redirected with the :switch:`-o` switch;
however, ``gcc`` and ``gnat1`` have not been coordinated on this
so the :file:`ALI` file will not go to the right place. Therefore, you should
avoid using the :switch:`-o` switch.

.. index:: System.IO

The packages ``Ada``, ``System``, and ``Interfaces`` and their
children make up the GNAT RTL, 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. In a normal installation, you need not specify these directory
names when compiling or binding. Either the environment variables or
the built-in defaults cause these files to be found.

In addition to the language-defined hierarchies (``System``, ``Ada`` and
``Interfaces``), the GNAT distribution provides a fourth hierarchy,
consisting of child units of ``GNAT``. This is a collection of generally
useful types, subprograms, etc. See the :title:`GNAT_Reference_Manual`
for further details.

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

.. _Order_of_Compilation_Issues:

Order of Compilation Issues
---------------------------

If, in our earlier example, there was a spec for the ``hello``
procedure, it would be contained in the file :file:`hello.ads`; yet this
file would not have to be explicitly compiled. This is the result of the
model we chose to implement library management. Some of the consequences
of this model are as follows:

* There is no point in compiling specs (except for package
  specs with no bodies) because these are compiled as needed by clients. If
  you attempt a useless compilation, you will receive an error message.
  It is also useless to compile subunits because they are compiled as needed
  by the parent.

* There are no order of compilation requirements: performing a
  compilation never obsoletes anything. The only way you can obsolete
  something and require recompilations is to modify one of the
  source files on which it depends.

* There is no library as such, apart from the ALI files
  (:ref:`The_Ada_Library_Information_Files`, for information on the format
  of these files). For now we find it convenient to create separate ALI files,
  but eventually the information therein may be incorporated into the object
  file directly.

* When you compile a unit, the source files for the specs of all units
  that it |withs|, all its subunits, and the bodies of any generics it
  instantiates must be available (reachable by the search-paths mechanism
  described above), or you will receive a fatal error message.

.. _Examples:

Examples
--------

The following are some typical Ada compilation command line examples:

.. code-block:: sh

    $ gcc -c xyz.adb

Compile body in file :file:`xyz.adb` with all default options.

.. code-block:: sh

    $ gcc -c -O2 -gnata xyz-def.adb

Compile the child unit package in file :file:`xyz-def.adb` with extensive
optimizations, and pragma ``Assert``/``Debug`` statements
enabled.

.. code-block:: sh

    $ gcc -c -gnatc abc-def.adb

Compile the subunit in file :file:`abc-def.adb` in semantic-checking-only
mode.


.. _Switches_for_gcc:

Compiler Switches
=================

The ``gcc`` command accepts switches that control the
compilation process. These switches are fully described in this section:
first an alphabetical listing of all switches with a brief description,
and then functionally grouped sets of switches with more detailed
information.

More switches exist for GCC than those documented here, especially
for specific targets. However, their use is not recommended as
they may change code generation in ways that are incompatible with
the Ada run-time library, or can cause inconsistencies between
compilation units.

.. _Alphabetical_List_of_All_Switches:

Alphabetical List of All Switches
---------------------------------

.. index:: -b  (gcc)

:switch:`-b {target}`
  Compile your program to run on ``target``, which is the name of a
  system configuration. You must have a GNAT cross-compiler built if
  ``target`` is not the same as your host system.


.. index:: -B  (gcc)

:switch:`-B{dir}`
  Load compiler executables (for example, ``gnat1``, the Ada compiler)
  from ``dir`` instead of the default location. Only use this switch
  when multiple versions of the GNAT compiler are available.
  See the "Options for Directory Search" section in the
  :title:`Using the GNU Compiler Collection (GCC)` manual for further details.
  You would normally use the :switch:`-b` or :switch:`-V` switch instead.

.. index:: -c  (gcc)

:switch:`-c`
  Compile. Always use this switch when compiling Ada programs.

  Note: for some other languages when using ``gcc``, notably in
  the case of C and C++, it is possible to use
  use ``gcc`` without a :switch:`-c` switch to
  compile and link in one step. In the case of GNAT, you
  cannot use this approach, because the binder must be run
  and ``gcc`` cannot be used to run the GNAT binder.


.. index:: -fcallgraph-info  (gcc)

:switch:`-fcallgraph-info[=su,da]`
  Makes the compiler output callgraph information for the program, on a
  per-file basis. The information is generated in the VCG format.  It can
  be decorated with additional, per-node and/or per-edge information, if a
  list of comma-separated markers is additionally specified. When the
  ``su`` marker is specified, the callgraph is decorated with stack usage
  information; it is equivalent to :switch:`-fstack-usage`. When the ``da``
  marker is specified, the callgraph is decorated with information about
  dynamically allocated objects.

.. index:: -fdiagnostics-format   (gcc)

:switch:`-fdiagnostics-format=json`
  Makes GNAT emit warning and error messages as JSON. Inhibits printing of
  text warning and errors messages except if :switch:`-gnatv` or
  :switch:`-gnatl` are present. Uses absolute file paths when used along
  :switch:`-gnatef`.


.. index:: -fdump-scos  (gcc)

:switch:`-fdump-scos`
  Generates SCO (Source Coverage Obligation) information in the ALI file.
  This information is used by advanced coverage tools. See unit :file:`SCOs`
  in the compiler sources for details in files :file:`scos.ads` and
  :file:`scos.adb`.


.. index:: -fgnat-encodings  (gcc)

:switch:`-fgnat-encodings=[all|gdb|minimal]`
  This switch controls the balance between GNAT encodings and standard DWARF
  emitted in the debug information.


.. index:: -flto  (gcc)

:switch:`-flto[={n}]`
  Enables Link Time Optimization. This switch must be used in conjunction
  with the :switch:`-Ox` switches (but not with the :switch:`-gnatn` switch
  since it is a full replacement for the latter) and instructs the compiler
  to defer most optimizations until the link stage. The advantage of this
  approach is that the compiler can do a whole-program analysis and choose
  the best interprocedural optimization strategy based on a complete view
  of the program, instead of a fragmentary view with the usual approach.
  This can also speed up the compilation of big programs and reduce the
  size of the executable, compared with a traditional per-unit compilation
  with inlining across units enabled by the :switch:`-gnatn` switch.
  The drawback of this approach is that it may require more memory and that
  the debugging information generated by ``-g`` with it might be hardly usable.
  The switch, as well as the accompanying :switch:`-Ox` switches, must be
  specified both for the compilation and the link phases.
  If the ``n`` parameter is specified, the optimization and final code
  generation at link time are executed using ``n`` parallel jobs by
  means of an installed ``make`` program.


.. index:: -fno-inline  (gcc)

:switch:`-fno-inline`
  Suppresses all inlining, unless requested with pragma ``Inline_Always``. The
  effect is enforced regardless of other optimization or inlining switches.
  Note that inlining can also be suppressed on a finer-grained basis with
  pragma ``No_Inline``.


.. index:: -fno-inline-functions  (gcc)

:switch:`-fno-inline-functions`
  Suppresses automatic inlining of subprograms, which is enabled
  if :switch:`-O3` is used.


.. index:: -fno-inline-small-functions  (gcc)

:switch:`-fno-inline-small-functions`
  Suppresses automatic inlining of small subprograms, which is enabled
  if :switch:`-O2` is used.


.. index:: -fno-inline-functions-called-once  (gcc)

:switch:`-fno-inline-functions-called-once`
  Suppresses inlining of subprograms local to the unit and called once
  from within it, which is enabled if :switch:`-O1` is used.


.. index:: -fno-ivopts  (gcc)

:switch:`-fno-ivopts`
  Suppresses high-level loop induction variable optimizations, which are
  enabled if :switch:`-O1` is used. These optimizations are generally
  profitable but, for some specific cases of loops with numerous uses
  of the iteration variable that follow a common pattern, they may end
  up destroying the regularity that could be exploited at a lower level
  and thus producing inferior code.


.. index:: -fno-strict-aliasing  (gcc)

:switch:`-fno-strict-aliasing`
  Causes the compiler to avoid assumptions regarding non-aliasing
  of objects of different types. See
  :ref:`Optimization_and_Strict_Aliasing` for details.


.. index:: -fno-strict-overflow  (gcc)

:switch:`-fno-strict-overflow`
  Causes the compiler to avoid assumptions regarding the rules of signed
  integer overflow. These rules specify that signed integer overflow will
  result in a Constraint_Error exception at run time and are enforced in
  default mode by the compiler, so this switch should not be necessary in
  normal operating mode. It might be useful in conjunction with :switch:`-gnato0`
  for very peculiar cases of low-level programming.


.. index:: -fstack-check  (gcc)

:switch:`-fstack-check`
  Activates stack checking.
  See :ref:`Stack_Overflow_Checking` for details.


.. index:: -fstack-usage  (gcc)

:switch:`-fstack-usage`
  Makes the compiler output stack usage information for the program, on a
  per-subprogram basis. See :ref:`Static_Stack_Usage_Analysis` for details.


.. index:: -g  (gcc)

:switch:`-g`
  Generate debugging information. This information is stored in the object
  file and copied from there to the final executable file by the linker,
  where it can be read by the debugger. You must use the
  :switch:`-g` switch if you plan on using the debugger.


.. index:: -gnat05  (gcc)

:switch:`-gnat05`
  Allow full Ada 2005 features.


.. index:: -gnat12  (gcc)

:switch:`-gnat12`
  Allow full Ada 2012 features.

.. index:: -gnat83  (gcc)

.. index:: -gnat2005  (gcc)

:switch:`-gnat2005`
  Allow full Ada 2005 features (same as :switch:`-gnat05`)


.. index:: -gnat2012  (gcc)

:switch:`-gnat2012`
  Allow full Ada 2012 features (same as :switch:`-gnat12`)


.. index:: -gnat2022  (gcc)

:switch:`-gnat2022`
  Allow full Ada 2022 features


:switch:`-gnat83`
  Enforce Ada 83 restrictions.


.. index:: -gnat95  (gcc)

:switch:`-gnat95`
  Enforce Ada 95 restrictions.

  Note: for compatibility with some Ada 95 compilers which support only
  the ``overriding`` keyword of Ada 2005, the :switch:`-gnatd.D` switch can
  be used along with :switch:`-gnat95` to achieve a similar effect with GNAT.

  :switch:`-gnatd.D` instructs GNAT to consider ``overriding`` as a keyword
  and handle its associated semantic checks, even in Ada 95 mode.


.. index:: -gnata  (gcc)

:switch:`-gnata`
  Assertions enabled. ``Pragma Assert`` and ``pragma Debug`` to be
  activated. Note that these pragmas can also be controlled using the
  configuration pragmas ``Assertion_Policy`` and ``Debug_Policy``.
  It also activates pragmas ``Check``, ``Precondition``, and
  ``Postcondition``. Note that these pragmas can also be controlled
  using the configuration pragma ``Check_Policy``. In Ada 2012, it
  also activates all assertions defined in the RM as aspects: preconditions,
  postconditions, type invariants and (sub)type predicates. In all Ada modes,
  corresponding pragmas for type invariants and (sub)type predicates are
  also activated. The default is that all these assertions are disabled,
  and have no effect, other than being checked for syntactic validity, and
  in the case of subtype predicates, constructions such as membership tests
  still test predicates even if assertions are turned off.


.. index:: -gnatA  (gcc)

:switch:`-gnatA`
  Avoid processing :file:`gnat.adc`. If a :file:`gnat.adc` file is present,
  it will be ignored.


.. index:: -gnatb  (gcc)

:switch:`-gnatb`
  Generate brief messages to :file:`stderr` even if verbose mode set.


.. index:: -gnatB  (gcc)

:switch:`-gnatB`
  Assume no invalid (bad) values except for 'Valid attribute use
  (:ref:`Validity_Checking`).


.. index:: -gnatc  (gcc)

:switch:`-gnatc`
  Check syntax and semantics only (no code generation attempted). When the
  compiler is invoked by ``gnatmake``, if the switch :switch:`-gnatc` is
  only given to the compiler (after :switch:`-cargs` or in package Compiler of
  the project file), ``gnatmake`` will fail because it will not find the
  object file after compilation. If ``gnatmake`` is called with
  :switch:`-gnatc` as a builder switch (before :switch:`-cargs` or in package
  Builder of the project file) then ``gnatmake`` will not fail because
  it will not look for the object files after compilation, and it will not try
  to build and link.


.. index:: -gnatC  (gcc)

:switch:`-gnatC`
  Generate CodePeer intermediate format (no code generation attempted).
  This switch will generate an intermediate representation suitable for
  use by CodePeer (:file:`.scil` files). This switch is not compatible with
  code generation (it will, among other things, disable some switches such
  as ``-gnatn``, and enable others such as ``-gnata``).


.. index:: -gnatd  (gcc)

:switch:`-gnatd`
  Specify debug options for the compiler. The string of characters after
  the :switch:`-gnatd` specifies the specific debug options. The possible
  characters are 0-9, a-z, A-Z, optionally preceded by a dot or underscore.
  See compiler source file :file:`debug.adb` for details of the implemented
  debug options. Certain debug options are relevant to application
  programmers, and these are documented at appropriate points in this
  user's guide.


.. index:: -gnatD[nn]  (gcc)

:switch:`-gnatD`
  Create expanded source files for source level debugging. This switch
  also suppresses generation of cross-reference information
  (see :switch:`-gnatx`). Note that this switch is not allowed if a previous
  ``-gnatR`` switch has been given, since these two switches are not compatible.


.. index:: -gnateA  (gcc)

:switch:`-gnateA`
  Check that the actual parameters of a subprogram call are not aliases of one
  another. To qualify as aliasing, their memory locations must be identical or
  overlapping, at least one of the corresponding formal parameters must be of
  mode OUT or IN OUT, and at least one of the corresponding formal parameters
  must have its parameter passing mechanism not specified.


  .. code-block:: ada

      type Rec_Typ is record
         Data : Integer := 0;
      end record;

      function Self (Val : Rec_Typ) return Rec_Typ is
      begin
         return Val;
      end Self;

      procedure Detect_Aliasing (Val_1 : in out Rec_Typ; Val_2 : Rec_Typ) is
      begin
         null;
      end Detect_Aliasing;

      Obj : Rec_Typ;

      Detect_Aliasing (Obj, Obj);
      Detect_Aliasing (Obj, Self (Obj));


  In the example above, the first call to ``Detect_Aliasing`` fails with a
  ``Program_Error`` at run time because the actuals for ``Val_1`` and
  ``Val_2`` denote the same object. The second call executes without raising
  an exception because ``Self(Obj)`` produces an anonymous object which does
  not share the memory location of ``Obj``.

.. index:: -gnateb  (gcc)

:switch:`-gnateb`
  Store configuration files by their basename in ALI files. This switch is
  used for instance by gprbuild for distributed builds in order to prevent
  issues where machine-specific absolute paths could end up being stored in
  ALI files.

.. index:: -gnatec  (gcc)

:switch:`-gnatec={path}`
  Specify a configuration pragma file
  (the equal sign is optional)
  (:ref:`The_Configuration_Pragmas_Files`).


.. index:: -gnateC  (gcc)

:switch:`-gnateC`
  Generate CodePeer messages in a compiler-like format. This switch is only
  effective if :switch:`-gnatcC` is also specified and requires an installation
  of CodePeer.


.. index:: -gnated  (gcc)

:switch:`-gnated`
  Disable atomic synchronization


.. index:: -gnateD  (gcc)

:switch:`-gnateDsymbol[={value}]`
  Defines a symbol, associated with ``value``, for preprocessing.
  (:ref:`Integrated_Preprocessing`).


.. index:: -gnateE  (gcc)

:switch:`-gnateE`
  Generate extra information in exception messages. In particular, display
  extra column information and the value and range associated with index and
  range check failures, and extra column information for access checks.
  In cases where the compiler is able to determine at compile time that
  a check will fail, it gives a warning, and the extra information is not
  produced at run time.


.. index:: -gnatef  (gcc)

:switch:`-gnatef`
  Display full source path name in brief error messages and absolute paths in
  :switch:`-fdiagnostics-format=json`'s output.


.. index:: -gnateF  (gcc)

:switch:`-gnateF`
  Check for overflow on all floating-point operations, including those
  for unconstrained predefined types. See description of pragma
  ``Check_Float_Overflow`` in GNAT RM.


.. index:: -gnateg  (gcc)

:switch:`-gnateg`
:switch:`-gnatceg`

  The :switch:`-gnatc` switch must always be specified before this switch, e.g.
  :switch:`-gnatceg`. Generate a C header from the Ada input file. See
  :ref:`Generating_C_Headers_for_Ada_Specifications` for more
  information.


.. index:: -gnateG  (gcc)

:switch:`-gnateG[bce]`
  Save result of preprocessing in a text file. An optional character (b, c,
  or e) can be appended to indicate that filtered lines are to be replaced by
  blank lines, comment lines that include the filtered line, or empty comment
  lines ("--!"), respectively. The default is to replace filtered lines with
  blank lines.


.. index:: -gnateH  (gcc)

:switch:`-gnateH`
  Set the threshold from which the RM 13.5.1(13.3/2) clause applies to 64.
  This is useful only on 64-bit platforms where this threshold is 128, but
  used to be 64 in earlier versions of the compiler.


.. index:: -gnatei  (gcc)

:switch:`-gnatei{nnn}`
  Set maximum number of instantiations during compilation of a single unit to
  ``nnn``. This may be useful in increasing the default maximum of 8000 for
  the rare case when a single unit legitimately exceeds this limit.


.. index:: -gnateI  (gcc)

:switch:`-gnateI{nnn}`
  Indicates that the source is a multi-unit source and that the index of the
  unit to compile is ``nnn``. ``nnn`` needs to be a positive number and need
  to be a valid index in the multi-unit source.


.. index:: -gnatel  (gcc)

:switch:`-gnatel`
  This switch can be used with the static elaboration model to issue info
  messages showing
  where implicit ``pragma Elaborate`` and ``pragma Elaborate_All``
  are generated. This is useful in diagnosing elaboration circularities
  caused by these implicit pragmas when using the static elaboration
  model. See the section in this guide on elaboration checking for
  further details. These messages are not generated by default, and are
  intended only for temporary use when debugging circularity problems.


.. index:: -gnatel  (gcc)

:switch:`-gnateL`
  This switch turns off the info messages about implicit elaboration pragmas.


.. index:: -gnatem  (gcc)

:switch:`-gnatem={path}`
  Specify a mapping file
  (the equal sign is optional)
  (:ref:`Units_to_Sources_Mapping_Files`).


.. index:: -gnatep  (gcc)

:switch:`-gnatep={file}`
  Specify a preprocessing data file
  (the equal sign is optional)
  (:ref:`Integrated_Preprocessing`).


.. index:: -gnateP  (gcc)

:switch:`-gnateP`
  Turn categorization dependency errors into warnings.
  Ada requires that units that WITH one another have compatible categories, for
  example a Pure unit cannot WITH a Preelaborate unit. If this switch is used,
  these errors become warnings (which can be ignored, or suppressed in the usual
  manner). This can be useful in some specialized circumstances such as the
  temporary use of special test software.


.. index:: -gnateS  (gcc)

:switch:`-gnateS`
  Synonym of :switch:`-fdump-scos`, kept for backwards compatibility.


.. index:: -gnatet=file  (gcc)

:switch:`-gnatet={path}`
  Generate target dependent information. The format of the output file is
  described in the section about switch :switch:`-gnateT`.


.. index:: -gnateT  (gcc)

:switch:`-gnateT={path}`
  Read target dependent information, such as endianness or sizes and alignments
  of base type. If this switch is passed, the default target dependent
  information of the compiler is replaced by the one read from the input file.
  This is used by tools other than the compiler, e.g. to do
  semantic analysis of programs that will run on some other target than
  the machine on which the tool is run.

  The following target dependent values should be defined,
  where ``Nat`` denotes a natural integer value, ``Pos`` denotes a
  positive integer value, and fields marked with a question mark are
  boolean fields, where a value of 0 is False, and a value of 1 is True:


  ::

    Bits_BE                    : Nat; -- Bits stored big-endian?
    Bits_Per_Unit              : Pos; -- Bits in a storage unit
    Bits_Per_Word              : Pos; -- Bits in a word
    Bytes_BE                   : Nat; -- Bytes stored big-endian?
    Char_Size                  : Pos; -- Standard.Character'Size
    Double_Float_Alignment     : Nat; -- Alignment of double float
    Double_Scalar_Alignment    : Nat; -- Alignment of double length scalar
    Double_Size                : Pos; -- Standard.Long_Float'Size
    Float_Size                 : Pos; -- Standard.Float'Size
    Float_Words_BE             : Nat; -- Float words stored big-endian?
    Int_Size                   : Pos; -- Standard.Integer'Size
    Long_Double_Size           : Pos; -- Standard.Long_Long_Float'Size
    Long_Long_Long_Size        : Pos; -- Standard.Long_Long_Long_Integer'Size
    Long_Long_Size             : Pos; -- Standard.Long_Long_Integer'Size
    Long_Size                  : Pos; -- Standard.Long_Integer'Size
    Maximum_Alignment          : Pos; -- Maximum permitted alignment
    Max_Unaligned_Field        : Pos; -- Maximum size for unaligned bit field
    Pointer_Size               : Pos; -- System.Address'Size
    Short_Enums                : Nat; -- Foreign enums use short size?
    Short_Size                 : Pos; -- Standard.Short_Integer'Size
    Strict_Alignment           : Nat; -- Strict alignment?
    System_Allocator_Alignment : Nat; -- Alignment for malloc calls
    Wchar_T_Size               : Pos; -- Interfaces.C.wchar_t'Size
    Words_BE                   : Nat; -- Words stored big-endian?

  ``Bits_Per_Unit`` is the number of bits in a storage unit, the equivalent of
  GCC macro ``BITS_PER_UNIT`` documented as follows: `Define this macro to be
  the number of bits in an addressable storage unit (byte); normally 8.`

  ``Bits_Per_Word`` is the number of bits in a machine word, the equivalent of
  GCC macro ``BITS_PER_WORD`` documented as follows: `Number of bits in a word;
  normally 32.`

  ``Double_Float_Alignment``, if not zero, is the maximum alignment that the
  compiler can choose by default for a 64-bit floating-point type or object.

  ``Double_Scalar_Alignment``, if not zero, is the maximum alignment that the
  compiler can choose by default for a 64-bit or larger scalar type or object.

  ``Maximum_Alignment`` is the maximum alignment that the compiler can choose
  by default for a type or object, which is also the maximum alignment that can
  be specified in GNAT. It is computed for GCC back ends as ``BIGGEST_ALIGNMENT
  / BITS_PER_UNIT`` where GCC macro ``BIGGEST_ALIGNMENT`` is documented as
  follows: `Biggest alignment that any data type can require on this machine,
  in bits.`

  ``Max_Unaligned_Field`` is the maximum size for unaligned bit field, which is
  64 for the majority of GCC targets (but can be different on some targets).

  ``Strict_Alignment`` is the equivalent of GCC macro ``STRICT_ALIGNMENT``
  documented as follows: `Define this macro to be the value 1 if instructions
  will fail to work if given data not on the nominal alignment. If instructions
  will merely go slower in that case, define this macro as 0.`

  ``System_Allocator_Alignment`` is the guaranteed alignment of data returned
  by calls to ``malloc``.


  The format of the input file is as follows. First come the values of
  the variables defined above, with one line per value:


  ::

    name  value

  where ``name`` is the name of the parameter, spelled out in full,
  and cased as in the above list, and ``value`` is an unsigned decimal
  integer. Two or more blanks separates the name from the value.

  All the variables must be present, in alphabetical order (i.e. the
  same order as the list above).

  Then there is a blank line to separate the two parts of the file. Then
  come the lines showing the floating-point types to be registered, with
  one line per registered mode:


  ::

    name  digs float_rep size alignment


  where ``name`` is the string name of the type (which can have
  single spaces embedded in the name, e.g. long double), ``digs`` is
  the number of digits for the floating-point type, ``float_rep`` is
  the float representation (I for IEEE-754-Binary, which is
  the only one supported at this time),
  ``size`` is the size in bits, ``alignment`` is the
  alignment in bits. The name is followed by at least two blanks, fields
  are separated by at least one blank, and a LF character immediately
  follows the alignment field.

  Here is an example of a target parameterization file:


  ::

    Bits_BE                       0
    Bits_Per_Unit                 8
    Bits_Per_Word                64
    Bytes_BE                      0
    Char_Size                     8
    Double_Float_Alignment        0
    Double_Scalar_Alignment       0
    Double_Size                  64
    Float_Size                   32
    Float_Words_BE                0
    Int_Size                     64
    Long_Double_Size            128
    Long_Long_Long_Size         128
    Long_Long_Size               64
    Long_Size                    64
    Maximum_Alignment            16
    Max_Unaligned_Field          64
    Pointer_Size                 64
    Short_Size                   16
    Strict_Alignment              0
    System_Allocator_Alignment   16
    Wchar_T_Size                 32
    Words_BE                      0

    float         15  I  64  64
    double        15  I  64  64
    long double   18  I  80 128
    TF            33  I 128 128



.. index:: -gnateu  (gcc)

:switch:`-gnateu`
  Ignore unrecognized validity, warning, and style switches that
  appear after this switch is given. This may be useful when
  compiling sources developed on a later version of the compiler
  with an earlier version. Of course the earlier version must
  support this switch.


.. index:: -gnateV  (gcc)

:switch:`-gnateV`
  Check that all actual parameters of a subprogram call are valid according to
  the rules of validity checking (:ref:`Validity_Checking`).


.. index:: -gnateY  (gcc)

:switch:`-gnateY`
  Ignore all STYLE_CHECKS pragmas. Full legality checks
  are still carried out, but the pragmas have no effect
  on what style checks are active. This allows all style
  checking options to be controlled from the command line.


.. index:: -gnatE  (gcc)

:switch:`-gnatE`
  Dynamic elaboration checking mode enabled. For further details see
  :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -gnatf  (gcc)

:switch:`-gnatf`
  Full errors. Multiple errors per line, all undefined references, do not
  attempt to suppress cascaded errors.


.. index:: -gnatF  (gcc)

:switch:`-gnatF`
  Externals names are folded to all uppercase.


.. index:: -gnatg  (gcc)

:switch:`-gnatg`
  Internal GNAT implementation mode. This should not be used for applications
  programs, it is intended only for use by the compiler and its run-time
  library. For documentation, see the GNAT sources. Note that :switch:`-gnatg`
  implies :switch:`-gnatw.ge` and :switch:`-gnatyg` so that all standard
  warnings and all standard style options are turned on. All warnings and style
  messages are treated as errors.


.. index:: -gnatG[nn]  (gcc)

:switch:`-gnatG=nn`
  List generated expanded code in source form.


.. index:: -gnath  (gcc)

:switch:`-gnath`
  Output usage information. The output is written to :file:`stdout`.


.. index:: -gnatH  (gcc)

:switch:`-gnatH`
  Legacy elaboration-checking mode enabled. When this switch is in effect,
  the pre-18.x access-before-elaboration model becomes the de facto model.
  For further details see :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -gnati  (gcc)

:switch:`-gnati{c}`
  Identifier character set (``c`` = 1/2/3/4/5/9/p/8/f/n/w).
  For details of the possible selections for ``c``,
  see :ref:`Character_Set_Control`.


.. index:: -gnatI  (gcc)

:switch:`-gnatI`
  Ignore representation clauses. When this switch is used,
  representation clauses are treated as comments. This is useful
  when initially porting code where you want to ignore rep clause
  problems, and also for compiling foreign code. The representation
  clauses that are ignored are: enumeration_representation_clause,
  record_representation_clause, and attribute_definition_clause for the
  following attributes: Address, Alignment, Bit_Order, Component_Size,
  Machine_Radix, Object_Size, Scalar_Storage_Order, Size, Small,
  Stream_Size, and Value_Size.
  Pragma Default_Scalar_Storage_Order is also ignored.
  Note that this option should be used only for compiling -- the
  code is likely to malfunction at run time.


.. index:: -gnatjnn  (gcc)

:switch:`-gnatj{nn}`
  Reformat error messages to fit on ``nn`` character lines


.. index:: -gnatJ  (gcc)

:switch:`-gnatJ`
  Permissive elaboration-checking mode enabled. When this switch is in effect,
  the post-18.x access-before-elaboration model ignores potential issues with:

  - Accept statements
  - Activations of tasks defined in instances
  - Assertion pragmas
  - Calls from within an instance to its enclosing context
  - Calls through generic formal parameters
  - Calls to subprograms defined in instances
  - Entry calls
  - Indirect calls using 'Access
  - Requeue statements
  - Select statements
  - Synchronous task suspension

  and does not emit compile-time diagnostics or run-time checks. For further
  details see :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -gnatk  (gcc)

:switch:`-gnatk={n}`
  Limit file names to ``n`` (1-999) characters (``k`` = krunch).


.. index:: -gnatl  (gcc)

:switch:`-gnatl`
  Output full source listing with embedded error messages.


.. index:: -gnatL  (gcc)

:switch:`-gnatL`
  Used in conjunction with -gnatG or -gnatD to intersperse original
  source lines (as comment lines with line numbers) in the expanded
  source output.


.. index:: -gnatm  (gcc)

:switch:`-gnatm={n}`
  Limit number of detected error or warning messages to ``n``
  where ``n`` is in the range 1..999999. The default setting if
  no switch is given is 9999. If the number of warnings reaches this
  limit, then a message is output and further warnings are suppressed,
  but the compilation is continued. If the number of error messages
  reaches this limit, then a message is output and the compilation
  is abandoned. The equal sign here is optional. A value of zero
  means that no limit applies.


.. index:: -gnatn  (gcc)

:switch:`-gnatn[12]`
  Activate inlining across units for subprograms for which pragma ``Inline``
  is specified. This inlining is performed by the GCC back end. An optional
  digit sets the inlining level: 1 for moderate inlining across units
  or 2 for full inlining across units. If no inlining level is specified,
  the compiler will pick it based on the optimization level.


.. index:: -gnatN  (gcc)

:switch:`-gnatN`
  Activate front end inlining for subprograms for which
  pragma ``Inline`` is specified. This inlining is performed
  by the front end and will be visible in the
  :switch:`-gnatG` output.

  When using a gcc-based back end, then the use of
  :switch:`-gnatN` is deprecated, and the use of :switch:`-gnatn` is preferred.
  Historically front end inlining was more extensive than the gcc back end
  inlining, but that is no longer the case.


.. index:: -gnato0  (gcc)

:switch:`-gnato0`
  Suppresses overflow checking. This causes the behavior of the compiler to
  match the default for older versions where overflow checking was suppressed
  by default. This is equivalent to having
  ``pragma Suppress (Overflow_Check)`` in a configuration pragma file.


.. index:: -gnato??  (gcc)

:switch:`-gnato??`
  Set default mode for handling generation of code to avoid intermediate
  arithmetic overflow. Here ``??`` is two digits, a
  single digit, or nothing. Each digit is one of the digits ``1``
  through ``3``:

  ===== ===============================================================
  Digit Interpretation
  ----- ---------------------------------------------------------------
  *1*   All intermediate overflows checked against base type (``STRICT``)
  *2*   Minimize intermediate overflows (``MINIMIZED``)
  *3*   Eliminate intermediate overflows (``ELIMINATED``)
  ===== ===============================================================

  If only one digit appears, then it applies to all
  cases; if two digits are given, then the first applies outside
  assertions, pre/postconditions, and type invariants, and the second
  applies within assertions, pre/postconditions, and type invariants.

  If no digits follow the :switch:`-gnato`, then it is equivalent to
  :switch:`-gnato11`,
  causing all intermediate overflows to be handled in strict
  mode.

  This switch also causes arithmetic overflow checking to be performed
  (as though ``pragma Unsuppress (Overflow_Check)`` had been specified).

  The default if no option :switch:`-gnato` is given is that overflow handling
  is in ``STRICT`` mode (computations done using the base type), and that
  overflow checking is enabled.

  Note that division by zero is a separate check that is not
  controlled by this switch (divide-by-zero checking is on by default).

  See also :ref:`Specifying_the_Desired_Mode`.


.. index:: -gnatp  (gcc)

:switch:`-gnatp`
  Suppress all checks. See :ref:`Run-Time_Checks` for details. This switch
  has no effect if cancelled by a subsequent :switch:`-gnat-p` switch.


.. index:: -gnat-p  (gcc)

:switch:`-gnat-p`
  Cancel effect of previous :switch:`-gnatp` switch.


.. index:: -gnatq  (gcc)

:switch:`-gnatq`
  Don't quit. Try semantics, even if parse errors.


.. index:: -gnatQ  (gcc)

:switch:`-gnatQ`
  Don't quit. Generate :file:`ALI` and tree files even if illegalities.
  Note that code generation is still suppressed in the presence of any
  errors, so even with :switch:`-gnatQ` no object file is generated.


.. index:: -gnatr  (gcc)

:switch:`-gnatr`
  Treat pragma Restrictions as Restriction_Warnings.


.. index:: -gnatR  (gcc)

:switch:`-gnatR[0|1|2|3|4][e][h][m][j][s]`
  Output representation information for declared types, objects and
  subprograms. Note that this switch is not allowed if a previous
  :switch:`-gnatD` switch has been given, since these two switches
  are not compatible.


.. index:: -gnats  (gcc)

:switch:`-gnats`
  Syntax check only.


.. index:: -gnatS  (gcc)

:switch:`-gnatS`
  Print package Standard.


.. index:: -gnatT  (gcc)

:switch:`-gnatT{nnn}`
  All compiler tables start at ``nnn`` times usual starting size.


.. index:: -gnatu  (gcc)

:switch:`-gnatu`
  List units for this compilation.


.. index:: -gnatU  (gcc)

:switch:`-gnatU`
  Tag all error messages with the unique string 'error:'


.. index:: -gnatv  (gcc)

:switch:`-gnatv`
  Verbose mode. Full error output with source lines to :file:`stdout`.


.. index:: -gnatV  (gcc)

:switch:`-gnatV`
  Control level of validity checking (:ref:`Validity_Checking`).


.. index:: -gnatw  (gcc)

:switch:`-gnatw{xxx}`
  Warning mode where
  ``xxx`` is a string of option letters that denotes
  the exact warnings that
  are enabled or disabled (:ref:`Warning_Message_Control`).


.. index:: -gnatW  (gcc)

:switch:`-gnatW{e}`
  Wide character encoding method
  (``e``\ =n/h/u/s/e/8).


.. index:: -gnatx  (gcc)

:switch:`-gnatx`
  Suppress generation of cross-reference information.


.. index:: -gnatX  (gcc)

:switch:`-gnatX`
  Enable core GNAT implementation extensions and latest Ada version.


.. index:: -gnatX0  (gcc)

:switch:`-gnatX0`
  Enable all GNAT implementation extensions and latest Ada version.


.. index:: -gnaty  (gcc)

:switch:`-gnaty`
  Enable built-in style checks (:ref:`Style_Checking`).


.. index:: -gnatz  (gcc)

:switch:`-gnatz{m}`
  Distribution stub generation and compilation
  (``m``\ =r/c for receiver/caller stubs).


.. index:: -I  (gcc)

:switch:`-I{dir}`
  .. index:: RTL

  Direct GNAT to search the ``dir`` directory for source files needed by
  the current compilation
  (see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`).


.. index:: -I-  (gcc)

:switch:`-I-`
  .. index:: RTL

  Except for the source file named in the command line, do not look for source
  files in the directory containing the source file named in the command line
  (see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`).


.. index:: -o  (gcc)

:switch:`-o {file}`
  This switch is used in ``gcc`` to redirect the generated object file
  and its associated ALI file. Beware of this switch with GNAT, because it may
  cause the object file and ALI file to have different names which in turn
  may confuse the binder and the linker.


.. index:: -nostdinc  (gcc)

:switch:`-nostdinc`
  Inhibit the search of the default location for the GNAT Run Time
  Library (RTL) source files.


.. index:: -nostdlib  (gcc)

:switch:`-nostdlib`
  Inhibit the search of the default location for the GNAT Run Time
  Library (RTL) ALI files.


.. index:: -O  (gcc)

:switch:`-O[{n}]`
  ``n`` controls the optimization level:

  ======= ==================================================================
   *n*     Effect
  ------- ------------------------------------------------------------------
  *0*      No optimization, the default setting if no :switch:`-O` appears.
  *1*      Moderate optimization, same as :switch:`-O` without an operand.
           A good compromise between code quality and compilation time.
  *2*      Extensive optimization, should improve execution time, possibly at
           the cost of substantially increased compilation time.
  *3*      Full optimization, may further improve execution time, possibly at
           the cost of substantially larger generated code.
  *s*      Optimize for size (code and data) rather than speed.
  *z*      Optimize aggressively for size (code and data) rather than speed.
  *g*      Optimize for debugging experience rather than speed.
  ======= ==================================================================

  See also :ref:`Optimization_Levels`.


.. index:: -pass-exit-codes  (gcc)

:switch:`-pass-exit-codes`
  Catch exit codes from the compiler and use the most meaningful as
  exit status.


.. index:: --RTS  (gcc)

:switch:`--RTS={rts-path}`
  Specifies the default location of the run-time library. Same meaning as the
  equivalent ``gnatmake`` flag (:ref:`Switches_for_gnatmake`).


.. index:: -S  (gcc)

:switch:`-S`
  Used in place of :switch:`-c` to
  cause the assembler source file to be
  generated, using :file:`.s` as the extension,
  instead of the object file.
  This may be useful if you need to examine the generated assembly code.


.. index:: -fverbose-asm  (gcc)

:switch:`-fverbose-asm`
  Used in conjunction with :switch:`-S`
  to cause the generated assembly code file to be annotated with variable
  names, making it significantly easier to follow.


.. index:: -v  (gcc)

:switch:`-v`
  Show commands generated by the ``gcc`` driver. Normally used only for
  debugging purposes or if you need to be sure what version of the
  compiler you are executing.


.. index:: -V  (gcc)

:switch:`-V {ver}`
  Execute ``ver`` version of the compiler. This is the ``gcc``
  version, not the GNAT version.


.. index:: -w  (gcc)

:switch:`-w`
  Turn off warnings generated by the back end of the compiler. Use of
  this switch also causes the default for front end warnings to be set
  to suppress (as though :switch:`-gnatws` had appeared at the start of
  the options).


.. index:: Combining GNAT switches

You may combine a sequence of GNAT switches into a single switch. For
example, the combined switch

  ::

    -gnatofi3

is equivalent to specifying the following sequence of switches:

  ::

    -gnato -gnatf -gnati3

The following restrictions apply to the combination of switches
in this manner:

* The switch :switch:`-gnatc` if combined with other switches must come
  first in the string.

* The switch :switch:`-gnats` if combined with other switches must come
  first in the string.

* The switches
  :switch:`-gnatzc` and :switch:`-gnatzr` may not be combined with any other
  switches, and only one of them may appear in the command line.

* The switch :switch:`-gnat-p` may not be combined with any other switch.

* Once a 'y' appears in the string (that is a use of the :switch:`-gnaty`
  switch), then all further characters in the switch are interpreted
  as style modifiers (see description of :switch:`-gnaty`).

* Once a 'd' appears in the string (that is a use of the :switch:`-gnatd`
  switch), then all further characters in the switch are interpreted
  as debug flags (see description of :switch:`-gnatd`).

* Once a 'w' appears in the string (that is a use of the :switch:`-gnatw`
  switch), then all further characters in the switch are interpreted
  as warning mode modifiers (see description of :switch:`-gnatw`).

* Once a 'V' appears in the string (that is a use of the :switch:`-gnatV`
  switch), then all further characters in the switch are interpreted
  as validity checking options (:ref:`Validity_Checking`).

* Option 'em', 'ec', 'ep', 'l=' and 'R' must be the last options in
  a combined list of options.

.. _Output_and_Error_Message_Control:

Output and Error Message Control
--------------------------------

.. index:: stderr

The standard default format for error messages is called 'brief format'.
Brief format messages are written to :file:`stderr` (the standard error
file) and have the following form:

::

  e.adb:3:04: Incorrect spelling of keyword "function"
  e.adb:4:20: ";" should be "is"

The first integer after the file name is the line number in the file,
and the second integer is the column number within the line.
``GNAT Studio`` can parse the error messages
and point to the referenced character.
The following switches provide control over the error message
format:


.. index:: -gnatv  (gcc)

:switch:`-gnatv`
  The ``v`` stands for verbose.
  The effect of this setting is to write long-format error
  messages to :file:`stdout` (the standard output file).
  The same program compiled with the
  :switch:`-gnatv` switch would generate:

  ::

    3. funcion X (Q : Integer)
       |
    >>> Incorrect spelling of keyword "function"
    4. return Integer;
                     |
    >>> ";" should be "is"


  The vertical bar indicates the location of the error, and the ``>>>``
  prefix can be used to search for error messages. When this switch is
  used the only source lines output are those with errors.


.. index:: -gnatl  (gcc)

:switch:`-gnatl`
  The ``l`` stands for list.
  This switch causes a full listing of
  the file to be generated. In the case where a body is
  compiled, the corresponding spec is also listed, along
  with any subunits. Typical output from compiling a package
  body :file:`p.adb` might look like::

    Compiling: p.adb

         1. package body p is
         2.    procedure a;
         3.    procedure a is separate;
         4. begin
         5.    null
                   |
            >>> missing ";"

         6. end;

    Compiling: p.ads

         1. package p is
         2.    pragma Elaborate_Body
                                    |
            >>> missing ";"

         3. end p;

    Compiling: p-a.adb

         1. separate p
                    |
            >>> missing "("

         2. procedure a is
         3. begin
         4.    null
                   |
            >>> missing ";"

         5. end;


  When you specify the :switch:`-gnatv` or :switch:`-gnatl` switches and
  standard output is redirected, a brief summary is written to
  :file:`stderr` (standard error) giving the number of error messages and
  warning messages generated.


.. index:: -gnatl=fname  (gcc)

:switch:`-gnatl={fname}`
  This has the same effect as :switch:`-gnatl` except that the output is
  written to a file instead of to standard output. If the given name
  :file:`fname` does not start with a period, then it is the full name
  of the file to be written. If :file:`fname` is an extension, it is
  appended to the name of the file being compiled. For example, if
  file :file:`xyz.adb` is compiled with :switch:`-gnatl=.lst`,
  then the output is written to file xyz.adb.lst.


.. index:: -gnatU  (gcc)

:switch:`-gnatU`
  This switch forces all error messages to be preceded by the unique
  string 'error:'. This means that error messages take a few more
  characters in space, but allows easy searching for and identification
  of error messages.


.. index:: -gnatb  (gcc)

:switch:`-gnatb`
  The ``b`` stands for brief.
  This switch causes GNAT to generate the
  brief format error messages to :file:`stderr` (the standard error
  file) as well as the verbose
  format message or full listing (which as usual is written to
  :file:`stdout`, the standard output file).


.. index:: -gnatm  (gcc)

:switch:`-gnatm={n}`
  The ``m`` stands for maximum.
  ``n`` is a decimal integer in the
  range of 1 to 999999 and limits the number of error or warning
  messages to be generated. For example, using
  :switch:`-gnatm2` might yield

  ::

    e.adb:3:04: Incorrect spelling of keyword "function"
    e.adb:5:35: missing ".."
    fatal error: maximum number of errors detected
    compilation abandoned


  The default setting if
  no switch is given is 9999. If the number of warnings reaches this
  limit, then a message is output and further warnings are suppressed,
  but the compilation is continued. If the number of error messages
  reaches this limit, then a message is output and the compilation
  is abandoned. A value of zero means that no limit applies.

  Note that the equal sign is optional, so the switches
  :switch:`-gnatm2` and :switch:`-gnatm=2` are equivalent.


.. index:: -gnatf  (gcc)

:switch:`-gnatf`
  .. index:: Error messages, suppressing

  The ``f`` stands for full.
  Normally, the compiler suppresses error messages that are likely to be
  redundant. This switch causes all error
  messages to be generated. In particular, in the case of
  references to undefined variables. If a given variable is referenced
  several times, the normal format of messages is

  ::

    e.adb:7:07: "V" is undefined (more references follow)

  where the parenthetical comment warns that there are additional
  references to the variable ``V``. Compiling the same program with the
  :switch:`-gnatf` switch yields

  ::

    e.adb:7:07: "V" is undefined
    e.adb:8:07: "V" is undefined
    e.adb:8:12: "V" is undefined
    e.adb:8:16: "V" is undefined
    e.adb:9:07: "V" is undefined
    e.adb:9:12: "V" is undefined

  The :switch:`-gnatf` switch also generates additional information for
  some error messages.  Some examples are:

  * Details on possibly non-portable unchecked conversion

  * List possible interpretations for ambiguous calls

  * Additional details on incorrect parameters


.. index:: -gnatjnn  (gcc)

:switch:`-gnatjnn`
  In normal operation mode (or if :switch:`-gnatj0` is used), then error messages
  with continuation lines are treated as though the continuation lines were
  separate messages (and so a warning with two continuation lines counts as
  three warnings, and is listed as three separate messages).

  If the :switch:`-gnatjnn` switch is used with a positive value for nn, then
  messages are output in a different manner. A message and all its continuation
  lines are treated as a unit, and count as only one warning or message in the
  statistics totals. Furthermore, the message is reformatted so that no line
  is longer than nn characters.


.. index:: -gnatq  (gcc)

:switch:`-gnatq`
  The ``q`` stands for quit (really 'don't quit').
  In normal operation mode, the compiler first parses the program and
  determines if there are any syntax errors. If there are, appropriate
  error messages are generated and compilation is immediately terminated.
  This switch tells
  GNAT to continue with semantic analysis even if syntax errors have been
  found. This may enable the detection of more errors in a single run. On
  the other hand, the semantic analyzer is more likely to encounter some
  internal fatal error when given a syntactically invalid tree.


.. index:: -gnatQ  (gcc)

:switch:`-gnatQ`
  In normal operation mode, the :file:`ALI` file is not generated if any
  illegalities are detected in the program. The use of :switch:`-gnatQ` forces
  generation of the :file:`ALI` file. This file is marked as being in
  error, so it cannot be used for binding purposes, but it does contain
  reasonably complete cross-reference information, and thus may be useful
  for use by tools (e.g., semantic browsing tools or integrated development
  environments) that are driven from the :file:`ALI` file. This switch
  implies :switch:`-gnatq`, since the semantic phase must be run to get a
  meaningful ALI file.

  When :switch:`-gnatQ` is used and the generated :file:`ALI` file is marked as
  being in error, ``gnatmake`` will attempt to recompile the source when it
  finds such an :file:`ALI` file, including with switch :switch:`-gnatc`.

  Note that :switch:`-gnatQ` has no effect if :switch:`-gnats` is specified,
  since ALI files are never generated if :switch:`-gnats` is set.


.. _Warning_Message_Control:

Warning Message Control
-----------------------

.. index:: Warning messages

In addition to error messages, which correspond to illegalities as defined
in the Ada Reference Manual, the compiler detects two kinds of warning
situations.

First, the compiler considers some constructs suspicious and generates a
warning message to alert you to a possible error. Second, if the
compiler detects a situation that is sure to raise an exception at
run time, it generates a warning message. The following shows an example
of warning messages:

::

  e.adb:4:24: warning: creation of object may raise Storage_Error
  e.adb:10:17: warning: static value out of range
  e.adb:10:17: warning: "Constraint_Error" will be raised at run time


GNAT considers a large number of situations as appropriate
for the generation of warning messages. As always, warnings are not
definite indications of errors. For example, if you do an out-of-range
assignment with the deliberate intention of raising a
``Constraint_Error`` exception, then the warning that may be
issued does not indicate an error. Some of the situations for which GNAT
issues warnings (at least some of the time) are given in the following
list. This list is not complete, and new warnings are often added to
subsequent versions of GNAT. The list is intended to give a general idea
of the kinds of warnings that are generated.

* Possible infinitely recursive calls

* Out-of-range values being assigned

* Possible order of elaboration problems

* Size not a multiple of alignment for a record type

* Assertions (pragma Assert) that are sure to fail

* Unreachable code

* Address clauses with possibly unaligned values, or where an attempt is
  made to overlay a smaller variable with a larger one.

* Fixed-point type declarations with a null range

* Direct_IO or Sequential_IO instantiated with a type that has access values

* Variables that are never assigned a value

* Variables that are referenced before being initialized

* Task entries with no corresponding ``accept`` statement

* Duplicate accepts for the same task entry in a ``select``

* Objects that take too much storage

* Unchecked conversion between types of differing sizes

* Missing ``return`` statement along some execution path in a function

* Incorrect (unrecognized) pragmas

* Incorrect external names

* Allocation from empty storage pool

* Potentially blocking operation in protected type

* Suspicious parenthesization of expressions

* Mismatching bounds in an aggregate

* Attempt to return local value by reference

* Premature instantiation of a generic body

* Attempt to pack aliased components

* Out of bounds array subscripts

* Wrong length on string assignment

* Violations of style rules if style checking is enabled

* Unused |with| clauses

* ``Bit_Order`` usage that does not have any effect

* ``Standard.Duration`` used to resolve universal fixed expression

* Dereference of possibly null value

* Declaration that is likely to cause storage error

* Internal GNAT unit |withed| by application unit

* Values known to be out of range at compile time

* Unreferenced or unmodified variables. Note that a special
  exemption applies to variables which contain any of the substrings
  ``DISCARD, DUMMY, IGNORE, JUNK, UNUSE, TMP, TEMP`` in any casing. Such
  variables are considered likely to be intentionally used in a situation
  where otherwise a warning would be given, so warnings of this kind are
  always suppressed for such variables.

* Address overlays that could clobber memory

* Unexpected initialization when address clause present

* Bad alignment for address clause

* Useless type conversions

* Redundant assignment statements and other redundant constructs

* Useless exception handlers

* Accidental hiding of name by child unit

* Access before elaboration detected at compile time

* A range in a ``for`` loop that is known to be null or might be null


The following section lists compiler switches that are available
to control the handling of warning messages. It is also possible
to exercise much finer control over what warnings are issued and
suppressed using the GNAT pragma Warnings (see the description
of the pragma in the :title:`GNAT_Reference_manual`).


.. index:: -gnatwa  (gcc)

:switch:`-gnatwa`
  *Activate most optional warnings.*

  This switch activates most optional warning messages. See the remaining list
  in this section for details on optional warning messages that can be
  individually controlled.  The warnings that are not turned on by this
  switch are:


  * :switch:`-gnatwd` (implicit dereferencing)

  * :switch:`-gnatw.d` (tag warnings with -gnatw switch)

  * :switch:`-gnatwh` (hiding)

  * :switch:`-gnatw.h` (holes in record layouts)

  * :switch:`-gnatw.j` (late primitives of tagged types)

  * :switch:`-gnatw.k` (redefinition of names in standard)

  * :switch:`-gnatwl` (elaboration warnings)

  * :switch:`-gnatw.l` (inherited aspects)

  * :switch:`-gnatw.n` (atomic synchronization)

  * :switch:`-gnatwo` (address clause overlay)

  * :switch:`-gnatw.o` (values set by out parameters ignored)

  * :switch:`-gnatw.q` (questionable layout of record types)

  * :switch:`-gnatw_q` (ignored equality)

  * :switch:`-gnatw_r` (out-of-order record representation clauses)

  * :switch:`-gnatw.s` (overridden size clause)

  * :switch:`-gnatw_s` (ineffective predicate test)

  * :switch:`-gnatwt` (tracking of deleted conditional code)

  * :switch:`-gnatw.u` (unordered enumeration)

  * :switch:`-gnatw.w` (use of Warnings Off)

  * :switch:`-gnatw.y` (reasons for package needing body)

  All other optional warnings are turned on.


.. index:: -gnatwA  (gcc)

:switch:`-gnatwA`
  *Suppress all optional errors.*

  This switch suppresses all optional warning messages, see remaining list
  in this section for details on optional warning messages that can be
  individually controlled. Note that unlike switch :switch:`-gnatws`, the
  use of switch :switch:`-gnatwA` does not suppress warnings that are
  normally given unconditionally and cannot be individually controlled
  (for example, the warning about a missing exit path in a function).
  Also, again unlike switch :switch:`-gnatws`, warnings suppressed by
  the use of switch :switch:`-gnatwA` can be individually turned back
  on. For example the use of switch :switch:`-gnatwA` followed by
  switch :switch:`-gnatwd` will suppress all optional warnings except
  the warnings for implicit dereferencing.

.. index:: -gnatw.a  (gcc)

:switch:`-gnatw.a`
  *Activate warnings on failing assertions.*

  .. index:: Assert failures

  This switch activates warnings for assertions where the compiler can tell at
  compile time that the assertion will fail. Note that this warning is given
  even if assertions are disabled. The default is that such warnings are
  generated.


.. index:: -gnatw.A  (gcc)

:switch:`-gnatw.A`
  *Suppress warnings on failing assertions.*

  .. index:: Assert failures

  This switch suppresses warnings for assertions where the compiler can tell at
  compile time that the assertion will fail.


.. index:: -gnatw_a

:switch:`-gnatw_a`
  *Activate warnings on anonymous allocators.*

  .. index:: Anonymous allocators

  This switch activates warnings for allocators of anonymous access types,
  which can involve run-time accessibility checks and lead to unexpected
  accessibility violations. For more details on the rules involved, see
  RM 3.10.2 (14).


.. index:: -gnatw_A

:switch:`-gnatw_A`
  *Suppress warnings on anonymous allocators.*

  .. index:: Anonymous allocators

  This switch suppresses warnings for anonymous access type allocators.


.. index:: -gnatwb  (gcc)

:switch:`-gnatwb`
  *Activate warnings on bad fixed values.*

  .. index:: Bad fixed values

  .. index:: Fixed-point Small value

  .. index:: Small value

  This switch activates warnings for static fixed-point expressions whose
  value is not an exact multiple of Small. Such values are implementation
  dependent, since an implementation is free to choose either of the multiples
  that surround the value. GNAT always chooses the closer one, but this is not
  required behavior, and it is better to specify a value that is an exact
  multiple, ensuring predictable execution. The default is that such warnings
  are not generated.


.. index:: -gnatwB  (gcc)

:switch:`-gnatwB`
  *Suppress warnings on bad fixed values.*

  This switch suppresses warnings for static fixed-point expressions whose
  value is not an exact multiple of Small.


.. index:: -gnatw.b  (gcc)

:switch:`-gnatw.b`
  *Activate warnings on biased representation.*

  .. index:: Biased representation

  This switch activates warnings when a size clause, value size clause, component
  clause, or component size clause forces the use of biased representation for an
  integer type (e.g. representing a range of 10..11 in a single bit by using 0/1
  to represent 10/11). The default is that such warnings are generated.


.. index:: -gnatwB  (gcc)

:switch:`-gnatw.B`
  *Suppress warnings on biased representation.*

  This switch suppresses warnings for representation clauses that force the use
  of biased representation.


.. index:: -gnatwc  (gcc)

:switch:`-gnatwc`
  *Activate warnings on conditionals.*

  .. index:: Conditionals, constant

  This switch activates warnings for boolean expressions that are known to
  be True or False at compile time. The default
  is that such warnings are not generated.
  Note that this warning does
  not get issued for the use of boolean constants whose
  values are known at compile time, since this is a standard technique
  for conditional compilation in Ada, and this would generate too many
  false positive warnings.

  This warning option also activates a special test for comparisons using
  the operators '>=' and' <='.
  If the compiler can tell that only the equality condition is possible,
  then it will warn that the '>' or '<' part of the test
  is useless and that the operator could be replaced by '='.
  An example would be comparing a ``Natural`` variable <= 0.

  This warning option also generates warnings if
  one or both tests is optimized away in a membership test for integer
  values if the result can be determined at compile time. Range tests on
  enumeration types are not included, since it is common for such tests
  to include an end point.

  This warning can also be turned on using :switch:`-gnatwa`.


.. index:: -gnatwC  (gcc)

:switch:`-gnatwC`
  *Suppress warnings on conditionals.*

  This switch suppresses warnings for conditional expressions used in
  tests that are known to be True or False at compile time.


.. index:: -gnatw.c  (gcc)

:switch:`-gnatw.c`
  *Activate warnings on missing component clauses.*

  .. index:: Component clause, missing

  This switch activates warnings for record components where a record
  representation clause is present and has component clauses for the
  majority, but not all, of the components. A warning is given for each
  component for which no component clause is present.


.. index:: -gnatw.C  (gcc)

:switch:`-gnatw.C`
  *Suppress warnings on missing component clauses.*

  This switch suppresses warnings for record components that are
  missing a component clause in the situation described above.


.. index:: -gnatw_c  (gcc)

:switch:`-gnatw_c`
  *Activate warnings on unknown condition in Compile_Time_Warning.*

  .. index:: Compile_Time_Warning
  .. index:: Compile_Time_Error

  This switch activates warnings on a pragma Compile_Time_Warning
  or Compile_Time_Error whose condition has a value that is not
  known at compile time.
  The default is that such warnings are generated.


.. index:: -gnatw_C  (gcc)

:switch:`-gnatw_C`
  *Suppress warnings on unknown condition in Compile_Time_Warning.*

  This switch suppresses warnings on a pragma Compile_Time_Warning
  or Compile_Time_Error whose condition has a value that is not
  known at compile time.


.. index:: -gnatwd  (gcc)

:switch:`-gnatwd`
  *Activate warnings on implicit dereferencing.*

  If this switch is set, then the use of a prefix of an access type
  in an indexed component, slice, or selected component without an
  explicit ``.all`` will generate a warning. With this warning
  enabled, access checks occur only at points where an explicit
  ``.all`` appears in the source code (assuming no warnings are
  generated as a result of this switch). The default is that such
  warnings are not generated.


.. index:: -gnatwD  (gcc)

:switch:`-gnatwD`
  *Suppress warnings on implicit dereferencing.*

  .. index:: Implicit dereferencing

  .. index:: Dereferencing, implicit

  This switch suppresses warnings for implicit dereferences in
  indexed components, slices, and selected components.


.. index:: -gnatw.d  (gcc)

:switch:`-gnatw.d`
  *Activate tagging of warning and info messages.*

  If this switch is set, then warning messages are tagged, with one of the
  following strings:

    - *[-gnatw?]*
      Used to tag warnings controlled by the switch :switch:`-gnatwx` where x
      is a letter a-z.


    - *[-gnatw.?]*
      Used to tag warnings controlled by the switch :switch:`-gnatw.x` where x
      is a letter a-z.


    - *[-gnatel]*
      Used to tag elaboration information (info) messages generated when the
      static model of elaboration is used and the :switch:`-gnatel` switch is set.


    - *[restriction warning]*
      Used to tag warning messages for restriction violations, activated by use
      of the pragma ``Restriction_Warnings``.


    - *[warning-as-error]*
      Used to tag warning messages that have been converted to error messages by
      use of the pragma Warning_As_Error. Note that such warnings are prefixed by
      the string "error: " rather than "warning: ".


    - *[enabled by default]*
      Used to tag all other warnings that are always given by default, unless
      warnings are completely suppressed using pragma *Warnings(Off)* or
      the switch :switch:`-gnatws`.



.. index:: -gnatw.d  (gcc)

:switch:`-gnatw.D`
  *Deactivate tagging of warning and info messages messages.*

  If this switch is set, then warning messages return to the default
  mode in which warnings and info messages are not tagged as described above for
  :switch:`-gnatw.d`.


.. index:: -gnatwe  (gcc)
.. index:: Warnings, treat as error

:switch:`-gnatwe`
  *Treat warnings and style checks as errors.*

  This switch causes warning messages and style check messages to be
  treated as errors.
  The warning string still appears, but the warning messages are counted
  as errors, and prevent the generation of an object file. Note that this
  is the only -gnatw switch that affects the handling of style check messages.
  Note also that this switch has no effect on info (information) messages, which
  are not treated as errors if this switch is present.


.. index:: -gnatw.e  (gcc)

:switch:`-gnatw.e`
  *Activate every optional warning.*

  .. index:: Warnings, activate every optional warning

  This switch activates all optional warnings, including those which
  are not activated by :switch:`-gnatwa`. The use of this switch is not
  recommended for normal use. If you turn this switch on, it is almost
  certain that you will get large numbers of useless warnings. The
  warnings that are excluded from :switch:`-gnatwa` are typically highly
  specialized warnings that are suitable for use only in code that has
  been specifically designed according to specialized coding rules.


.. index:: -gnatwE  (gcc)
.. index:: Warnings, treat as error

:switch:`-gnatwE`
  *Treat all run-time exception warnings as errors.*

  This switch causes warning messages regarding errors that will be raised
  during run-time execution to be treated as errors.


.. index:: -gnatwf  (gcc)

:switch:`-gnatwf`
  *Activate warnings on unreferenced formals.*

  .. index:: Formals, unreferenced

  This switch causes a warning to be generated if a formal parameter
  is not referenced in the body of the subprogram. This warning can
  also be turned on using :switch:`-gnatwu`. The
  default is that these warnings are not generated.


.. index:: -gnatwF  (gcc)

:switch:`-gnatwF`
  *Suppress warnings on unreferenced formals.*

  This switch suppresses warnings for unreferenced formal
  parameters. Note that the
  combination :switch:`-gnatwu` followed by :switch:`-gnatwF` has the
  effect of warning on unreferenced entities other than subprogram
  formals.


.. index:: -gnatwg  (gcc)

:switch:`-gnatwg`
  *Activate warnings on unrecognized pragmas.*

  .. index:: Pragmas, unrecognized

  This switch causes a warning to be generated if an unrecognized
  pragma is encountered. Apart from issuing this warning, the
  pragma is ignored and has no effect. The default
  is that such warnings are issued (satisfying the Ada Reference
  Manual requirement that such warnings appear).


.. index:: -gnatwG  (gcc)

:switch:`-gnatwG`
  *Suppress warnings on unrecognized pragmas.*

  This switch suppresses warnings for unrecognized pragmas.


.. index:: -gnatw.g  (gcc)

:switch:`-gnatw.g`
  *Warnings used for GNAT sources.*

  This switch sets the warning categories that are used by the standard
  GNAT style. Currently this is equivalent to
  :switch:`-gnatwAao.q.s.CI.V.X.Z`
  but more warnings may be added in the future without advanced notice.


.. index:: -gnatwh  (gcc)

:switch:`-gnatwh`
  *Activate warnings on hiding.*

  .. index:: Hiding of Declarations

  This switch activates warnings on hiding declarations that are considered
  potentially confusing. Not all cases of hiding cause warnings; for example an
  overriding declaration hides an implicit declaration, which is just normal
  code. The default is that warnings on hiding are not generated.


.. index:: -gnatwH  (gcc)

:switch:`-gnatwH`
  *Suppress warnings on hiding.*

  This switch suppresses warnings on hiding declarations.


.. index:: -gnatw.h  (gcc)

:switch:`-gnatw.h`
  *Activate warnings on holes/gaps in records.*

  .. index:: Record Representation (gaps)

  This switch activates warnings on component clauses in record
  representation clauses that leave holes (gaps) in the record layout.
  If a record representation clause does not specify a location for
  every component of the record type, then the warnings generated (or not
  generated) are unspecified. For example, there may be gaps for which
  either no warning is generated or a warning is generated that
  incorrectly describes the location of the gap. This undesirable situation
  can sometimes be avoided by adding (and specifying the location for) unused
  fill fields.


.. index:: -gnatw.H  (gcc)

:switch:`-gnatw.H`
  *Suppress warnings on holes/gaps in records.*

  This switch suppresses warnings on component clauses in record
  representation clauses that leave holes (haps) in the record layout.


.. index:: -gnatwi  (gcc)

:switch:`-gnatwi`
  *Activate warnings on implementation units.*

  This switch activates warnings for a |with| of an internal GNAT
  implementation unit, defined as any unit from the ``Ada``,
  ``Interfaces``, ``GNAT``,
  or ``System``
  hierarchies that is not
  documented in either the Ada Reference Manual or the GNAT
  Programmer's Reference Manual. Such units are intended only
  for internal implementation purposes and should not be |withed|
  by user programs. The default is that such warnings are generated


.. index:: -gnatwI  (gcc)

:switch:`-gnatwI`
  *Disable warnings on implementation units.*

  This switch disables warnings for a |with| of an internal GNAT
  implementation unit.


.. index:: -gnatw.i  (gcc)

:switch:`-gnatw.i`
  *Activate warnings on overlapping actuals.*

  This switch enables a warning on statically detectable overlapping actuals in
  a subprogram call, when one of the actuals is an in-out parameter, and the
  types of the actuals are not by-copy types. This warning is off by default.


.. index:: -gnatw.I  (gcc)

:switch:`-gnatw.I`
  *Disable warnings on overlapping actuals.*

  This switch disables warnings on overlapping actuals in a call.


.. index:: -gnatwj  (gcc)

:switch:`-gnatwj`
  *Activate warnings on obsolescent features (Annex J).*

  .. index:: Features, obsolescent

  .. index:: Obsolescent features

  If this warning option is activated, then warnings are generated for
  calls to subprograms marked with ``pragma Obsolescent`` and
  for use of features in Annex J of the Ada Reference Manual. In the
  case of Annex J, not all features are flagged. In particular, uses of package
  ``ASCII`` are not flagged, since these are very common and
  would generate many annoying positive warnings. The default is that
  such warnings are not generated.

  In addition to the above cases, warnings are also generated for
  GNAT features that have been provided in past versions but which
  have been superseded (typically by features in the new Ada standard).
  For example, ``pragma Ravenscar`` will be flagged since its
  function is replaced by ``pragma Profile(Ravenscar)``, and
  ``pragma Interface_Name`` will be flagged since its function
  is replaced by ``pragma Import``.

  Note that this warning option functions differently from the
  restriction ``No_Obsolescent_Features`` in two respects.
  First, the restriction applies only to annex J features.
  Second, the restriction does flag uses of package ``ASCII``.


.. index:: -gnatwJ  (gcc)

:switch:`-gnatwJ`
  *Suppress warnings on obsolescent features (Annex J).*

  This switch disables warnings on use of obsolescent features.


.. index:: -gnatw.j  (gcc)

:switch:`-gnatw.j`
  *Activate warnings on late declarations of tagged type primitives.*

  This switch activates warnings on visible primitives added to a
  tagged type after deriving a private extension from it.


.. index:: -gnatw.J  (gcc)

:switch:`-gnatw.J`
  *Suppress warnings on late declarations of tagged type primitives.*

  This switch suppresses warnings on visible primitives added to a
  tagged type after deriving a private extension from it.


.. index:: -gnatwk  (gcc)

:switch:`-gnatwk`
  *Activate warnings on variables that could be constants.*

  This switch activates warnings for variables that are initialized but
  never modified, and then could be declared constants. The default is that
  such warnings are not given.


.. index:: -gnatwK  (gcc)

:switch:`-gnatwK`
  *Suppress warnings on variables that could be constants.*

  This switch disables warnings on variables that could be declared constants.


.. index:: -gnatw.k  (gcc)

:switch:`-gnatw.k`
  *Activate warnings on redefinition of names in standard.*

  This switch activates warnings for declarations that declare a name that
  is defined in package Standard. Such declarations can be confusing,
  especially since the names in package Standard continue to be directly
  visible, meaning that use visibility on such redeclared names does not
  work as expected. Names of discriminants and components in records are
  not included in this check.


.. index:: -gnatwK  (gcc)

:switch:`-gnatw.K`
  *Suppress warnings on redefinition of names in standard.*

  This switch disables warnings for declarations that declare a name that
  is defined in package Standard.


.. index:: -gnatwl  (gcc)

:switch:`-gnatwl`
  *Activate warnings for elaboration pragmas.*

  .. index:: Elaboration, warnings

  This switch activates warnings for possible elaboration problems,
  including suspicious use
  of ``Elaborate`` pragmas, when using the static elaboration model, and
  possible situations that may raise ``Program_Error`` when using the
  dynamic elaboration model.
  See the section in this guide on elaboration checking for further details.
  The default is that such warnings
  are not generated.


.. index:: -gnatwL  (gcc)

:switch:`-gnatwL`
  *Suppress warnings for elaboration pragmas.*

  This switch suppresses warnings for possible elaboration problems.


.. index:: -gnatw.l  (gcc)

:switch:`-gnatw.l`
  *List inherited aspects as info messages.*

  This switch causes the compiler to list inherited invariants,
  preconditions, and postconditions from Type_Invariant'Class, Invariant'Class,
  Pre'Class, and Post'Class aspects. Also list inherited subtype predicates.


.. index:: -gnatw.L  (gcc)

:switch:`-gnatw.L`
  *Suppress listing of inherited aspects as info messages.*

  This switch suppresses listing of inherited aspects.


.. index:: -gnatw_l  (gcc)

:switch:`-gnatw_l`
  *Activate warnings on implicitly limited types.*

  This switch causes the compiler trigger warnings on record types that do not
  have a limited keyword but contain a component that is a limited type.


.. index:: -gnatw_L  (gcc)

:switch:`-gnatw_L`
  *Suppress warnings on implicitly limited types.*

  This switch suppresses warnings on implicitly limited types.


.. index:: -gnatwm  (gcc)

:switch:`-gnatwm`
  *Activate warnings on modified but unreferenced variables.*

  This switch activates warnings for variables that are assigned (using
  an initialization value or with one or more assignment statements) but
  whose value is never read. The warning is suppressed for volatile
  variables and also for variables that are renamings of other variables
  or for which an address clause is given.
  The default is that these warnings are not given.


.. index:: -gnatwM  (gcc)

:switch:`-gnatwM`
  *Disable warnings on modified but unreferenced variables.*

  This switch disables warnings for variables that are assigned or
  initialized, but never read.


.. index:: -gnatw.m  (gcc)

:switch:`-gnatw.m`
  *Activate warnings on suspicious modulus values.*

  This switch activates warnings for modulus values that seem suspicious.
  The cases caught are where the size is the same as the modulus (e.g.
  a modulus of 7 with a size of 7 bits), and modulus values of 32 or 64
  with no size clause. The guess in both cases is that 2**x was intended
  rather than x. In addition expressions of the form 2*x for small x
  generate a warning (the almost certainly accurate guess being that
  2**x was intended). This switch also activates warnings for negative
  literal values of a modular type, which are interpreted as large positive
  integers after wrap-around. The default is that these warnings are given.



.. index:: -gnatw.M  (gcc)

:switch:`-gnatw.M`
  *Disable warnings on suspicious modulus values.*

  This switch disables warnings for suspicious modulus values.


.. index:: -gnatwn  (gcc)

:switch:`-gnatwn`
  *Set normal warnings mode.*

  This switch sets normal warning mode, in which enabled warnings are
  issued and treated as warnings rather than errors. This is the default
  mode. the switch :switch:`-gnatwn` can be used to cancel the effect of
  an explicit :switch:`-gnatws` or
  :switch:`-gnatwe`. It also cancels the effect of the
  implicit :switch:`-gnatwe` that is activated by the
  use of :switch:`-gnatg`.


.. index:: -gnatw.n  (gcc)
.. index:: Atomic Synchronization, warnings

:switch:`-gnatw.n`
  *Activate warnings on atomic synchronization.*

  This switch activates warnings when an access to an atomic variable
  requires the generation of atomic synchronization code. These
  warnings are off by default.

.. index:: -gnatw.N  (gcc)

:switch:`-gnatw.N`
  *Suppress warnings on atomic synchronization.*

  .. index:: Atomic Synchronization, warnings

  This switch suppresses warnings when an access to an atomic variable
  requires the generation of atomic synchronization code.


.. index:: -gnatwo  (gcc)
.. index:: Address Clauses, warnings

:switch:`-gnatwo`
  *Activate warnings on address clause overlays.*

  This switch activates warnings for possibly unintended initialization
  effects of defining address clauses that cause one variable to overlap
  another. The default is that such warnings are generated.


.. index:: -gnatwO  (gcc)

:switch:`-gnatwO`
  *Suppress warnings on address clause overlays.*

  This switch suppresses warnings on possibly unintended initialization
  effects of defining address clauses that cause one variable to overlap
  another.


.. index:: -gnatw.o  (gcc)

:switch:`-gnatw.o`
  *Activate warnings on modified but unreferenced out parameters.*

  This switch activates warnings for variables that are modified by using
  them as actuals for a call to a procedure with an out mode formal, where
  the resulting assigned value is never read. It is applicable in the case
  where there is more than one out mode formal. If there is only one out
  mode formal, the warning is issued by default (controlled by -gnatwu).
  The warning is suppressed for volatile
  variables and also for variables that are renamings of other variables
  or for which an address clause is given.
  The default is that these warnings are not given.


.. index:: -gnatw.O  (gcc)

:switch:`-gnatw.O`
  *Disable warnings on modified but unreferenced out parameters.*

  This switch suppresses warnings for variables that are modified by using
  them as actuals for a call to a procedure with an out mode formal, where
  the resulting assigned value is never read.


.. index:: -gnatwp  (gcc)
.. index:: Inlining, warnings

:switch:`-gnatwp`
  *Activate warnings on ineffective pragma Inlines.*

  This switch activates warnings for failure of cross-unit inlining
  (activated by :switch:`-gnatn`) to inline calls to a subprogram.
  There are many reasons for not being able to inline these calls,
  including most commonly that the subprogram body is too complex
  to inline. The default is that such warnings are not given.
  Warnings on ineffective inlining (within units) by the back end
  can be activated separately, using the -Winline switch.


.. index:: -gnatwP  (gcc)

:switch:`-gnatwP`
  *Suppress warnings on ineffective pragma Inlines.*

  This switch suppresses warnings on ineffective pragma Inlines. If the
  inlining mechanism cannot inline a call, it will simply ignore the
  request silently.


.. index:: -gnatw.p  (gcc)
.. index:: Parameter order, warnings

:switch:`-gnatw.p`
  *Activate warnings on parameter ordering.*

  This switch activates warnings for cases of suspicious parameter
  ordering when the list of arguments are all simple identifiers that
  match the names of the formals, but are in a different order. The
  warning is suppressed if any use of named parameter notation is used,
  so this is the appropriate way to suppress a false positive (and
  serves to emphasize that the "misordering" is deliberate). The
  default is that such warnings are not given.


.. index:: -gnatw.P  (gcc)

:switch:`-gnatw.P`
  *Suppress warnings on parameter ordering.*

  This switch suppresses warnings on cases of suspicious parameter
  ordering.


.. index:: -gnatw_p  (gcc)

:switch:`-gnatw_p`
  *Activate warnings for pedantic checks.*

  This switch activates warnings for the failure of certain pedantic checks.
  The only case currently supported is a check that the subtype_marks given
  for corresponding formal parameter and function results in a subprogram
  declaration and its body denote the same subtype declaration. The default
  is that such warnings are not given.

.. index:: -gnatw_P  (gcc)

:switch:`-gnatw_P`
  *Suppress warnings for pedantic checks.*

  This switch suppresses warnings on violations of pedantic checks.


.. index:: -gnatwq  (gcc)
.. index:: Parentheses, warnings

:switch:`-gnatwq`
  *Activate warnings on questionable missing parentheses.*

  This switch activates warnings for cases where parentheses are not used and
  the result is potential ambiguity from a readers point of view. For example
  (not a > b) when a and b are modular means ((not a) > b) and very likely the
  programmer intended (not (a > b)). Similarly (-x mod 5) means (-(x mod 5)) and
  quite likely ((-x) mod 5) was intended. In such situations it seems best to
  follow the rule of always parenthesizing to make the association clear, and
  this warning switch warns if such parentheses are not present. The default
  is that these warnings are given.


.. index:: -gnatwQ  (gcc)

:switch:`-gnatwQ`
  *Suppress warnings on questionable missing parentheses.*

  This switch suppresses warnings for cases where the association is not
  clear and the use of parentheses is preferred.


.. index:: -gnatw.q  (gcc)
.. index:: Layout, warnings

:switch:`-gnatw.q`
  *Activate warnings on questionable layout of record types.*

  This switch activates warnings for cases where the default layout of
  a record type, that is to say the layout of its components in textual
  order of the source code, would very likely cause inefficiencies in
  the code generated by the compiler, both in terms of space and speed
  during execution. One warning is issued for each problematic component
  without representation clause in the nonvariant part and then in each
  variant recursively, if any.

  The purpose of these warnings is neither to prescribe an optimal layout
  nor to force the use of representation clauses, but rather to get rid of
  the most blatant inefficiencies in the layout. Therefore, the default
  layout is matched against the following synthetic ordered layout and
  the deviations are flagged on a component-by-component basis:

  * first all components or groups of components whose length is fixed
    and a multiple of the storage unit,

  * then the remaining components whose length is fixed and not a multiple
    of the storage unit,

  * then the remaining components whose length doesn't depend on discriminants
    (that is to say, with variable but uniform length for all objects),

  * then all components whose length depends on discriminants,

  * finally the variant part (if any),

  for the nonvariant part and for each variant recursively, if any.

  The exact wording of the warning depends on whether the compiler is allowed
  to reorder the components in the record type or precluded from doing it by
  means of pragma ``No_Component_Reordering``.

  The default is that these warnings are not given.

.. index:: -gnatw.Q  (gcc)

:switch:`-gnatw.Q`
  *Suppress warnings on questionable layout of record types.*

  This switch suppresses warnings for cases where the default layout of
  a record type would very likely cause inefficiencies.


.. index:: -gnatw_q  (gcc)

:switch:`-gnatw_q`
  *Activate warnings for ignored equality operators.*

  This switch activates warnings for a user-defined "=" function that does
  not compose (i.e. is ignored for a predefined "=" for a composite type
  containing a component whose type has the user-defined "=" as
  primitive). Note that the user-defined "=" must be a primitive operator
  in order to trigger the warning.
  See RM-4.5.2(14/3-15/5, 21, 24/3, 32.1/1)
  for the exact Ada rules on composability of "=".

  The default is that these warnings are not given.

.. index:: -gnatw_Q  (gcc)

:switch:`-gnatw_Q`
  *Suppress warnings for ignored equality operators.*


.. index:: -gnatwr  (gcc)

:switch:`-gnatwr`
  *Activate warnings on redundant constructs.*

  This switch activates warnings for redundant constructs. The following
  is the current list of constructs regarded as redundant:

  * Assignment of an item to itself.

  * Type conversion that converts an expression to its own subtype.

  * Use of the attribute ``Base`` where ``typ'Base`` is the same
    as ``typ``.

  * Use of pragma ``Pack`` when all components are placed by a record
    representation clause.

  * Exception handler containing only a reraise statement (raise with no
    operand) which has no effect.

  * Use of the operator abs on an operand that is known at compile time
    to be non-negative

  * Comparison of an object or (unary or binary) operation of boolean type to
    an explicit True value.

  * Import of parent package.

  The default is that warnings for redundant constructs are not given.


.. index:: -gnatwR  (gcc)

:switch:`-gnatwR`
  *Suppress warnings on redundant constructs.*

  This switch suppresses warnings for redundant constructs.


.. index:: -gnatw.r  (gcc)

:switch:`-gnatw.r`
  *Activate warnings for object renaming function.*

  This switch activates warnings for an object renaming that renames a
  function call, which is equivalent to a constant declaration (as
  opposed to renaming the function itself).  The default is that these
  warnings are given.


.. index:: -gnatw.R  (gcc)

:switch:`-gnatw.R`
  *Suppress warnings for object renaming function.*

  This switch suppresses warnings for object renaming function.


.. index:: -gnatw_r  (gcc)

:switch:`-gnatw_r`
  *Activate warnings for out-of-order record representation clauses.*

  This switch activates warnings for record representation clauses,
  if the order of component declarations, component clauses,
  and bit-level layout do not all agree.
  The default is that these warnings are not given.


.. index:: -gnatw_R  (gcc)

:switch:`-gnatw_R`
  *Suppress warnings for out-of-order record representation clauses.*


.. index:: -gnatws  (gcc)

:switch:`-gnatws`
  *Suppress all warnings.*

  This switch completely suppresses the
  output of all warning messages from the GNAT front end, including
  both warnings that can be controlled by switches described in this
  section, and those that are normally given unconditionally. The
  effect of this suppress action can only be cancelled by a subsequent
  use of the switch :switch:`-gnatwn`.

  Note that switch :switch:`-gnatws` does not suppress
  warnings from the ``gcc`` back end.
  To suppress these back end warnings as well, use the switch :switch:`-w`
  in addition to :switch:`-gnatws`. Also this switch has no effect on the
  handling of style check messages.


.. index:: -gnatw.s  (gcc)
.. index:: Record Representation (component sizes)

:switch:`-gnatw.s`
  *Activate warnings on overridden size clauses.*

  This switch activates warnings on component clauses in record
  representation clauses where the length given overrides that
  specified by an explicit size clause for the component type. A
  warning is similarly given in the array case if a specified
  component size overrides an explicit size clause for the array
  component type.


.. index:: -gnatw.S  (gcc)

:switch:`-gnatw.S`
  *Suppress warnings on overridden size clauses.*

  This switch suppresses warnings on component clauses in record
  representation clauses that override size clauses, and similar
  warnings when an array component size overrides a size clause.


.. index:: -gnatw_s  (gcc)
.. index:: Warnings

:switch:`-gnatw_s`
  *Activate warnings on ineffective predicate tests.*

  This switch activates warnings on Static_Predicate aspect
  specifications that test for values that do not belong to
  the parent subtype. Not all such ineffective tests are detected.

.. index:: -gnatw_S  (gcc)

:switch:`-gnatw_S`
  *Suppress warnings on ineffective predicate tests.*

  This switch suppresses warnings on Static_Predicate aspect
  specifications that test for values that do not belong to
  the parent subtype.

.. index:: -gnatwt  (gcc)
.. index:: Deactivated code, warnings
.. index:: Deleted code, warnings

:switch:`-gnatwt`
  *Activate warnings for tracking of deleted conditional code.*

  This switch activates warnings for tracking of code in conditionals (IF and
  CASE statements) that is detected to be dead code which cannot be executed, and
  which is removed by the front end. This warning is off by default. This may be
  useful for detecting deactivated code in certified applications.


.. index:: -gnatwT  (gcc)

:switch:`-gnatwT`
  *Suppress warnings for tracking of deleted conditional code.*

  This switch suppresses warnings for tracking of deleted conditional code.


.. index:: -gnatw.t  (gcc)

:switch:`-gnatw.t`
  *Activate warnings on suspicious contracts.*

  This switch activates warnings on suspicious contracts. This includes
  warnings on suspicious postconditions (whether a pragma ``Postcondition`` or a
  ``Post`` aspect in Ada 2012) and suspicious contract cases (pragma or aspect
  ``Contract_Cases``). A function postcondition or contract case is suspicious
  when no postcondition or contract case for this function mentions the result
  of the function.  A procedure postcondition or contract case is suspicious
  when it only refers to the pre-state of the procedure, because in that case
  it should rather be expressed as a precondition. This switch also controls
  warnings on suspicious cases of expressions typically found in contracts like
  quantified expressions and uses of Update attribute. The default is that such
  warnings are generated.


.. index:: -gnatw.T  (gcc)

:switch:`-gnatw.T`
  *Suppress warnings on suspicious contracts.*

  This switch suppresses warnings on suspicious contracts.


.. index:: -gnatwu  (gcc)

:switch:`-gnatwu`
  *Activate warnings on unused entities.*

  This switch activates warnings to be generated for entities that
  are declared but not referenced, and for units that are |withed|
  and not
  referenced. In the case of packages, a warning is also generated if
  no entities in the package are referenced. This means that if a with'ed
  package is referenced but the only references are in ``use``
  clauses or ``renames``
  declarations, a warning is still generated. A warning is also generated
  for a generic package that is |withed| but never instantiated.
  In the case where a package or subprogram body is compiled, and there
  is a |with| on the corresponding spec
  that is only referenced in the body,
  a warning is also generated, noting that the
  |with| can be moved to the body. The default is that
  such warnings are not generated.
  This switch also activates warnings on unreferenced formals
  (it includes the effect of :switch:`-gnatwf`).


.. index:: -gnatwU  (gcc)

:switch:`-gnatwU`
  *Suppress warnings on unused entities.*

  This switch suppresses warnings for unused entities and packages.
  It also turns off warnings on unreferenced formals (and thus includes
  the effect of :switch:`-gnatwF`).


.. index:: -gnatw.u  (gcc)

:switch:`-gnatw.u`
  *Activate warnings on unordered enumeration types.*

  This switch causes enumeration types to be considered as conceptually
  unordered, unless an explicit pragma ``Ordered`` is given for the type.
  The effect is to generate warnings in clients that use explicit comparisons
  or subranges, since these constructs both treat objects of the type as
  ordered. (A *client* is defined as a unit that is other than the unit in
  which the type is declared, or its body or subunits.) Please refer to
  the description of pragma ``Ordered`` in the
  :title:`GNAT Reference Manual` for further details.
  The default is that such warnings are not generated.


.. index:: -gnatw.U  (gcc)

:switch:`-gnatw.U`
  *Deactivate warnings on unordered enumeration types.*

  This switch causes all enumeration types to be considered as ordered, so
  that no warnings are given for comparisons or subranges for any type.


.. index:: -gnatwv  (gcc)
.. index:: Unassigned variable warnings

:switch:`-gnatwv`
  *Activate warnings on unassigned variables.*

  This switch activates warnings for access to variables which
  may not be properly initialized. The default is that
  such warnings are generated. This switch will also be emitted when
  initializing an array or record object via the following aggregate:

  .. code-block:: ada

       Array_Or_Record : XXX := (others => <>);

  unless the relevant type fully initializes all components.

.. index:: -gnatwV  (gcc)

:switch:`-gnatwV`
  *Suppress warnings on unassigned variables.*

  This switch suppresses warnings for access to variables which
  may not be properly initialized.


.. index:: -gnatw.v  (gcc)
.. index:: bit order warnings

:switch:`-gnatw.v`
  *Activate warnings for non-default bit order.*

  This switch activates warning messages about the effects of non-default
  bit-order on records to which a component clause is applied. The effect of
  specifying non-default bit ordering is a bit subtle
  (and changed with Ada 2005), so these messages, which are given by default,
  are useful in understanding the exact consequences of using this feature.


.. index:: -gnatw.V  (gcc)

:switch:`-gnatw.V`
  *Suppress warnings for non-default bit order.*

  This switch suppresses warnings for the effects of specifying
  non-default bit order on record components with component clauses.


.. index:: -gnatww  (gcc)
.. index:: String indexing warnings

:switch:`-gnatww`
  *Activate warnings on wrong low bound assumption.*

  This switch activates warnings for indexing an unconstrained string parameter
  with a literal or S'Length. This is a case where the code is assuming that the
  low bound is one, which is in general not true (for example when a slice is
  passed). The default is that such warnings are generated.


.. index:: -gnatwW  (gcc)

:switch:`-gnatwW`
  *Suppress warnings on wrong low bound assumption.*

  This switch suppresses warnings for indexing an unconstrained string parameter
  with a literal or S'Length. Note that this warning can also be suppressed
  in a particular case by adding an assertion that the lower bound is 1,
  as shown in the following example:

  .. code-block:: ada

       procedure K (S : String) is
          pragma Assert (S'First = 1);
          ...


.. index:: -gnatw.w  (gcc)
.. index:: Warnings Off control

:switch:`-gnatw.w`
  *Activate warnings on Warnings Off pragmas.*

  This switch activates warnings for use of ``pragma Warnings (Off, entity)``
  where either the pragma is entirely useless (because it suppresses no
  warnings), or it could be replaced by ``pragma Unreferenced`` or
  ``pragma Unmodified``.
  Also activates warnings for the case of
  Warnings (Off, String), where either there is no matching
  Warnings (On, String), or the Warnings (Off) did not suppress any warning.
  The default is that these warnings are not given.


.. index:: -gnatw.W  (gcc)

:switch:`-gnatw.W`
  *Suppress warnings on unnecessary Warnings Off pragmas.*

  This switch suppresses warnings for use of ``pragma Warnings (Off, ...)``.


.. index:: -gnatwx  (gcc)
.. index:: Export/Import pragma warnings

:switch:`-gnatwx`
  *Activate warnings on Export/Import pragmas.*

  This switch activates warnings on Export/Import pragmas when
  the compiler detects a possible conflict between the Ada and
  foreign language calling sequences. For example, the use of
  default parameters in a convention C procedure is dubious
  because the C compiler cannot supply the proper default, so
  a warning is issued. The default is that such warnings are
  generated.


.. index:: -gnatwX  (gcc)

:switch:`-gnatwX`
  *Suppress warnings on Export/Import pragmas.*

  This switch suppresses warnings on Export/Import pragmas.
  The sense of this is that you are telling the compiler that
  you know what you are doing in writing the pragma, and it
  should not complain at you.


.. index:: -gnatw.x  (gcc)

:switch:`-gnatw.x`
  *Activate warnings for No_Exception_Propagation mode.*

  This switch activates warnings for exception usage when pragma Restrictions
  (No_Exception_Propagation) is in effect. Warnings are given for implicit or
  explicit exception raises which are not covered by a local handler, and for
  exception handlers which do not cover a local raise. The default is that
  these warnings are given for units that contain exception handlers.


:switch:`-gnatw.X`
  *Disable warnings for No_Exception_Propagation mode.*

  This switch disables warnings for exception usage when pragma Restrictions
  (No_Exception_Propagation) is in effect.


.. index:: -gnatwy  (gcc)
.. index:: Ada compatibility issues warnings

:switch:`-gnatwy`
  *Activate warnings for Ada compatibility issues.*

  For the most part, newer versions of Ada are upwards compatible
  with older versions. For example, Ada 2005 programs will almost
  always work when compiled as Ada 2012.
  However there are some exceptions (for example the fact that
  ``some`` is now a reserved word in Ada 2012). This
  switch activates several warnings to help in identifying
  and correcting such incompatibilities. The default is that
  these warnings are generated. Note that at one point Ada 2005
  was called Ada 0Y, hence the choice of character.


.. index:: -gnatwY  (gcc)
.. index:: Ada compatibility issues warnings

:switch:`-gnatwY`
  *Disable warnings for Ada compatibility issues.*

  This switch suppresses the warnings intended to help in identifying
  incompatibilities between Ada language versions.


.. index:: -gnatw.y  (gcc)
.. index:: Package spec needing body

:switch:`-gnatw.y`
  *Activate information messages for why package spec needs body.*

  There are a number of cases in which a package spec needs a body.
  For example, the use of pragma Elaborate_Body, or the declaration
  of a procedure specification requiring a completion. This switch
  causes information messages to be output showing why a package
  specification requires a body. This can be useful in the case of
  a large package specification which is unexpectedly requiring a
  body. The default is that such information messages are not output.


.. index:: -gnatw.Y  (gcc)
.. index:: No information messages for why package spec needs body

:switch:`-gnatw.Y`
  *Disable information messages for why package spec needs body.*

  This switch suppresses the output of information messages showing why
  a package specification needs a body.


.. index:: -gnatwz  (gcc)
.. index:: Unchecked_Conversion warnings

:switch:`-gnatwz`
  *Activate warnings on unchecked conversions.*

  This switch activates warnings for unchecked conversions
  where the types are known at compile time to have different
  sizes. The default is that such warnings are generated. Warnings are also
  generated for subprogram pointers with different conventions.


.. index:: -gnatwZ  (gcc)

:switch:`-gnatwZ`
  *Suppress warnings on unchecked conversions.*

  This switch suppresses warnings for unchecked conversions
  where the types are known at compile time to have different
  sizes or conventions.


.. index:: -gnatw.z  (gcc)
.. index:: Size/Alignment warnings

:switch:`-gnatw.z`
  *Activate warnings for size not a multiple of alignment.*

  This switch activates warnings for cases of array and record types
  with specified ``Size`` and ``Alignment`` attributes where the
  size is not a multiple of the alignment, resulting in an object
  size that is greater than the specified size. The default
  is that such warnings are generated.


.. index:: -gnatw.Z  (gcc)
.. index:: Size/Alignment warnings

:switch:`-gnatw.Z`
  *Suppress warnings for size not a multiple of alignment.*

  This switch suppresses warnings for cases of array and record types
  with specified ``Size`` and ``Alignment`` attributes where the
  size is not a multiple of the alignment, resulting in an object
  size that is greater than the specified size. The warning can also
  be suppressed by giving an explicit ``Object_Size`` value.


.. index:: -Wunused (gcc)

:switch:`-Wunused`
  The warnings controlled by the :switch:`-gnatw` switch are generated by
  the front end of the compiler. The GCC back end can provide
  additional warnings and they are controlled by the :switch:`-W` switch.
  For example, :switch:`-Wunused` activates back end
  warnings for entities that are declared but not referenced.


.. index:: -Wuninitialized (gcc)

:switch:`-Wuninitialized`
  Similarly, :switch:`-Wuninitialized` activates
  the back end warning for uninitialized variables. This switch must be
  used in conjunction with an optimization level greater than zero.


.. index:: -Wstack-usage (gcc)

:switch:`-Wstack-usage={len}`
  Warn if the stack usage of a subprogram might be larger than ``len`` bytes.
  See :ref:`Static_Stack_Usage_Analysis` for details.


.. index:: -Wall (gcc)

:switch:`-Wall`
  This switch enables most warnings from the GCC back end.
  The code generator detects a number of warning situations that are missed
  by the GNAT front end, and this switch can be used to activate them.
  The use of this switch also sets the default front-end warning mode to
  :switch:`-gnatwa`, that is, most front-end warnings are activated as well.


.. index:: -w (gcc)

:switch:`-w`
  Conversely, this switch suppresses warnings from the GCC back end.
  The use of this switch also sets the default front-end warning mode to
  :switch:`-gnatws`, that is, front-end warnings are suppressed as well.


.. index:: -Werror (gcc)

:switch:`-Werror`
  This switch causes warnings from the GCC back end to be treated as
  errors.  The warning string still appears, but the warning messages are
  counted as errors, and prevent the generation of an object file.
  The use of this switch also sets the default front-end warning mode to
  :switch:`-gnatwe`, that is, front-end warning messages and style check
  messages are treated as errors as well.


A string of warning parameters can be used in the same parameter. For example::

  -gnatwaGe


will turn on all optional warnings except for unrecognized pragma warnings,
and also specify that warnings should be treated as errors.

When no switch :switch:`-gnatw` is used, this is equivalent to:

  * :switch:`-gnatw.a`

  * :switch:`-gnatwB`

  * :switch:`-gnatw.b`

  * :switch:`-gnatwC`

  * :switch:`-gnatw.C`

  * :switch:`-gnatwD`

  * :switch:`-gnatw.D`

  * :switch:`-gnatwF`

  * :switch:`-gnatw.F`

  * :switch:`-gnatwg`

  * :switch:`-gnatwH`

  * :switch:`-gnatw.H`

  * :switch:`-gnatwi`

  * :switch:`-gnatwJ`

  * :switch:`-gnatw.J`

  * :switch:`-gnatwK`

  * :switch:`-gnatw.K`

  * :switch:`-gnatwL`

  * :switch:`-gnatw.L`

  * :switch:`-gnatwM`

  * :switch:`-gnatw.m`

  * :switch:`-gnatwn`

  * :switch:`-gnatw.N`

  * :switch:`-gnatwo`

  * :switch:`-gnatw.O`

  * :switch:`-gnatwP`

  * :switch:`-gnatw.P`

  * :switch:`-gnatwq`

  * :switch:`-gnatw.Q`

  * :switch:`-gnatwR`

  * :switch:`-gnatw.R`

  * :switch:`-gnatw.S`

  * :switch:`-gnatwT`

  * :switch:`-gnatw.t`

  * :switch:`-gnatwU`

  * :switch:`-gnatw.U`

  * :switch:`-gnatwv`

  * :switch:`-gnatw.v`

  * :switch:`-gnatww`

  * :switch:`-gnatw.W`

  * :switch:`-gnatwx`

  * :switch:`-gnatw.X`

  * :switch:`-gnatwy`

  * :switch:`-gnatw.Y`

  * :switch:`-gnatwz`

  * :switch:`-gnatw.z`

.. _Debugging_and_Assertion_Control:



Info message Control
--------------------

In addition to the warning messages, the compiler can also generate info
messages. In order to control the generation of these messages, the following
switch is provided:

:switch:`-gnatis`
  *Suppress all info messages.*

  This switch completely suppresses the output of all info messages from the
  GNAT front end.



Debugging and Assertion Control
-------------------------------



.. index:: -gnata  (gcc)

:switch:`-gnata`
  .. index:: Assert
  .. index:: Debug
  .. index:: Assertions
  .. index:: Precondition
  .. index:: Postcondition
  .. index:: Type invariants
  .. index:: Subtype predicates

  The :switch:`-gnata` option is equivalent to the following ``Assertion_Policy`` pragma::

       pragma Assertion_Policy (Check);

  Which is a shorthand for::

       pragma Assertion_Policy
       --  Ada RM assertion pragmas
         (Assert                    => Check,
          Static_Predicate          => Check,
          Dynamic_Predicate         => Check,
          Pre                       => Check,
          Pre'Class                 => Check,
          Post                      => Check,
          Post'Class                => Check,
          Type_Invariant            => Check,
          Type_Invariant'Class      => Check,
          Default_Initial_Condition => Check,
       --  GNAT specific assertion pragmas
          Assert_And_Cut            => Check,
          Assume                    => Check,
          Contract_Cases            => Check,
          Debug                     => Check,
          Ghost                     => Check,
          Initial_Condition         => Check,
          Loop_Invariant            => Check,
          Loop_Variant              => Check,
          Postcondition             => Check,
          Precondition              => Check,
          Predicate                 => Check,
          Refined_Post              => Check,
          Subprogram_Variant        => Check);

  The pragmas ``Assert`` and ``Debug`` normally have no effect and
  are ignored. This switch, where ``a`` stands for 'assert', causes
  pragmas ``Assert`` and ``Debug`` to be activated. This switch also
  causes preconditions, postconditions, subtype predicates, and
  type invariants to be activated.

  The pragmas have the form::

       pragma Assert (<Boolean-expression> [, <static-string-expression>])
       pragma Debug (<procedure call>)
       pragma Type_Invariant (<type-local-name>, <Boolean-expression>)
       pragma Predicate (<type-local-name>, <Boolean-expression>)
       pragma Precondition (<Boolean-expression>, <string-expression>)
       pragma Postcondition (<Boolean-expression>, <string-expression>)

  The aspects have the form::

       with [Pre|Post|Type_Invariant|Dynamic_Predicate|Static_Predicate]
         => <Boolean-expression>;

  The ``Assert`` pragma causes ``Boolean-expression`` to be tested.
  If the result is ``True``, the pragma has no effect (other than
  possible side effects from evaluating the expression). If the result is
  ``False``, the exception ``Assert_Failure`` declared in the package
  ``System.Assertions`` is raised (passing ``static-string-expression``, if
  present, as the message associated with the exception). If no string
  expression is given, the default is a string containing the file name and
  line number of the pragma.

  The ``Debug`` pragma causes ``procedure`` to be called. Note that
  ``pragma Debug`` may appear within a declaration sequence, allowing
  debugging procedures to be called between declarations.

  For the aspect specification, the ``Boolean-expression`` is evaluated.
  If the result is ``True``, the aspect has no effect. If the result
  is ``False``, the exception ``Assert_Failure`` is raised.

.. _Validity_Checking:

Validity Checking
-----------------

.. index:: Validity Checking

The Ada Reference Manual defines the concept of invalid values (see
RM 13.9.1). The primary source of invalid values is uninitialized
variables. A scalar variable that is left uninitialized may contain
an invalid value; the concept of invalid does not apply to access or
composite types.

It is an error to read an invalid value, but the RM does not require
run-time checks to detect such errors, except for some minimal
checking to prevent erroneous execution (i.e. unpredictable
behavior). This corresponds to the :switch:`-gnatVd` switch below,
which is the default. For example, by default, if the expression of a
case statement is invalid, it will raise Constraint_Error rather than
causing a wild jump, and if an array index on the left-hand side of an
assignment is invalid, it will raise Constraint_Error rather than
overwriting an arbitrary memory location.

The :switch:`-gnatVa` may be used to enable additional validity checks,
which are not required by the RM. These checks are often very
expensive (which is why the RM does not require them). These checks
are useful in tracking down uninitialized variables, but they are
not usually recommended for production builds, and in particular
we do not recommend using these extra validity checking options in
combination with optimization, since this can confuse the optimizer.
If performance is a consideration, leading to the need to optimize,
then the validity checking options should not be used.

The other :switch:`-gnatV{x}` switches below allow finer-grained
control; you can enable whichever validity checks you desire. However,
for most debugging purposes, :switch:`-gnatVa` is sufficient, and the
default :switch:`-gnatVd` (i.e. standard Ada behavior) is usually
sufficient for non-debugging use.

The :switch:`-gnatB` switch tells the compiler to assume that all
values are valid (that is, within their declared subtype range)
except in the context of a use of the Valid attribute. This means
the compiler can generate more efficient code, since the range
of values is better known at compile time. However, an uninitialized
variable can cause wild jumps and memory corruption in this mode.

The :switch:`-gnatV{x}` switch allows control over the validity
checking mode as described below.
The ``x`` argument is a string of letters that
indicate validity checks that are performed or not performed in addition
to the default checks required by Ada as described above.


.. index:: -gnatVa  (gcc)

:switch:`-gnatVa`
  *All validity checks.*

  All validity checks are turned on.
  That is, :switch:`-gnatVa` is
  equivalent to ``gnatVcdefimoprst``.


.. index:: -gnatVc  (gcc)

:switch:`-gnatVc`
  *Validity checks for copies.*

  The right-hand side of assignments, and the (explicit) initializing values
  of object declarations are validity checked.


.. index:: -gnatVd  (gcc)

:switch:`-gnatVd`
  *Default (RM) validity checks.*

  Some validity checks are required by Ada (see RM 13.9.1 (9-11)); these
  (and only these) validity checks are enabled by default.
  For case statements (and case expressions) that lack a "when others =>"
  choice, a check is made that the value of the selector expression
  belongs to its nominal subtype. If it does not, Constraint_Error is raised.
  For assignments to array components (and for indexed components in some
  other contexts), a check is made that each index expression belongs to the
  corresponding index subtype. If it does not, Constraint_Error is raised.
  Both these validity checks may be turned off using switch :switch:`-gnatVD`.
  They are turned on by default. If :switch:`-gnatVD` is specified, a subsequent
  switch :switch:`-gnatVd` will leave the checks turned on.
  Switch :switch:`-gnatVD` should be used only if you are sure that all such
  expressions have valid values. If you use this switch and invalid values
  are present, then the program is erroneous, and wild jumps or memory
  overwriting may occur.


.. index:: -gnatVe  (gcc)

:switch:`-gnatVe`
  *Validity checks for scalar components.*

  In the absence of this switch, assignments to scalar components of
  enclosing record or array objects are not validity checked, even if
  validity checks for assignments generally (:switch:`-gnatVc`) are turned on.
  Specifying this switch enables such checks.
  This switch has no effect if the :switch:`-gnatVc` switch is not specified.

.. index:: -gnatVf  (gcc)

:switch:`-gnatVf`
  *Validity checks for floating-point values.*

  Specifying this switch enables validity checking for floating-point
  values in the same contexts where validity checking is enabled for
  other scalar values.
  In the absence of this switch, validity checking is not performed for
  floating-point values. This takes precedence over other statements about
  performing validity checking for scalar objects in various scenarios.
  One way to look at it is that if this switch is not set, then whenever
  any of the other rules in this section use the word "scalar" they
  really mean "scalar and not floating-point".
  If :switch:`-gnatVf` is specified, then validity checking also applies
  for floating-point values, and NaNs and infinities are considered invalid,
  as well as out-of-range values for constrained types. The exact contexts
  in which floating-point values are checked depends on the setting of other
  options. For example, :switch:`-gnatVif` or :switch:`-gnatVfi`
  (the order does not matter) specifies that floating-point parameters of mode
  ``in`` should be validity checked.


.. index:: -gnatVi  (gcc)

:switch:`-gnatVi`
  *Validity checks for ``in`` mode parameters.*

  Arguments for parameters of mode ``in`` are validity checked in function
  and procedure calls at the point of call.


.. index:: -gnatVm  (gcc)

:switch:`-gnatVm`
  *Validity checks for ``in out`` mode parameters.*

  Arguments for parameters of mode ``in out`` are validity checked in
  procedure calls at the point of call. The ``'m'`` here stands for
  modify, since this concerns parameters that can be modified by the call.
  Note that there is no specific option to test ``out`` parameters,
  but any reference within the subprogram will be tested in the usual
  manner, and if an invalid value is copied back, any reference to it
  will be subject to validity checking.


.. index:: -gnatVn  (gcc)

:switch:`-gnatVn`
  *No validity checks.*

  This switch turns off all validity checking, including the default checking
  for case statements and left hand side subscripts. Note that the use of
  the switch :switch:`-gnatp` suppresses all run-time checks, including
  validity checks, and thus implies :switch:`-gnatVn`. When this switch
  is used, it cancels any other :switch:`-gnatV` previously issued.


.. index:: -gnatVo  (gcc)

:switch:`-gnatVo`
  *Validity checks for operator and attribute operands.*

  Scalar arguments for predefined operators and for attributes are
  validity checked.
  This includes all operators in package ``Standard``,
  the shift operators defined as intrinsic in package ``Interfaces``
  and operands for attributes such as ``Pos``. Checks are also made
  on individual component values for composite comparisons, and on the
  expressions in type conversions and qualified expressions. Checks are
  also made on explicit ranges using :samp:`..` (e.g., slices, loops etc).


.. index:: -gnatVp  (gcc)

:switch:`-gnatVp`
  *Validity checks for parameters.*

  This controls the treatment of formal parameters within a subprogram (as
  opposed to :switch:`-gnatVi` and :switch:`-gnatVm`, which control validity
  testing of actual parameters of a call). If either of these call options is
  specified, then normally an assumption is made within a subprogram that
  the validity of any incoming formal parameters of the corresponding mode(s)
  has already been checked at the point of call and does not need rechecking.
  If :switch:`-gnatVp` is set, then this assumption is not made and so their
  validity may be checked (or rechecked) within the subprogram. If neither of
  the two call-related options is specified, then this switch has no effect.

.. index:: -gnatVr  (gcc)

:switch:`-gnatVr`
  *Validity checks for function returns.*

  The expression in simple ``return`` statements in functions is validity
  checked.


.. index:: -gnatVs  (gcc)

:switch:`-gnatVs`
  *Validity checks for subscripts.*

  All subscript expressions are checked for validity, whatever context
  they occur in (in default mode some subscripts are not validity checked;
  for example, validity checking may be omitted in some cases involving
  a read of a component of an array).


.. index:: -gnatVt  (gcc)

:switch:`-gnatVt`
  *Validity checks for tests.*

  Expressions used as conditions in ``if``, ``while`` or ``exit``
  statements are checked, as well as guard expressions in entry calls.


The :switch:`-gnatV` switch may be followed by a string of letters
to turn on a series of validity checking options.
For example, :switch:`-gnatVcr`
specifies that in addition to the default validity checking, copies and
function return expressions are to be validity checked.
In order to make it easier to specify the desired combination of effects,
the upper case letters ``CDFIMORST`` may
be used to turn off the corresponding lower case option.
Thus :switch:`-gnatVaM` turns on all validity checking options except for
checking of ``in out`` parameters.

The specification of additional validity checking generates extra code (and
in the case of :switch:`-gnatVa` the code expansion can be substantial).
However, these additional checks can be very useful in detecting
uninitialized variables, incorrect use of unchecked conversion, and other
errors leading to invalid values. The use of pragma ``Initialize_Scalars``
is useful in conjunction with the extra validity checking, since this
ensures that wherever possible uninitialized variables have invalid values.

See also the pragma ``Validity_Checks`` which allows modification of
the validity checking mode at the program source level, and also allows for
temporary disabling of validity checks.

.. _Style_Checking:

Style Checking
--------------

.. index:: Style checking

.. index:: -gnaty  (gcc)

The :switch:`-gnaty` switch causes the compiler to
enforce specified style rules. A limited set of style rules has been used
in writing the GNAT sources themselves. This switch allows user programs
to activate all or some of these checks. If the source program fails a
specified style check, an appropriate message is given, preceded by
the character sequence '(style)'. This message does not prevent
successful compilation (unless the :switch:`-gnatwe` switch is used).

Note that this is by no means intended to be a general facility for
checking arbitrary coding standards. It is simply an embedding of the
style rules we have chosen for the GNAT sources. If you are starting
a project which does not have established style standards, you may
find it useful to adopt the entire set of GNAT coding standards, or
some subset of them.

.. only:: PRO or GPL

  If you already have an established set of coding
  standards, then the selected style checking options may
  indeed correspond to choices you have made, but for general checking
  of an existing set of coding rules, you should look to the gnatcheck
  tool, which is designed for that purpose.

The string ``x`` is a sequence of letters or digits
indicating the particular style
checks to be performed. The following checks are defined:


.. index:: -gnaty[0-9]   (gcc)

:switch:`-gnaty0`
  *Specify indentation level.*

  If a digit from 1-9 appears
  in the string after :switch:`-gnaty`
  then proper indentation is checked, with the digit indicating the
  indentation level required. A value of zero turns off this style check.
  The rule checks that the following constructs start on a column that is
  one plus a multiple of the alignment level:

  * beginnings of declarations (except record component declarations)
    and statements;

  * beginnings of the structural components of compound statements;

  * ``end`` keyword that completes the declaration of a program unit declaration
    or body or that completes a compound statement.

  Full line comments must be
  aligned with the ``--`` starting on a column that is one plus a multiple of
  the alignment level, or they may be aligned the same way as the following
  non-blank line (this is useful when full line comments appear in the middle
  of a statement), or they may be aligned with the source line on the previous
  non-blank line.

.. index:: -gnatya   (gcc)

:switch:`-gnatya`
  *Check attribute casing.*

  Attribute names, including the case of keywords such as ``digits``
  used as attributes names, must be written in mixed case, that is, the
  initial letter and any letter following an underscore must be uppercase.
  All other letters must be lowercase.


.. index:: -gnatyA (gcc)

:switch:`-gnatyA`
  *Use of array index numbers in array attributes.*

  When using the array attributes First, Last, Range,
  or Length, the index number must be omitted for one-dimensional arrays
  and is required for multi-dimensional arrays.


.. index:: -gnatyb (gcc)

:switch:`-gnatyb`
  *Blanks not allowed at statement end.*

  Trailing blanks are not allowed at the end of statements. The purpose of this
  rule, together with h (no horizontal tabs), is to enforce a canonical format
  for the use of blanks to separate source tokens.


.. index:: -gnatyB (gcc)

:switch:`-gnatyB`
  *Check Boolean operators.*

  The use of AND/OR operators is not permitted except in the cases of modular
  operands, array operands, and simple stand-alone boolean variables or
  boolean constants. In all other cases ``and then``/`or else` are
  required.


.. index:: -gnatyc (gcc)

:switch:`-gnatyc`
  *Check comments, double space.*

  Comments must meet the following set of rules:

  * The ``--`` that starts the column must either start in column one,
    or else at least one blank must precede this sequence.

  * Comments that follow other tokens on a line must have at least one blank
    following the ``--`` at the start of the comment.

  * Full line comments must have at least two blanks following the
    ``--`` that starts the comment, with the following exceptions.

  * A line consisting only of the ``--`` characters, possibly preceded
    by blanks is permitted.

  * A comment starting with ``--x`` where ``x`` is a special character
    is permitted.
    This allows proper processing of the output from specialized tools
    such as ``gnatprep`` (where ``--!`` is used) and in earlier versions of the SPARK
    annotation
    language (where ``--#`` is used). For the purposes of this rule, a
    special character is defined as being in one of the ASCII ranges
    ``16#21#...16#2F#`` or ``16#3A#...16#3F#``.
    Note that this usage is not permitted
    in GNAT implementation units (i.e., when :switch:`-gnatg` is used).

  * A line consisting entirely of minus signs, possibly preceded by blanks, is
    permitted. This allows the construction of box comments where lines of minus
    signs are used to form the top and bottom of the box.

  * A comment that starts and ends with ``--`` is permitted as long as at
    least one blank follows the initial ``--``. Together with the preceding
    rule, this allows the construction of box comments, as shown in the following
    example:

    .. code-block:: ada

       ---------------------------
       -- This is a box comment --
       -- with two text lines.  --
       ---------------------------


.. index:: -gnatyC (gcc)

:switch:`-gnatyC`
  *Check comments, single space.*

  This is identical to ``c`` except that only one space
  is required following the ``--`` of a comment instead of two.


.. index:: -gnatyd (gcc)

:switch:`-gnatyd`
  *Check no DOS line terminators present.*

  All lines must be terminated by a single ASCII.LF
  character (in particular the DOS line terminator sequence CR/LF is not
  allowed).


.. index:: -gnatyD (gcc)

:switch:`-gnatyD`
  *Check declared identifiers in mixed case.*

  Declared identifiers must be in mixed case, as in
  This_Is_An_Identifier. Use -gnatyr in addition to ensure
  that references match declarations.


.. index:: -gnatye (gcc)

:switch:`-gnatye`
  *Check end/exit labels.*

  Optional labels on ``end`` statements ending subprograms and on
  ``exit`` statements exiting named loops, are required to be present.


.. index:: -gnatyf (gcc)

:switch:`-gnatyf`
  *No form feeds or vertical tabs.*

  Neither form feeds nor vertical tab characters are permitted
  in the source text.


.. index:: -gnatyg (gcc)

:switch:`-gnatyg`
  *GNAT style mode.*

  The set of style check switches is set to match that used by the GNAT sources.
  This may be useful when developing code that is eventually intended to be
  incorporated into GNAT. Currently this is equivalent to
  :switch:`-gnatyydISuxz`) but additional style switches may be added to this
  set in the future without advance notice.


.. index:: -gnatyh (gcc)

:switch:`-gnatyh`
  *No horizontal tabs.*

  Horizontal tab characters are not permitted in the source text.
  Together with the b (no blanks at end of line) check, this
  enforces a canonical form for the use of blanks to separate
  source tokens.


.. index:: -gnatyi (gcc)

:switch:`-gnatyi`
  *Check if-then layout.*

  The keyword ``then`` must appear either on the same
  line as corresponding ``if``, or on a line on its own, lined
  up under the ``if``.


.. index:: -gnatyI (gcc)

:switch:`-gnatyI`
  *check mode IN keywords.*

  Mode ``in`` (the default mode) is not
  allowed to be given explicitly. ``in out`` is fine,
  but not ``in`` on its own.


.. index:: -gnatyk (gcc)

:switch:`-gnatyk`
  *Check keyword casing.*

  All keywords must be in lower case (with the exception of keywords
  such as ``digits`` used as attribute names to which this check
  does not apply). A single error is reported for each line breaking
  this rule even if multiple casing issues exist on a same line.


.. index:: -gnatyl (gcc)

:switch:`-gnatyl`
  *Check layout.*

  Layout of statement and declaration constructs must follow the
  recommendations in the Ada Reference Manual, as indicated by the
  form of the syntax rules. For example an ``else`` keyword must
  be lined up with the corresponding ``if`` keyword.

  There are two respects in which the style rule enforced by this check
  option are more liberal than those in the Ada Reference Manual. First
  in the case of record declarations, it is permissible to put the
  ``record`` keyword on the same line as the ``type`` keyword, and
  then the ``end`` in ``end record`` must line up under ``type``.
  This is also permitted when the type declaration is split on two lines.
  For example, any of the following three layouts is acceptable:

  .. code-block:: ada

    type q is record
       a : integer;
       b : integer;
    end record;

    type q is
       record
          a : integer;
          b : integer;
       end record;

    type q is
       record
          a : integer;
          b : integer;
    end record;

  Second, in the case of a block statement, a permitted alternative
  is to put the block label on the same line as the ``declare`` or
  ``begin`` keyword, and then line the ``end`` keyword up under
  the block label. For example both the following are permitted:

  .. code-block:: ada

    Block : declare
       A : Integer := 3;
    begin
       Proc (A, A);
    end Block;

    Block :
       declare
          A : Integer := 3;
       begin
          Proc (A, A);
       end Block;

  The same alternative format is allowed for loops. For example, both of
  the following are permitted:

  .. code-block:: ada

    Clear : while J < 10 loop
       A (J) := 0;
    end loop Clear;

    Clear :
       while J < 10 loop
          A (J) := 0;
       end loop Clear;


.. index:: -gnatyLnnn (gcc)

:switch:`-gnatyL`
  *Set maximum nesting level.*

  The maximum level of nesting of constructs (including subprograms, loops,
  blocks, packages, and conditionals) may not exceed the given value
  *nnn*. A value of zero disconnects this style check.


.. index:: -gnatym (gcc)

:switch:`-gnatym`
  *Check maximum line length.*

  The length of source lines must not exceed 79 characters, including
  any trailing blanks. The value of 79 allows convenient display on an
  80 character wide device or window, allowing for possible special
  treatment of 80 character lines. Note that this count is of
  characters in the source text. This means that a tab character counts
  as one character in this count and a wide character sequence counts as
  a single character (however many bytes are needed in the encoding).


.. index:: -gnatyMnnn (gcc)

:switch:`-gnatyM`
  *Set maximum line length.*

  The length of lines must not exceed the
  given value *nnn*. The maximum value that can be specified is 32767.
  If neither style option for setting the line length is used, then the
  default is 255. This also controls the maximum length of lexical elements,
  where the only restriction is that they must fit on a single line.


.. index:: -gnatyn (gcc)

:switch:`-gnatyn`
  *Check casing of entities in Standard.*

  Any identifier from Standard must be cased
  to match the presentation in the Ada Reference Manual (for example,
  ``Integer`` and ``ASCII.NUL``).


.. index:: -gnatyN (gcc)

:switch:`-gnatyN`
  *Turn off all style checks.*

  All style check options are turned off.


.. index:: -gnatyo (gcc)

:switch:`-gnatyo`
  *Check order of subprogram bodies.*

  All subprogram bodies in a given scope
  (e.g., a package body) must be in alphabetical order. The ordering
  rule uses normal Ada rules for comparing strings, ignoring casing
  of letters, except that if there is a trailing numeric suffix, then
  the value of this suffix is used in the ordering (e.g., Junk2 comes
  before Junk10).


.. index:: -gnatyO (gcc)

:switch:`-gnatyO`
  *Check that overriding subprograms are explicitly marked as such.*

  This applies to all subprograms of a derived type that override a primitive
  operation of the type, for both tagged and untagged types. In particular,
  the declaration of a primitive operation of a type extension that overrides
  an inherited operation must carry an overriding indicator. Another case is
  the declaration of a function that overrides a predefined operator (such
  as an equality operator).


.. index:: -gnatyp (gcc)

:switch:`-gnatyp`
  *Check pragma casing.*

  Pragma names must be written in mixed case, that is, the
  initial letter and any letter following an underscore must be uppercase.
  All other letters must be lowercase. An exception is that SPARK_Mode is
  allowed as an alternative for Spark_Mode.


.. index:: -gnatyr (gcc)

:switch:`-gnatyr`
  *Check references.*

  All identifier references must be cased in the same way as the
  corresponding declaration. No specific casing style is imposed on
  identifiers. The only requirement is for consistency of references
  with declarations.


.. index:: -gnatys (gcc)

:switch:`-gnatys`
  *Check separate specs.*

  Separate declarations ('specs') are required for subprograms (a
  body is not allowed to serve as its own declaration). The only
  exception is that parameterless library level procedures are
  not required to have a separate declaration. This exception covers
  the most frequent form of main program procedures.


.. index:: -gnatyS (gcc)

:switch:`-gnatyS`
  *Check no statements after then/else.*

  No statements are allowed
  on the same line as a ``then`` or ``else`` keyword following the
  keyword in an ``if`` statement. ``or else`` and ``and then`` are not
  affected, and a special exception allows a pragma to appear after ``else``.


.. index:: -gnatyt (gcc)

:switch:`-gnatyt`
  *Check token spacing.*

  The following token spacing rules are enforced:

  * The keywords ``abs`` and ``not`` must be followed by a space.

  * The token ``=>`` must be surrounded by spaces.

  * The token ``<>`` must be preceded by a space or a left parenthesis.

  * Binary operators other than ``**`` must be surrounded by spaces.
    There is no restriction on the layout of the ``**`` binary operator.

  * Colon must be surrounded by spaces.

  * Colon-equal (assignment, initialization) must be surrounded by spaces.

  * Comma must be the first non-blank character on the line, or be
    immediately preceded by a non-blank character, and must be followed
    by a space.

  * If the token preceding a left parenthesis ends with a letter or digit, then
    a space must separate the two tokens.

  * If the token following a right parenthesis starts with a letter or digit, then
    a space must separate the two tokens.

  * A right parenthesis must either be the first non-blank character on
    a line, or it must be preceded by a non-blank character.

  * A semicolon must not be preceded by a space, and must not be followed by
    a non-blank character.

  * A unary plus or minus may not be followed by a space.

  * A vertical bar must be surrounded by spaces.

  Exactly one blank (and no other white space) must appear between
  a ``not`` token and a following ``in`` token.


.. index:: -gnatyu (gcc)

:switch:`-gnatyu`
  *Check unnecessary blank lines.*

  Unnecessary blank lines are not allowed. A blank line is considered
  unnecessary if it appears at the end of the file, or if more than
  one blank line occurs in sequence.


.. index:: -gnatyx (gcc)

:switch:`-gnatyx`
  *Check extra parentheses.*

  Unnecessary extra levels of parentheses (C-style) are not allowed
  around conditions (or selection expressions) in ``if``, ``while``,
  ``case``, and ``exit`` statements, as well as part of ranges.


.. index:: -gnatyy (gcc)

:switch:`-gnatyy`
  *Set all standard style check options.*

  This is equivalent to ``gnaty3aAbcefhiklmnprst``, that is all checking
  options enabled with the exception of :switch:`-gnatyB`, :switch:`-gnatyd`,
  :switch:`-gnatyI`, :switch:`-gnatyLnnn`, :switch:`-gnatyo`, :switch:`-gnatyO`,
  :switch:`-gnatyS`, :switch:`-gnatyu`, and :switch:`-gnatyx`.


.. index:: -gnatyz (gcc)

:switch:`-gnatyz`
  *Check extra parentheses (operator precedence).*

  Extra levels of parentheses that are not required by operator precedence
  rules are flagged. See also ``-gnatyx``.


.. index:: -gnaty- (gcc)

:switch:`-gnaty-`
  *Remove style check options.*

  This causes any subsequent options in the string to act as canceling the
  corresponding style check option. To cancel maximum nesting level control,
  use the ``L`` parameter without any integer value after that, because any
  digit following *-* in the parameter string of the :switch:`-gnaty`
  option will be treated as canceling the indentation check. The same is true
  for the ``M`` parameter. ``y`` and ``N`` parameters are not
  allowed after *-*.


.. index:: -gnaty+ (gcc)

:switch:`-gnaty+`
  *Enable style check options.*

  This causes any subsequent options in the string to enable the corresponding
  style check option. That is, it cancels the effect of a previous -,
  if any.


.. end of switch description (leave this comment to ease automatic parsing for
.. GNAT Studio)

In the above rules, appearing in column one is always permitted, that is,
counts as meeting either a requirement for a required preceding space,
or as meeting a requirement for no preceding space.

Appearing at the end of a line is also always permitted, that is, counts
as meeting either a requirement for a following space, or as meeting
a requirement for no following space.

If any of these style rules is violated, a message is generated giving
details on the violation. The initial characters of such messages are
always '`(style)`'. Note that these messages are treated as warning
messages, so they normally do not prevent the generation of an object
file. The :switch:`-gnatwe` switch can be used to treat warning messages,
including style messages, as fatal errors.

The switch :switch:`-gnaty` on its own (that is not
followed by any letters or digits) is equivalent
to the use of :switch:`-gnatyy` as described above, that is all
built-in standard style check options are enabled.

The switch :switch:`-gnatyN` clears any previously set style checks.

.. _Run-Time_Checks:

Run-Time Checks
---------------

.. index:: Division by zero

.. index:: Access before elaboration

.. index:: Checks, division by zero

.. index:: Checks, access before elaboration

.. index:: Checks, stack overflow checking

By default, the following checks are suppressed: stack overflow
checks, and checks for access before elaboration on subprogram
calls. All other checks, including overflow checks, range checks and
array bounds checks, are turned on by default. The following ``gcc``
switches refine this default behavior.

.. index:: -gnatp  (gcc)

:switch:`-gnatp`
  .. index:: Suppressing checks

  .. index:: Checks, suppressing

  This switch causes the unit to be compiled
  as though ``pragma Suppress (All_checks)``
  had been present in the source. Validity checks are also eliminated (in
  other words :switch:`-gnatp` also implies :switch:`-gnatVn`.
  Use this switch to improve the performance
  of the code at the expense of safety in the presence of invalid data or
  program bugs.

  Note that when checks are suppressed, the compiler is allowed, but not
  required, to omit the checking code. If the run-time cost of the
  checking code is zero or near-zero, the compiler will generate it even
  if checks are suppressed. In particular, if the compiler can prove
  that a certain check will necessarily fail, it will generate code to
  do an unconditional 'raise', even if checks are suppressed. The
  compiler warns in this case. Another case in which checks may not be
  eliminated is when they are embedded in certain run-time routines such
  as math library routines.

  Of course, run-time checks are omitted whenever the compiler can prove
  that they will not fail, whether or not checks are suppressed.

  Note that if you suppress a check that would have failed, program
  execution is erroneous, which means the behavior is totally
  unpredictable. The program might crash, or print wrong answers, or
  do anything else. It might even do exactly what you wanted it to do
  (and then it might start failing mysteriously next week or next
  year). The compiler will generate code based on the assumption that
  the condition being checked is true, which can result in erroneous
  execution if that assumption is wrong.

  The checks subject to suppression include all the checks defined by the Ada
  standard, as well as all implementation-defined checks,
  including any checks introduced using ``pragma Check_Name``.

  If the code depends on certain checks being active, you can use
  pragma ``Unsuppress`` either as a configuration pragma or as
  a local pragma to make sure that a specified check is performed
  even if ``gnatp`` is specified.

  The :switch:`-gnatp` switch has no effect if a subsequent
  :switch:`-gnat-p` switch appears.


.. index:: -gnat-p  (gcc)
.. index:: Suppressing checks
.. index:: Checks, suppressing
.. index:: Suppress

:switch:`-gnat-p`
  This switch cancels the effect of a previous ``gnatp`` switch.


.. index:: -gnato??  (gcc)
.. index:: Overflow checks
.. index:: Overflow mode
.. index:: Check, overflow

:switch:`-gnato??`
  This switch controls the mode used for computing intermediate
  arithmetic integer operations, and also enables overflow checking.
  For a full description of overflow mode and checking control, see
  the :ref:`Overflow_Check_Handling_in_GNAT` appendix in this
  User's Guide.

.. index:: -gnatE  (gcc)
.. index:: Elaboration checks
.. index:: Check, elaboration

:switch:`-gnatE`
  Enables dynamic checks for access-before-elaboration
  on subprogram calls and generic instantiations.
  Note that :switch:`-gnatE` is not necessary for safety, because in the
  default mode, GNAT ensures statically that the checks would not fail.
  For full details of the effect and use of this switch,
  :ref:`Compiling_with_gcc`.


.. index:: -fstack-check  (gcc)
.. index:: Stack Overflow Checking
.. index:: Checks, stack overflow checking

:switch:`-fstack-check`
  Activates stack overflow checking. For full details of the effect and use of
  this switch see :ref:`Stack_Overflow_Checking`.

.. index:: Unsuppress

The setting of these switches only controls the default setting of the
checks. You may modify them using either ``Suppress`` (to remove
checks) or ``Unsuppress`` (to add back suppressed checks) pragmas in
the program source.


.. _Using_gcc_for_Syntax_Checking:

Using ``gcc`` for Syntax Checking
---------------------------------

.. index:: -gnats  (gcc)

:switch:`-gnats`
  The ``s`` stands for 'syntax'.

  Run GNAT in syntax checking only mode. For
  example, the command

  ::

    $ gcc -c -gnats x.adb

  compiles file :file:`x.adb` in syntax-check-only mode. You can check a
  series of files in a single command
  , and can use wildcards to specify such a group of files.
  Note that you must specify the :switch:`-c` (compile
  only) flag in addition to the :switch:`-gnats` flag.

  You may use other switches in conjunction with :switch:`-gnats`. In
  particular, :switch:`-gnatl` and :switch:`-gnatv` are useful to control the
  format of any generated error messages.

  When the source file is empty or contains only empty lines and/or comments,
  the output is a warning:


  ::

    $ gcc -c -gnats -x ada toto.txt
    toto.txt:1:01: warning: empty file, contains no compilation units
    $


  Otherwise, the output is simply the error messages, if any. No object file or
  ALI file is generated by a syntax-only compilation. Also, no units other
  than the one specified are accessed. For example, if a unit ``X``
  |withs| a unit ``Y``, compiling unit ``X`` in syntax
  check only mode does not access the source file containing unit
  ``Y``.

  .. index:: Multiple units, syntax checking

  Normally, GNAT allows only a single unit in a source file. However, this
  restriction does not apply in syntax-check-only mode, and it is possible
  to check a file containing multiple compilation units concatenated
  together. This is primarily used by the ``gnatchop`` utility
  (:ref:`Renaming_Files_with_gnatchop`).

.. _Using_gcc_for_Semantic_Checking:

Using ``gcc`` for Semantic Checking
-----------------------------------



.. index:: -gnatc  (gcc)

:switch:`-gnatc`
  The ``c`` stands for 'check'.
  Causes the compiler to operate in semantic check mode,
  with full checking for all illegalities specified in the
  Ada Reference Manual, but without generation of any object code
  (no object file is generated).

  Because dependent files must be accessed, you must follow the GNAT
  semantic restrictions on file structuring to operate in this mode:

  * The needed source files must be accessible
    (see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`).

  * Each file must contain only one compilation unit.

  * The file name and unit name must match (:ref:`File_Naming_Rules`).

  The output consists of error messages as appropriate. No object file is
  generated. An :file:`ALI` file is generated for use in the context of
  cross-reference tools, but this file is marked as not being suitable
  for binding (since no object file is generated).
  The checking corresponds exactly to the notion of
  legality in the Ada Reference Manual.

  Any unit can be compiled in semantics-checking-only mode, including
  units that would not normally be compiled (subunits,
  and specifications where a separate body is present).

.. _Compiling_Different_Versions_of_Ada:

Compiling Different Versions of Ada
-----------------------------------

The switches described in this section allow you to explicitly specify
the version of the Ada language that your programs are written in.
The default mode is Ada 2012,
but you can also specify Ada 95, Ada 2005 mode, or
indicate Ada 83 compatibility mode.


.. index:: Compatibility with Ada 83
.. index:: -gnat83  (gcc)
.. index:: ACVC, Ada 83 tests
.. index:: Ada 83 mode

:switch:`-gnat83` (Ada 83 Compatibility Mode)
  Although GNAT is primarily an Ada 95 / Ada 2005 compiler, this switch
  specifies that the program is to be compiled in Ada 83 mode. With
  :switch:`-gnat83`, GNAT rejects most post-Ada 83 extensions and applies Ada 83
  semantics where this can be done easily.
  It is not possible to guarantee this switch does a perfect
  job; some subtle tests, such as are
  found in earlier ACVC tests (and that have been removed from the ACATS suite
  for Ada 95), might not compile correctly.
  Nevertheless, this switch may be useful in some circumstances, for example
  where, due to contractual reasons, existing code needs to be maintained
  using only Ada 83 features.

  With few exceptions (most notably the need to use ``<>`` on
  unconstrained :index:`generic formal parameters <Generic formal parameters>`,
  the use of the new Ada 95 / Ada 2005
  reserved words, and the use of packages
  with optional bodies), it is not necessary to specify the
  :switch:`-gnat83` switch when compiling Ada 83 programs, because, with rare
  exceptions, Ada 95 and Ada 2005 are upwardly compatible with Ada 83. Thus
  a correct Ada 83 program is usually also a correct program
  in these later versions of the language standard. For further information
  please refer to the *Compatibility and Porting Guide* chapter in the
  :title:`GNAT Reference Manual`.


.. index:: -gnat95  (gcc)
.. index:: Ada 95 mode

:switch:`-gnat95` (Ada 95 mode)
  This switch directs the compiler to implement the Ada 95 version of the
  language.
  Since Ada 95 is almost completely upwards
  compatible with Ada 83, Ada 83 programs may generally be compiled using
  this switch (see the description of the :switch:`-gnat83` switch for further
  information about Ada 83 mode).
  If an Ada 2005 program is compiled in Ada 95 mode,
  uses of the new Ada 2005 features will cause error
  messages or warnings.

  This switch also can be used to cancel the effect of a previous
  :switch:`-gnat83`, :switch:`-gnat05/2005`, or :switch:`-gnat12/2012`
  switch earlier in the command line.


.. index:: -gnat05  (gcc)
.. index:: -gnat2005  (gcc)
.. index:: Ada 2005 mode

:switch:`-gnat05` or :switch:`-gnat2005` (Ada 2005 mode)
  This switch directs the compiler to implement the Ada 2005 version of the
  language, as documented in the official Ada standards document.
  Since Ada 2005 is almost completely upwards
  compatible with Ada 95 (and thus also with Ada 83), Ada 83 and Ada 95 programs
  may generally be compiled using this switch (see the description of the
  :switch:`-gnat83` and :switch:`-gnat95` switches for further
  information).


.. index:: -gnat12  (gcc)
.. index:: -gnat2012  (gcc)
.. index:: Ada 2012 mode

:switch:`-gnat12` or :switch:`-gnat2012` (Ada 2012 mode)
  This switch directs the compiler to implement the Ada 2012 version of the
  language (also the default).
  Since Ada 2012 is almost completely upwards
  compatible with Ada 2005 (and thus also with Ada 83, and Ada 95),
  Ada 83 and Ada 95 programs
  may generally be compiled using this switch (see the description of the
  :switch:`-gnat83`, :switch:`-gnat95`, and :switch:`-gnat05/2005` switches
  for further information).


.. index:: -gnat2022  (gcc)
.. index:: Ada 2022 mode

:switch:`-gnat2022` (Ada 2022 mode)
  This switch directs the compiler to implement the Ada 2022 version of the
  language.


.. index:: -gnatX0  (gcc)
.. index:: Ada language extensions
.. index:: GNAT extensions

:switch:`-gnatX0` (Enable GNAT Extensions)
  This switch directs the compiler to implement the latest version of the
  language (currently Ada 2022) and also to enable certain GNAT implementation
  extensions that are not part of any Ada standard. For a full list of these
  extensions, see the GNAT reference manual, ``Pragma Extensions_Allowed``.

.. index:: -gnatX  (gcc)
.. index:: Ada language extensions
.. index:: GNAT extensions

:switch:`-gnatX` (Enable core GNAT Extensions)
  This switch is similar to -gnatX0 except that only some, not all, of the
  GNAT-defined language extensions are enabled. For a list of the
  extensions enabled by this switch, see the GNAT reference manual
  ``Pragma Extensions_Allowed`` and the description of that pragma's
  "On" (as opposed to "All") argument.


.. _Character_Set_Control:

Character Set Control
---------------------

.. index:: -gnati  (gcc)

:switch:`-gnati{c}`
  Normally GNAT recognizes the Latin-1 character set in source program
  identifiers, as described in the Ada Reference Manual.
  This switch causes
  GNAT to recognize alternate character sets in identifiers. ``c`` is a
  single character  indicating the character set, as follows:

  ========== ======================================================
  *1*         ISO 8859-1 (Latin-1) identifiers
  *2*         ISO 8859-2 (Latin-2) letters allowed in identifiers
  *3*         ISO 8859-3 (Latin-3) letters allowed in identifiers
  *4*         ISO 8859-4 (Latin-4) letters allowed in identifiers
  *5*         ISO 8859-5 (Cyrillic) letters allowed in identifiers
  *9*         ISO 8859-15 (Latin-9) letters allowed in identifiers
  *p*         IBM PC letters (code page 437) allowed in identifiers
  *8*         IBM PC letters (code page 850) allowed in identifiers
  *f*         Full upper-half codes allowed in identifiers
  *n*         No upper-half codes allowed in identifiers
  *w*         Wide-character codes (that is, codes greater than 255)
              allowed in identifiers
  ========== ======================================================

  See :ref:`Foreign_Language_Representation` for full details on the
  implementation of these character sets.


.. index:: -gnatW  (gcc)

:switch:`-gnatW{e}`
  Specify the method of encoding for wide characters.
  ``e`` is one of the following:

  ========== ======================================================
  *h*        Hex encoding (brackets coding also recognized)
  *u*        Upper half encoding (brackets encoding also recognized)
  *s*        Shift/JIS encoding (brackets encoding also recognized)
  *e*        EUC encoding (brackets encoding also recognized)
  *8*        UTF-8 encoding (brackets encoding also recognized)
  *b*        Brackets encoding only (default value)
  ========== ======================================================

  For full details on these encoding
  methods see :ref:`Wide_Character_Encodings`.
  Note that brackets coding is always accepted, even if one of the other
  options is specified, so for example :switch:`-gnatW8` specifies that both
  brackets and UTF-8 encodings will be recognized. The units that are
  with'ed directly or indirectly will be scanned using the specified
  representation scheme, and so if one of the non-brackets scheme is
  used, it must be used consistently throughout the program. However,
  since brackets encoding is always recognized, it may be conveniently
  used in standard libraries, allowing these libraries to be used with
  any of the available coding schemes.

  Note that brackets encoding only applies to program text. Within comments,
  brackets are considered to be normal graphic characters, and bracket sequences
  are never recognized as wide characters.

  If no :switch:`-gnatW?` parameter is present, then the default
  representation is normally Brackets encoding only. However, if the
  first three characters of the file are 16#EF# 16#BB# 16#BF# (the standard
  byte order mark or BOM for UTF-8), then these three characters are
  skipped and the default representation for the file is set to UTF-8.

  Note that the wide character representation that is specified (explicitly
  or by default) for the main program also acts as the default encoding used
  for Wide_Text_IO files if not specifically overridden by a WCEM form
  parameter.


When no :switch:`-gnatW?` is specified, then characters (other than wide
characters represented using brackets notation) are treated as 8-bit
Latin-1 codes. The codes recognized are the Latin-1 graphic characters,
and ASCII format effectors (CR, LF, HT, VT). Other lower half control
characters in the range 16#00#..16#1F# are not accepted in program text
or in comments. Upper half control characters (16#80#..16#9F#) are rejected
in program text, but allowed and ignored in comments. Note in particular
that the Next Line (NEL) character whose encoding is 16#85# is not recognized
as an end of line in this default mode. If your source program contains
instances of the NEL character used as a line terminator,
you must use UTF-8 encoding for the whole
source program. In default mode, all lines must be ended by a standard
end of line sequence (CR, CR/LF, or LF).

Note that the convention of simply accepting all upper half characters in
comments means that programs that use standard ASCII for program text, but
UTF-8 encoding for comments are accepted in default mode, providing that the
comments are ended by an appropriate (CR, or CR/LF, or LF) line terminator.
This is a common mode for many programs with foreign language comments.

.. _File_Naming_Control:

File Naming Control
-------------------

.. index:: -gnatk  (gcc)

:switch:`-gnatk{n}`
  Activates file name 'krunching'. ``n``, a decimal integer in the range
  1-999, indicates the maximum allowable length of a file name (not
  including the :file:`.ads` or :file:`.adb` extension). The default is not
  to enable file name krunching.

  For the source file naming rules, :ref:`File_Naming_Rules`.

.. _Subprogram_Inlining_Control:

Subprogram Inlining Control
---------------------------

.. index:: -gnatn  (gcc)

:switch:`-gnatn[12]`
  The ``n`` here is intended to suggest the first syllable of the word 'inline'.
  GNAT recognizes and processes ``Inline`` pragmas. However, for inlining to
  actually occur, optimization must be enabled and, by default, inlining of
  subprograms across units is not performed. If you want to additionally
  enable inlining of subprograms specified by pragma ``Inline`` across units,
  you must also specify this switch.

  In the absence of this switch, GNAT does not attempt inlining across units
  and does not access the bodies of subprograms for which ``pragma Inline`` is
  specified if they are not in the current unit.

  You can optionally specify the inlining level: 1 for moderate inlining across
  units, which is a good compromise between compilation times and performances
  at run time, or 2 for full inlining across units, which may bring about
  longer compilation times. If no inlining level is specified, the compiler will
  pick it based on the optimization level: 1 for :switch:`-O1`, :switch:`-O2` or
  :switch:`-Os` and 2 for :switch:`-O3`.

  If you specify this switch the compiler will access these bodies,
  creating an extra source dependency for the resulting object file, and
  where possible, the call will be inlined.
  For further details on when inlining is possible
  see :ref:`Inlining_of_Subprograms`.


.. index:: -gnatN  (gcc)

:switch:`-gnatN`
  This switch activates front-end inlining which also
  generates additional dependencies.

  When using a gcc-based back end, then the use of
  :switch:`-gnatN` is deprecated, and the use of :switch:`-gnatn` is preferred.
  Historically front end inlining was more extensive than the gcc back end
  inlining, but that is no longer the case.

.. _Auxiliary_Output_Control:

Auxiliary Output Control
------------------------

.. index:: -gnatu  (gcc)

:switch:`-gnatu`
  Print a list of units required by this compilation on :file:`stdout`.
  The listing includes all units on which the unit being compiled depends
  either directly or indirectly.


.. index:: -pass-exit-codes  (gcc)

:switch:`-pass-exit-codes`
  If this switch is not used, the exit code returned by ``gcc`` when
  compiling multiple files indicates whether all source files have
  been successfully used to generate object files or not.

  When :switch:`-pass-exit-codes` is used, ``gcc`` exits with an extended
  exit status and allows an integrated development environment to better
  react to a compilation failure. Those exit status are:

  ========== ======================================================
  *5*        There was an error in at least one source file.
  *3*        At least one source file did not generate an object file.
  *2*        The compiler died unexpectedly (internal error for example).
  *0*        An object file has been generated for every source file.
  ========== ======================================================

.. _Debugging_Control:

Debugging Control
-----------------

  .. index:: Debugging options


.. index:: -gnatd  (gcc)

:switch:`-gnatd{x}`
  Activate internal debugging switches. ``x`` is a letter or digit, or
  string of letters or digits, which specifies the type of debugging
  outputs desired. Normally these are used only for internal development
  or system debugging purposes. You can find full documentation for these
  switches in the body of the ``Debug`` unit in the compiler source
  file :file:`debug.adb`.


.. index:: -gnatG  (gcc)

:switch:`-gnatG[={nn}]`
  This switch causes the compiler to generate auxiliary output containing
  a pseudo-source listing of the generated expanded code. Like most Ada
  compilers, GNAT works by first transforming the high level Ada code into
  lower level constructs. For example, tasking operations are transformed
  into calls to the tasking run-time routines. A unique capability of GNAT
  is to list this expanded code in a form very close to normal Ada source.
  This is very useful in understanding the implications of various Ada
  usage on the efficiency of the generated code. There are many cases in
  Ada (e.g., the use of controlled types), where simple Ada statements can
  generate a lot of run-time code. By using :switch:`-gnatG` you can identify
  these cases, and consider whether it may be desirable to modify the coding
  approach to improve efficiency.

  The optional parameter ``nn`` if present after -gnatG specifies an
  alternative maximum line length that overrides the normal default of 72.
  This value is in the range 40-999999, values less than 40 being silently
  reset to 40. The equal sign is optional.

  The format of the output is very similar to standard Ada source, and is
  easily understood by an Ada programmer. The following special syntactic
  additions correspond to low level features used in the generated code that
  do not have any exact analogies in pure Ada source form. The following
  is a partial list of these special constructions. See the spec
  of package ``Sprint`` in file :file:`sprint.ads` for a full list.

  .. index:: -gnatL  (gcc)

  If the switch :switch:`-gnatL` is used in conjunction with
  :switch:`-gnatG`, then the original source lines are interspersed
  in the expanded source (as comment lines with the original line number).

  :samp:`new {xxx} [storage_pool = {yyy}]`
    Shows the storage pool being used for an allocator.


  :samp:`at end {procedure-name};`
    Shows the finalization (cleanup) procedure for a scope.


  :samp:`(if {expr} then {expr} else {expr})`
    Conditional expression equivalent to the ``x?y:z`` construction in C.


  :samp:`{target}^({source})`
    A conversion with floating-point truncation instead of rounding.


  :samp:`{target}?({source})`
    A conversion that bypasses normal Ada semantic checking. In particular
    enumeration types and fixed-point types are treated simply as integers.


  :samp:`{target}?^({source})`
    Combines the above two cases.


  :samp:`{x} #/ {y}`

  :samp:`{x} #mod {y}`

  :samp:`{x} # {y}`

  :samp:`{x} #rem {y}`
    A division or multiplication of fixed-point values which are treated as
    integers without any kind of scaling.


  :samp:`free {expr} [storage_pool = {xxx}]`
    Shows the storage pool associated with a ``free`` statement.


  :samp:`[subtype or type declaration]`
    Used to list an equivalent declaration for an internally generated
    type that is referenced elsewhere in the listing.


  :samp:`freeze {type-name} [{actions}]`
    Shows the point at which ``type-name`` is frozen, with possible
    associated actions to be performed at the freeze point.


  :samp:`reference {itype}`
    Reference (and hence definition) to internal type ``itype``.


  :samp:`{function-name}! ({arg}, {arg}, {arg})`
    Intrinsic function call.


  :samp:`{label-name} : label`
    Declaration of label ``labelname``.


  :samp:`#$ {subprogram-name}`
    An implicit call to a run-time support routine
    (to meet the requirement of H.3.1(9) in a
    convenient manner).


  :samp:`{expr} && {expr} && {expr} ... && {expr}`
    A multiple concatenation (same effect as ``expr`` & ``expr`` &
    ``expr``, but handled more efficiently).


  :samp:`[constraint_error]`
    Raise the ``Constraint_Error`` exception.


  :samp:`{expression}'reference`
    A pointer to the result of evaluating {expression}.


  :samp:`{target-type}!({source-expression})`
    An unchecked conversion of ``source-expression`` to ``target-type``.


  :samp:`[{numerator}/{denominator}]`
    Used to represent internal real literals (that) have no exact
    representation in base 2-16 (for example, the result of compile time
    evaluation of the expression 1.0/27.0).


.. index:: -gnatD  (gcc)

:switch:`-gnatD[=nn]`
  When used in conjunction with :switch:`-gnatG`, this switch causes
  the expanded source, as described above for
  :switch:`-gnatG` to be written to files with names
  :file:`xxx.dg`, where :file:`xxx` is the normal file name,
  instead of to the standard output file. For
  example, if the source file name is :file:`hello.adb`, then a file
  :file:`hello.adb.dg` will be written.  The debugging
  information generated by the ``gcc`` :switch:`-g` switch
  will refer to the generated :file:`xxx.dg` file. This allows
  you to do source level debugging using the generated code which is
  sometimes useful for complex code, for example to find out exactly
  which part of a complex construction raised an exception. This switch
  also suppresses generation of cross-reference information (see
  :switch:`-gnatx`) since otherwise the cross-reference information
  would refer to the :file:`.dg` file, which would cause
  confusion since this is not the original source file.

  Note that :switch:`-gnatD` actually implies :switch:`-gnatG`
  automatically, so it is not necessary to give both options.
  In other words :switch:`-gnatD` is equivalent to :switch:`-gnatDG`).

  .. index:: -gnatL  (gcc)

  If the switch :switch:`-gnatL` is used in conjunction with
  :switch:`-gnatDG`, then the original source lines are interspersed
  in the expanded source (as comment lines with the original line number).

  The optional parameter ``nn`` if present after -gnatD specifies an
  alternative maximum line length that overrides the normal default of 72.
  This value is in the range 40-999999, values less than 40 being silently
  reset to 40. The equal sign is optional.


.. index:: -gnatr  (gcc)
.. index:: pragma Restrictions

:switch:`-gnatr`
  This switch causes pragma Restrictions to be treated as Restriction_Warnings
  so that violation of restrictions causes warnings rather than illegalities.
  This is useful during the development process when new restrictions are added
  or investigated. The switch also causes pragma Profile to be treated as
  Profile_Warnings, and pragma Restricted_Run_Time and pragma Ravenscar set
  restriction warnings rather than restrictions.


.. index:: -gnatR  (gcc)

:switch:`-gnatR[0|1|2|3|4][e][h][m][j][s]`
  This switch controls output from the compiler of a listing showing
  representation information for declared types, objects and subprograms.
  For :switch:`-gnatR0`, no information is output (equivalent to omitting
  the :switch:`-gnatR` switch). For :switch:`-gnatR1` (which is the default,
  so :switch:`-gnatR` with no parameter has the same effect), size and
  alignment information is listed for declared array and record types.

  For :switch:`-gnatR2`, size and alignment information is listed for all
  declared types and objects. The ``Linker_Section`` is also listed for any
  entity for which the ``Linker_Section`` is set explicitly or implicitly (the
  latter case occurs for objects of a type for which a ``Linker_Section``
  is set).

  For :switch:`-gnatR3`, symbolic expressions for values that are computed
  at run time for records are included. These symbolic expressions have
  a mostly obvious format with #n being used to represent the value of the
  n'th discriminant. See source files :file:`repinfo.ads/adb` in the
  GNAT sources for full details on the format of :switch:`-gnatR3` output.

  For :switch:`-gnatR4`, information for relevant compiler-generated types
  is also listed, i.e. when they are structurally part of other declared
  types and objects.

  If the switch is followed by an ``e`` (e.g. :switch:`-gnatR2e`), then
  extended representation information for record sub-components of records
  is included.

  If the switch is followed by a ``h`` (e.g. :switch:`-gnatR3h`), then
  the components of records are sorted by increasing offsets and holes
  between consecutive components are flagged.

  If the switch is followed by an ``m`` (e.g. :switch:`-gnatRm`), then
  subprogram conventions and parameter passing mechanisms for all the
  subprograms are included.

  If the switch is followed by a ``j`` (e.g. :switch:`-gnatRj`), then
  the output is in the JSON data interchange format specified by the
  ECMA-404 standard. The semantic description of this JSON output is
  available in the specification of the Repinfo unit present in the
  compiler sources.

  If the switch is followed by an ``s`` (e.g. :switch:`-gnatR3s`), then
  the output is to a file with the name :file:`file.rep` where ``file`` is
  the name of the corresponding source file, except if ``j`` is also
  specified, in which case the file name is :file:`file.json`.

  Note that it is possible for record components to have zero size. In
  this case, the component clause uses an obvious extension of permitted
  Ada syntax, for example ``at 0 range 0 .. -1``.


.. index:: -gnatS  (gcc)

:switch:`-gnatS`
  The use of the switch :switch:`-gnatS` for an
  Ada compilation will cause the compiler to output a
  representation of package Standard in a form very
  close to standard Ada. It is not quite possible to
  do this entirely in standard Ada (since new
  numeric base types cannot be created in standard
  Ada), but the output is easily
  readable to any Ada programmer, and is useful to
  determine the characteristics of target dependent
  types in package Standard.


.. index:: -gnatx  (gcc)

:switch:`-gnatx`
  Normally the compiler generates full cross-referencing information in
  the :file:`ALI` file. This information is used by a number of tools.
  The :switch:`-gnatx` switch suppresses this information. This saves some space
  and may slightly speed up compilation, but means that tools depending
  on this information cannot be used.


.. index:: -fgnat-encodings  (gcc)

:switch:`-fgnat-encodings=[all|gdb|minimal]`
  This switch controls the balance between GNAT encodings and standard DWARF
  emitted in the debug information.

  Historically, old debug formats like stabs were not powerful enough to
  express some Ada types (for instance, variant records or fixed-point types).
  To work around this, GNAT introduced proprietary encodings that embed the
  missing information ("GNAT encodings").

  Recent versions of the DWARF debug information format are now able to
  correctly describe most of these Ada constructs ("standard DWARF"). As
  third-party tools started to use this format, GNAT has been enhanced to
  generate it. However, most tools (including GDB) are still relying on GNAT
  encodings.

  To support all tools, GNAT needs to be versatile about the balance between
  generation of GNAT encodings and standard DWARF. This is what
  :switch:`-fgnat-encodings` is about.

  * ``=all``: Emit all GNAT encodings, and then emit as much standard DWARF as
    possible so it does not conflict with GNAT encodings.
  * ``=gdb``: Emit as much standard DWARF as possible as long as the current
    GDB handles it. Emit GNAT encodings for the rest.
  * ``=minimal``: Emit as much standard DWARF as possible and emit GNAT
    encodings for the rest.


.. _Exception_Handling_Control:

Exception Handling Control
--------------------------

GNAT uses two methods for handling exceptions at run time. The
``setjmp/longjmp`` method saves the context when entering
a frame with an exception handler. Then when an exception is
raised, the context can be restored immediately, without the
need for tracing stack frames. This method provides very fast
exception propagation, but introduces significant overhead for
the use of exception handlers, even if no exception is raised.

The other approach is called 'zero cost' exception handling.
With this method, the compiler builds static tables to describe
the exception ranges. No dynamic code is required when entering
a frame containing an exception handler. When an exception is
raised, the tables are used to control a back trace of the
subprogram invocation stack to locate the required exception
handler. This method has considerably poorer performance for
the propagation of exceptions, but there is no overhead for
exception handlers if no exception is raised. Note that in this
mode and in the context of mixed Ada and C/C++ programming,
to propagate an exception through a C/C++ code, the C/C++ code
must be compiled with the :switch:`-funwind-tables` GCC's
option.

The following switches may be used to control which of the
two exception handling methods is used.



.. index:: --RTS=sjlj  (gnatmake)

:switch:`--RTS=sjlj`
  This switch causes the setjmp/longjmp run-time (when available) to be used
  for exception handling. If the default
  mechanism for the target is zero cost exceptions, then
  this switch can be used to modify this default, and must be
  used for all units in the partition.
  This option is rarely used. One case in which it may be
  advantageous is if you have an application where exception
  raising is common and the overall performance of the
  application is improved by favoring exception propagation.


.. index:: --RTS=zcx  (gnatmake)
.. index:: Zero Cost Exceptions

:switch:`--RTS=zcx`
  This switch causes the zero cost approach to be used
  for exception handling. If this is the default mechanism for the
  target (see below), then this switch is unneeded. If the default
  mechanism for the target is setjmp/longjmp exceptions, then
  this switch can be used to modify this default, and must be
  used for all units in the partition.
  This option can only be used if the zero cost approach
  is available for the target in use, otherwise it will generate an error.

The same option :switch:`--RTS` must be used both for ``gcc``
and ``gnatbind``. Passing this option to ``gnatmake``
(:ref:`Switches_for_gnatmake`) will ensure the required consistency
through the compilation and binding steps.

.. _Units_to_Sources_Mapping_Files:

Units to Sources Mapping Files
------------------------------



.. index:: -gnatem  (gcc)

:switch:`-gnatem={path}`
  A mapping file is a way to communicate to the compiler two mappings:
  from unit names to file names (without any directory information) and from
  file names to path names (with full directory information). These mappings
  are used by the compiler to short-circuit the path search.

  The use of mapping files is not required for correct operation of the
  compiler, but mapping files can improve efficiency, particularly when
  sources are read over a slow network connection. In normal operation,
  you need not be concerned with the format or use of mapping files,
  and the :switch:`-gnatem` switch is not a switch that you would use
  explicitly. It is intended primarily for use by automatic tools such as
  ``gnatmake`` running under the project file facility. The
  description here of the format of mapping files is provided
  for completeness and for possible use by other tools.

  A mapping file is a sequence of sets of three lines. In each set, the
  first line is the unit name, in lower case, with ``%s`` appended
  for specs and ``%b`` appended for bodies; the second line is the
  file name; and the third line is the path name.

  Example::

       main%b
       main.2.ada
       /gnat/project1/sources/main.2.ada


  When the switch :switch:`-gnatem` is specified, the compiler will
  create in memory the two mappings from the specified file. If there is
  any problem (nonexistent file, truncated file or duplicate entries),
  no mapping will be created.

  Several :switch:`-gnatem` switches may be specified; however, only the
  last one on the command line will be taken into account.

  When using a project file, ``gnatmake`` creates a temporary
  mapping file and communicates it to the compiler using this switch.


.. _Code_Generation_Control:

Code Generation Control
-----------------------

The GCC technology provides a wide range of target dependent
:switch:`-m` switches for controlling
details of code generation with respect to different versions of
architectures. This includes variations in instruction sets (e.g.,
different members of the power pc family), and different requirements
for optimal arrangement of instructions (e.g., different members of
the x86 family). The list of available :switch:`-m` switches may be
found in the GCC documentation.

Use of these :switch:`-m` switches may in some cases result in improved
code performance.

The GNAT technology is tested and qualified without any
:switch:`-m` switches,
so generally the most reliable approach is to avoid the use of these
switches. However, we generally expect most of these switches to work
successfully with GNAT, and many customers have reported successful
use of these options.

Our general advice is to avoid the use of :switch:`-m` switches unless
special needs lead to requirements in this area. In particular,
there is no point in using :switch:`-m` switches to improve performance
unless you actually see a performance improvement.


.. _Linker_Switches:

Linker Switches
===============

Linker switches can be specified after :switch:`-largs` builder switch.

.. index:: -fuse-ld=name

:switch:`-fuse-ld={name}`
  Linker to be used. The default is ``bfd`` for :file:`ld.bfd`; ``gold``
  (for :file:`ld.gold`) and ``mold`` (for :file:`ld.mold`) are more
  recent and faster alternatives, but only available on GNU/Linux
  platforms.

.. _Binding_with_gnatbind:

Binding with ``gnatbind``
=========================

.. index:: ! gnatbind

This chapter describes the GNAT binder, ``gnatbind``, which is used
to bind compiled GNAT objects.

The ``gnatbind`` program performs four separate functions:

* Checks that a program is consistent, in accordance with the rules in
  Chapter 10 of the Ada Reference Manual. In particular, error
  messages are generated if a program uses inconsistent versions of a
  given unit.

* Checks that an acceptable order of elaboration exists for the program
  and issues an error message if it cannot find an order of elaboration
  that satisfies the rules in Chapter 10 of the Ada Language Manual.

* Generates a main program incorporating the given elaboration order.
  This program is a small Ada package (body and spec) that
  must be subsequently compiled
  using the GNAT compiler. The necessary compilation step is usually
  performed automatically by ``gnatlink``. The two most important
  functions of this program
  are to call the elaboration routines of units in an appropriate order
  and to call the main program.

* Determines the set of object files required by the given main program.
  This information is output in the forms of comments in the generated program,
  to be read by the ``gnatlink`` utility used to link the Ada application.

.. _Running_gnatbind:

Running ``gnatbind``
--------------------

The form of the ``gnatbind`` command is

.. code-block:: sh

  $ gnatbind [ switches ] mainprog[.ali] [ switches ]


where :file:`mainprog.adb` is the Ada file containing the main program
unit body. ``gnatbind`` constructs an Ada
package in two files whose names are
:file:`b~mainprog.ads`, and :file:`b~mainprog.adb`.
For example, if given the
parameter :file:`hello.ali`, for a main program contained in file
:file:`hello.adb`, the binder output files would be :file:`b~hello.ads`
and :file:`b~hello.adb`.

When doing consistency checking, the binder takes into consideration
any source files it can locate. For example, if the binder determines
that the given main program requires the package ``Pack``, whose
:file:`.ALI`
file is :file:`pack.ali` and whose corresponding source spec file is
:file:`pack.ads`, it attempts to locate the source file :file:`pack.ads`
(using the same search path conventions as previously described for the
``gcc`` command). If it can locate this source file, it checks that
the time stamps
or source checksums of the source and its references to in :file:`ALI` files
match. In other words, any :file:`ALI` files that mentions this spec must have
resulted from compiling this version of the source file (or in the case
where the source checksums match, a version close enough that the
difference does not matter).

.. index:: Source files, use by binder

The effect of this consistency checking, which includes source files, is
that the binder ensures that the program is consistent with the latest
version of the source files that can be located at bind time. Editing a
source file without compiling files that depend on the source file cause
error messages to be generated by the binder.

For example, suppose you have a main program :file:`hello.adb` and a
package ``P``, from file :file:`p.ads` and you perform the following
steps:

* Enter ``gcc -c hello.adb`` to compile the main program.

* Enter ``gcc -c p.ads`` to compile package ``P``.

* Edit file :file:`p.ads`.

* Enter ``gnatbind hello``.

At this point, the file :file:`p.ali` contains an out-of-date time stamp
because the file :file:`p.ads` has been edited. The attempt at binding
fails, and the binder generates the following error messages:


::

  error: "hello.adb" must be recompiled ("p.ads" has been modified)
  error: "p.ads" has been modified and must be recompiled


Now both files must be recompiled as indicated, and then the bind can
succeed, generating a main program. You need not normally be concerned
with the contents of this file, but for reference purposes a sample
binder output file is given in :ref:`Example_of_Binder_Output_File`.

In most normal usage, the default mode of ``gnatbind`` which is to
generate the main package in Ada, as described in the previous section.
In particular, this means that any Ada programmer can read and understand
the generated main program. It can also be debugged just like any other
Ada code provided the :switch:`-g` switch is used for
``gnatbind`` and ``gnatlink``.

.. _Switches_for_gnatbind:

Switches for ``gnatbind``
-------------------------

The following switches are available with ``gnatbind``; details will
be presented in subsequent sections.


.. index:: --version  (gnatbind)

:switch:`--version`
  Display Copyright and version, then exit disregarding all other options.


.. index:: --help  (gnatbind)

:switch:`--help`
  If :switch:`--version` was not used, display usage, then exit disregarding
  all other options.


.. index:: -a  (gnatbind)

:switch:`-a`
  Indicates that, if supported by the platform, the adainit procedure should
  be treated as an initialisation routine by the linker (a constructor). This
  is intended to be used by the Project Manager to automatically initialize
  shared Stand-Alone Libraries.


.. index:: -aO  (gnatbind)

:switch:`-aO`
  Specify directory to be searched for ALI files.


.. index:: -aI  (gnatbind)

:switch:`-aI`
  Specify directory to be searched for source file.


.. index:: -A  (gnatbind)

:switch:`-A[={filename}]`
  Output ALI list (to standard output or to the named file).


.. index:: -b  (gnatbind)

:switch:`-b`
  Generate brief messages to :file:`stderr` even if verbose mode set.


.. index:: -c  (gnatbind)

:switch:`-c`
  Check only, no generation of binder output file.


.. index:: -dnn[k|m] (gnatbind)

:switch:`-d{nn}[k|m]`
  This switch can be used to change the default task stack size value
  to a specified size ``nn``, which is expressed in bytes by default, or
  in kilobytes when suffixed with ``k`` or in megabytes when suffixed
  with ``m``.
  In the absence of a :samp:`[k|m]` suffix, this switch is equivalent,
  in effect, to completing all task specs with

  .. code-block:: ada

       pragma Storage_Size (nn);

  When they do not already have such a pragma.


.. index:: -D  (gnatbind)

:switch:`-D{nn}[k|m]`
  Set the default secondary stack size to ``nn``. The suffix indicates whether
  the size is in bytes (no suffix), kilobytes (``k`` suffix) or megabytes
  (``m`` suffix).

  The secondary stack holds objects of unconstrained types that are returned by
  functions, for example unconstrained Strings. The size of the secondary stack
  can be dynamic or fixed depending on the target.

  For most targets, the secondary stack grows on demand and is implemented as
  a chain of blocks in the heap. In this case, the default secondary stack size
  determines the initial size of the secondary stack for each task and the
  smallest amount the secondary stack can grow by.

  For Light, Light-Tasking, and Embedded run-times the size of the secondary
  stack is fixed. This switch can be used to change the default size of these
  stacks. The default secondary stack size can be overridden on a per-task
  basis if individual tasks have different secondary stack requirements. This
  is achieved through the Secondary_Stack_Size aspect, which takes the size of
  the secondary stack in bytes.

.. index:: -e  (gnatbind)

:switch:`-e`
  Output complete list of elaboration-order dependencies.


.. index:: -Ea  (gnatbind)

:switch:`-Ea`
  Store tracebacks in exception occurrences when the target supports it.
  The "a" is for "address"; tracebacks will contain hexadecimal addresses,
  unless symbolic tracebacks are enabled.

  See also the packages ``GNAT.Traceback`` and
  ``GNAT.Traceback.Symbolic`` for more information.
  Note that on x86 ports, you must not use :switch:`-fomit-frame-pointer`
  ``gcc`` option.


.. index:: -Es  (gnatbind)

:switch:`-Es`
  Store tracebacks in exception occurrences when the target supports it.
  The "s" is for "symbolic"; symbolic tracebacks are enabled.


.. index:: -E  (gnatbind)

:switch:`-E`
  Currently the same as ``-Ea``.


.. index:: -f  (gnatbind)

:switch:`-f{elab-order}`
  Force elaboration order. For further details see :ref:`Elaboration_Control`
  and :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -F  (gnatbind)

:switch:`-F`
  Force the checks of elaboration flags. ``gnatbind`` does not normally
  generate checks of elaboration flags for the main executable, except when
  a Stand-Alone Library is used. However, there are cases when this cannot be
  detected by gnatbind. An example is importing an interface of a Stand-Alone
  Library through a pragma Import and only specifying through a linker switch
  this Stand-Alone Library. This switch is used to guarantee that elaboration
  flag checks are generated.


.. index:: -h  (gnatbind)

:switch:`-h`
  Output usage (help) information.


.. index:: -H  (gnatbind)

:switch:`-H`
  Legacy elaboration order model enabled. For further details see
  :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -H32  (gnatbind)

:switch:`-H32`
  Use 32-bit allocations for ``__gnat_malloc`` (and thus for access types).
  For further details see :ref:`Dynamic_Allocation_Control`.


.. index:: -H64  (gnatbind)
.. index:: __gnat_malloc

:switch:`-H64`
  Use 64-bit allocations for ``__gnat_malloc`` (and thus for access types).
  For further details see :ref:`Dynamic_Allocation_Control`.


  .. index:: -I  (gnatbind)

:switch:`-I`
  Specify directory to be searched for source and ALI files.


  .. index:: -I-  (gnatbind)

:switch:`-I-`
  Do not look for sources in the current directory where ``gnatbind`` was
  invoked, and do not look for ALI files in the directory containing the
  ALI file named in the ``gnatbind`` command line.


  .. index:: -k  (gnatbind)

:switch:`-k`
  Disable checking of elaboration flags. When using :switch:`-n`
  either explicitly or implicitly, :switch:`-F` is also implied,
  unless :switch:`-k` is used. This switch should be used with care
  and you should ensure manually that elaboration routines are not called
  twice unintentionally.


  .. index:: -K  (gnatbind)

:switch:`-K`
  Give list of linker options specified for link.


  .. index:: -l  (gnatbind)

:switch:`-l`
  Output chosen elaboration order.


  .. index:: -L  (gnatbind)

:switch:`-L{xxx}`
  Bind the units for library building. In this case the ``adainit`` and
  ``adafinal`` procedures (:ref:`Binding_with_Non-Ada_Main_Programs`)
  are renamed to :samp:`{xxx}init` and
  :samp:`{xxx}final`.
  Implies -n.
  (:ref:`GNAT_and_Libraries`, for more details.)


  .. index:: -M  (gnatbind)

:switch:`-M{xyz}`
  Rename generated main program from main to xyz. This option is
  supported on cross environments only.

  .. index:: -m  (gnatbind)

:switch:`-m{n}`
  Limit number of detected errors or warnings to ``n``, where ``n`` is
  in the range 1..999999. The default value if no switch is
  given is 9999. If the number of warnings reaches this limit, then a
  message is output and further warnings are suppressed, the bind
  continues in this case. If the number of errors reaches this
  limit, then a message is output and the bind is abandoned.
  A value of zero means that no limit is enforced. The equal
  sign is optional.

  .. index:: -minimal  (gnatbind)

:switch:`-minimal`
  Generate a binder file suitable for space-constrained applications. When
  active, binder-generated objects not required for program operation are no
  longer generated. **Warning:** this option comes with the following
  limitations:

  * Starting the program's execution in the debugger will cause it to
    stop at the start of the ``main`` function instead of the main subprogram.
    This can be worked around by manually inserting a breakpoint on that
    subprogram and resuming the program's execution until reaching that breakpoint.
  * Programs using GNAT.Compiler_Version will not link.

  .. index:: -n  (gnatbind)

:switch:`-n`
  No main program.


  .. index:: -nostdinc  (gnatbind)

:switch:`-nostdinc`
  Do not look for sources in the system default directory.


  .. index:: -nostdlib  (gnatbind)

:switch:`-nostdlib`
  Do not look for library files in the system default directory.


  .. index:: --RTS  (gnatbind)

:switch:`--RTS={rts-path}`
  Specifies the default location of the run-time library. Same meaning as the
  equivalent ``gnatmake`` flag (:ref:`Switches_for_gnatmake`).

  .. index:: -o   (gnatbind)

:switch:`-o {file}`
  Name the output file ``file`` (default is :file:`b~{xxx}.adb`).
  Note that if this option is used, then linking must be done manually,
  gnatlink cannot be used.


  .. index:: -O  (gnatbind)

:switch:`-O[={filename}]`
  Output object list (to standard output or to the named file).


  .. index:: -p  (gnatbind)

:switch:`-p`
  Pessimistic (worst-case) elaboration order.


  .. index:: -P  (gnatbind)

:switch:`-P`
  Generate binder file suitable for CodePeer.


.. index:: -Q  (gnatbind)

:switch:`-Q{nnn}`
  Generate ``nnn`` additional default-sized secondary stacks.

  Tasks declared at the library level that use default-size secondary stacks
  have their secondary stacks allocated from a pool of stacks generated by
  gnatbind. This allows the default secondary stack size to be quickly changed
  by rebinding the application.

  While the binder sizes this pool to match the number of such tasks defined in
  the application, the pool size may need to be increased with the :switch:`-Q`
  switch to accommodate foreign threads registered with the Light run-time. For
  more information, please see the *The Primary and Secondary Stack* chapter in
  the *GNAT User’s Guide Supplement for Cross Platforms*.


  .. index:: -R  (gnatbind)

:switch:`-R`
  Output closure source list, which includes all non-run-time units that are
  included in the bind.


  .. index:: -Ra  (gnatbind)

:switch:`-Ra`
  Like :switch:`-R` but the list includes run-time units.


  .. index:: -s  (gnatbind)

:switch:`-s`
  Require all source files to be present.


  .. index:: -S  (gnatbind)

:switch:`-S{xxx}`
  Specifies the value to be used when detecting uninitialized scalar
  objects with pragma Initialize_Scalars.
  The ``xxx`` string specified with the switch is one of:

  * ``in`` for an invalid value.

    If zero is invalid for the discrete type in question,
    then the scalar value is set to all zero bits.
    For signed discrete types, the largest possible negative value of
    the underlying scalar is set (i.e. a one bit followed by all zero bits).
    For unsigned discrete types, the underlying scalar value is set to all
    one bits. For floating-point types, a NaN value is set
    (see body of package System.Scalar_Values for exact values).

  * ``lo`` for low value.

    If zero is invalid for the discrete type in question,
    then the scalar value is set to all zero bits.
    For signed discrete types, the largest possible negative value of
    the underlying scalar is set (i.e. a one bit followed by all zero bits).
    For unsigned discrete types, the underlying scalar value is set to all
    zero bits. For floating-point, a small value is set
    (see body of package System.Scalar_Values for exact values).

  * ``hi`` for high value.

    If zero is invalid for the discrete type in question,
    then the scalar value is set to all one bits.
    For signed discrete types, the largest possible positive value of
    the underlying scalar is set (i.e. a zero bit followed by all one bits).
    For unsigned discrete types, the underlying scalar value is set to all
    one bits. For floating-point, a large value is set
    (see body of package System.Scalar_Values for exact values).

  * ``xx`` for hex value (two hex digits).

    The underlying scalar is set to a value consisting of repeated bytes, whose
    value corresponds to the given value. For example if ``BF`` is given,
    then a 32-bit scalar value will be set to the bit pattern ``16#BFBFBFBF#``.

  .. index:: GNAT_INIT_SCALARS

  In addition, you can specify :switch:`-Sev` to indicate that the value is
  to be set at run time. In this case, the program will look for an environment
  variable of the form :samp:`GNAT_INIT_SCALARS={yy}`, where ``yy`` is one
  of :samp:`in/lo/hi/{xx}` with the same meanings as above.
  If no environment variable is found, or if it does not have a valid value,
  then the default is ``in`` (invalid values).

.. index:: -static  (gnatbind)

:switch:`-static`
  Link against a static GNAT run-time.


  .. index:: -shared  (gnatbind)

:switch:`-shared`
  Link against a shared GNAT run-time when available.


  .. index:: -t  (gnatbind)

:switch:`-t`
  Tolerate time stamp and other consistency errors.


  .. index:: -T  (gnatbind)

:switch:`-T{n}`
  Set the time slice value to ``n`` milliseconds. If the system supports
  the specification of a specific time slice value, then the indicated value
  is used. If the system does not support specific time slice values, but
  does support some general notion of round-robin scheduling, then any
  nonzero value will activate round-robin scheduling.

  A value of zero is treated specially. It turns off time
  slicing, and in addition, indicates to the tasking run-time that the
  semantics should match as closely as possible the Annex D
  requirements of the Ada RM, and in particular sets the default
  scheduling policy to ``FIFO_Within_Priorities``.


  .. index:: -u  (gnatbind)

:switch:`-u{n}`
  Enable dynamic stack usage, with ``n`` results stored and displayed
  at program termination. A result is generated when a task
  terminates. Results that can't be stored are displayed on the fly, at
  task termination. This option is currently not supported on Itanium
  platforms. (See :ref:`Dynamic_Stack_Usage_Analysis` for details.)


  .. index:: -v  (gnatbind)

:switch:`-v`
  Verbose mode. Write error messages, header, summary output to
  :file:`stdout`.


  .. index:: -V  (gnatbind)

:switch:`-V{key}={value}`
  Store the given association of ``key`` to ``value`` in the bind environment.
  Values stored this way can be retrieved at run time using
  ``GNAT.Bind_Environment``.


  .. index:: -w  (gnatbind)

:switch:`-w{x}`
  Warning mode; ``x`` = s/e for suppress/treat as error.


  .. index:: -Wx  (gnatbind)

:switch:`-Wx{e}`
  Override default wide character encoding for standard Text_IO files.


  .. index:: -x  (gnatbind)

:switch:`-x`
  Exclude source files (check object consistency only).


  .. index:: -xdr  (gnatbind)

:switch:`-xdr`
  Use the target-independent XDR protocol for stream oriented attributes
  instead of the default implementation which is based on direct binary
  representations and is therefore target-and endianness-dependent.
  However it does not support 128-bit integer types and the exception
  ``Ada.IO_Exceptions.Device_Error`` is raised if any attempt is made
  at streaming 128-bit integer types with it.


  .. index:: -Xnnn  (gnatbind)

:switch:`-X{nnn}`
  Set default exit status value, normally 0 for POSIX compliance.


  .. index:: -y  (gnatbind)

:switch:`-y`
  Enable leap seconds support in ``Ada.Calendar`` and its children.


  .. index:: -z  (gnatbind)

:switch:`-z`
  No main subprogram.

You may obtain this listing of switches by running ``gnatbind`` with
no arguments.


.. _Consistency-Checking_Modes:

Consistency-Checking Modes
^^^^^^^^^^^^^^^^^^^^^^^^^^

As described earlier, by default ``gnatbind`` checks
that object files are consistent with one another and are consistent
with any source files it can locate. The following switches control binder
access to sources.


  .. index:: -s  (gnatbind)

:switch:`-s`
  Require source files to be present. In this mode, the binder must be
  able to locate all source files that are referenced, in order to check
  their consistency. In normal mode, if a source file cannot be located it
  is simply ignored. If you specify this switch, a missing source
  file is an error.


  .. index:: -Wx  (gnatbind)

:switch:`-Wx{e}`
  Override default wide character encoding for standard Text_IO files.
  Normally the default wide character encoding method used for standard
  [Wide\_[Wide\_]]Text_IO files is taken from the encoding specified for
  the main source input (see description of switch
  :switch:`-gnatWx` for the compiler). The
  use of this switch for the binder (which has the same set of
  possible arguments) overrides this default as specified.


  .. index:: -x  (gnatbind)

:switch:`-x`
  Exclude source files. In this mode, the binder only checks that ALI
  files are consistent with one another. Source files are not accessed.
  The binder runs faster in this mode, and there is still a guarantee that
  the resulting program is self-consistent.
  If a source file has been edited since it was last compiled, and you
  specify this switch, the binder will not detect that the object
  file is out of date with respect to the source file. Note that this is the
  mode that is automatically used by ``gnatmake`` because in this
  case the checking against sources has already been performed by
  ``gnatmake`` in the course of compilation (i.e., before binding).


.. _Binder_Error_Message_Control:

Binder Error Message Control
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following switches provide control over the generation of error
messages from the binder:



  .. index:: -v  (gnatbind)

:switch:`-v`
  Verbose mode. In the normal mode, brief error messages are generated to
  :file:`stderr`. If this switch is present, a header is written
  to :file:`stdout` and any error messages are directed to :file:`stdout`.
  All that is written to :file:`stderr` is a brief summary message.


  .. index:: -b  (gnatbind)

:switch:`-b`
  Generate brief error messages to :file:`stderr` even if verbose mode is
  specified. This is relevant only when used with the
  :switch:`-v` switch.


  .. index:: -m  (gnatbind)

:switch:`-m{n}`
  Limits the number of error messages to ``n``, a decimal integer in the
  range 1-999. The binder terminates immediately if this limit is reached.


  .. index:: -M  (gnatbind)

:switch:`-M{xxx}`
  Renames the generated main program from ``main`` to ``xxx``.
  This is useful in the case of some cross-building environments, where
  the actual main program is separate from the one generated
  by ``gnatbind``.


  .. index:: -ws  (gnatbind)
  .. index:: Warnings

:switch:`-ws`
  Suppress all warning messages.


  .. index:: -we  (gnatbind)

:switch:`-we`
  Treat any warning messages as fatal errors.


  .. index:: -t  (gnatbind)
  .. index:: Time stamp checks, in binder
  .. index:: Binder consistency checks
  .. index:: Consistency checks, in binder

:switch:`-t`
  The binder performs a number of consistency checks including:


  * Check that time stamps of a given source unit are consistent

  * Check that checksums of a given source unit are consistent

  * Check that consistent versions of ``GNAT`` were used for compilation

  * Check consistency of configuration pragmas as required

  Normally failure of such checks, in accordance with the consistency
  requirements of the Ada Reference Manual, causes error messages to be
  generated which abort the binder and prevent the output of a binder
  file and subsequent link to obtain an executable.

  The :switch:`-t` switch converts these error messages
  into warnings, so that
  binding and linking can continue to completion even in the presence of such
  errors. The result may be a failed link (due to missing symbols), or a
  non-functional executable which has undefined semantics.

  .. note::

     This means that :switch:`-t` should be used only in unusual situations,
     with extreme care.

.. _Elaboration_Control:

Elaboration Control
^^^^^^^^^^^^^^^^^^^

The following switches provide additional control over the elaboration
order. For further details see :ref:`Elaboration_Order_Handling_in_GNAT`.


.. index:: -f  (gnatbind)

:switch:`-f{elab-order}`
  Force elaboration order.

  ``elab-order`` should be the name of a "forced elaboration order file", that
  is, a text file containing library item names, one per line. A name of the
  form "some.unit%s" or "some.unit (spec)" denotes the spec of Some.Unit. A
  name of the form "some.unit%b" or "some.unit (body)" denotes the body of
  Some.Unit. Each pair of lines is taken to mean that there is an elaboration
  dependence of the second line on the first. For example, if the file
  contains:

  .. code-block:: ada

      this (spec)
      this (body)
      that (spec)
      that (body)

  then the spec of This will be elaborated before the body of This, and the
  body of This will be elaborated before the spec of That, and the spec of That
  will be elaborated before the body of That. The first and last of these three
  dependences are already required by Ada rules, so this file is really just
  forcing the body of This to be elaborated before the spec of That.

  The given order must be consistent with Ada rules, or else ``gnatbind`` will
  give elaboration cycle errors. For example, if you say x (body) should be
  elaborated before x (spec), there will be a cycle, because Ada rules require
  x (spec) to be elaborated before x (body); you can't have the spec and body
  both elaborated before each other.

  If you later add "with That;" to the body of This, there will be a cycle, in
  which case you should erase either "this (body)" or "that (spec)" from the
  above forced elaboration order file.

  Blank lines and Ada-style comments are ignored. Unit names that do not exist
  in the program are ignored. Units in the GNAT predefined library are also
  ignored.


.. index:: -p  (gnatbind)

:switch:`-p`
  Pessimistic elaboration order

  This switch is only applicable to the pre-20.x legacy elaboration models.
  The post-20.x elaboration model uses a more informed approach of ordering
  the units.

  Normally the binder attempts to choose an elaboration order that is likely to
  minimize the likelihood of an elaboration order error resulting in raising a
  ``Program_Error`` exception. This switch reverses the action of the binder,
  and requests that it deliberately choose an order that is likely to maximize
  the likelihood of an elaboration error. This is useful in ensuring
  portability and avoiding dependence on accidental fortuitous elaboration
  ordering.

  Normally it only makes sense to use the :switch:`-p` switch if dynamic
  elaboration checking is used (:switch:`-gnatE` switch used for compilation).
  This is because in the default static elaboration mode, all necessary
  ``Elaborate`` and ``Elaborate_All`` pragmas are implicitly inserted.
  These implicit pragmas are still respected by the binder in :switch:`-p`
  mode, so a safe elaboration order is assured.

  Note that :switch:`-p` is not intended for production use; it is more for
  debugging/experimental use.

.. _Output_Control:

Output Control
^^^^^^^^^^^^^^

The following switches allow additional control over the output
generated by the binder.


  .. index:: -c  (gnatbind)

:switch:`-c`
  Check only. Do not generate the binder output file. In this mode the
  binder performs all error checks but does not generate an output file.


  .. index:: -e  (gnatbind)

:switch:`-e`
  Output complete list of elaboration-order dependencies, showing the
  reason for each dependency. This output can be rather extensive but may
  be useful in diagnosing problems with elaboration order. The output is
  written to :file:`stdout`.


  .. index:: -h  (gnatbind)

:switch:`-h`
  Output usage information. The output is written to :file:`stdout`.


  .. index:: -K  (gnatbind)

:switch:`-K`
  Output linker options to :file:`stdout`. Includes library search paths,
  contents of pragmas Ident and Linker_Options, and libraries added
  by ``gnatbind``.


  .. index:: -l  (gnatbind)

:switch:`-l`
  Output chosen elaboration order. The output is written to :file:`stdout`.


  .. index:: -O  (gnatbind)

:switch:`-O`
  Output full names of all the object files that must be linked to provide
  the Ada component of the program. The output is written to :file:`stdout`.
  This list includes the files explicitly supplied and referenced by the user
  as well as implicitly referenced run-time unit files. The latter are
  omitted if the corresponding units reside in shared libraries. The
  directory names for the run-time units depend on the system configuration.


  .. index:: -o  (gnatbind)

:switch:`-o {file}`
  Set name of output file to ``file`` instead of the normal
  :file:`b~`mainprog`.adb` default. Note that ``file`` denote the Ada
  binder generated body filename.
  Note that if this option is used, then linking must be done manually.
  It is not possible to use gnatlink in this case, since it cannot locate
  the binder file.


  .. index:: -r  (gnatbind)

:switch:`-r`
  Generate list of ``pragma Restrictions`` that could be applied to
  the current unit. This is useful for code audit purposes, and also may
  be used to improve code generation in some cases.


.. _Dynamic_Allocation_Control:

Dynamic Allocation Control
^^^^^^^^^^^^^^^^^^^^^^^^^^

The heap control switches -- :switch:`-H32` and :switch:`-H64` --
determine whether dynamic allocation uses 32-bit or 64-bit memory.
They only affect compiler-generated allocations via ``__gnat_malloc``;
explicit calls to ``malloc`` and related functions from the C
run-time library are unaffected.

:switch:`-H32`
  Allocate memory on 32-bit heap


:switch:`-H64`
  Allocate memory on 64-bit heap.  This is the default
  unless explicitly overridden by a ``'Size`` clause on the access type.

These switches are only effective on VMS platforms.


.. _Binding_with_Non-Ada_Main_Programs:

Binding with Non-Ada Main Programs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The description so far has assumed that the main
program is in Ada, and that the task of the binder is to generate a
corresponding function ``main`` that invokes this Ada main
program. GNAT also supports the building of executable programs where
the main program is not in Ada, but some of the called routines are
written in Ada and compiled using GNAT (:ref:`Mixed_Language_Programming`).
The following switch is used in this situation:


  .. index:: -n  (gnatbind)

:switch:`-n`
  No main program. The main program is not in Ada.

In this case, most of the functions of the binder are still required,
but instead of generating a main program, the binder generates a file
containing the following callable routines:

  .. index:: adainit

  ``adainit``
    You must call this routine to initialize the Ada part of the program by
    calling the necessary elaboration routines. A call to ``adainit`` is
    required before the first call to an Ada subprogram.

    Note that it is assumed that the basic execution environment must be setup
    to be appropriate for Ada execution at the point where the first Ada
    subprogram is called. In particular, if the Ada code will do any
    floating-point operations, then the FPU must be setup in an appropriate
    manner. For the case of the x86, for example, full precision mode is
    required. The procedure GNAT.Float_Control.Reset may be used to ensure
    that the FPU is in the right state.

  .. index:: adafinal

  ``adafinal``
    You must call this routine to perform any library-level finalization
    required by the Ada subprograms. A call to ``adafinal`` is required
    after the last call to an Ada subprogram, and before the program
    terminates.

.. index:: -n  (gnatbind)
.. index:: Binder, multiple input files

If the :switch:`-n` switch
is given, more than one ALI file may appear on
the command line for ``gnatbind``. The normal ``closure``
calculation is performed for each of the specified units. Calculating
the closure means finding out the set of units involved by tracing
|with| references. The reason it is necessary to be able to
specify more than one ALI file is that a given program may invoke two or
more quite separate groups of Ada units.

The binder takes the name of its output file from the last specified ALI
file, unless overridden by the use of the :switch:`-o file`.

.. index:: -o  (gnatbind)

The output is an Ada unit in source form that can be compiled with GNAT.
This compilation occurs automatically as part of the ``gnatlink``
processing.

Currently the GNAT run-time requires a FPU using 80 bits mode
precision. Under targets where this is not the default it is required to
call GNAT.Float_Control.Reset before using floating point numbers (this
include float computation, float input and output) in the Ada code. A
side effect is that this could be the wrong mode for the foreign code
where floating point computation could be broken after this call.


.. _Binding_Programs_with_No_Main_Subprogram:

Binding Programs with No Main Subprogram
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It is possible to have an Ada program which does not have a main
subprogram. This program will call the elaboration routines of all the
packages, then the finalization routines.

The following switch is used to bind programs organized in this manner:

  .. index:: -z  (gnatbind)

:switch:`-z`
  Normally the binder checks that the unit name given on the command line
  corresponds to a suitable main subprogram. When this switch is used,
  a list of ALI files can be given, and the execution of the program
  consists of elaboration of these units in an appropriate order. Note
  that the default wide character encoding method for standard Text_IO
  files is always set to Brackets if this switch is set (you can use
  the binder switch
  :switch:`-Wx` to override this default).


.. _Command-Line_Access:

Command-Line Access
-------------------

The package ``Ada.Command_Line`` provides access to the command-line
arguments and program name. In order for this interface to operate
correctly, the two variables

.. code-block:: c

     int gnat_argc;
     char **gnat_argv;

.. index:: gnat_argv
.. index:: gnat_argc

are declared in one of the GNAT library routines. These variables must
be set from the actual ``argc`` and ``argv`` values passed to the
main program. With no :switch:`-n` present, ``gnatbind``
generates the C main program to automatically set these variables.
If the :switch:`-n` switch is used, there is no automatic way to
set these variables. If they are not set, the procedures in
``Ada.Command_Line`` will not be available, and any attempt to use
them will raise ``Constraint_Error``. If command line access is
required, your main program must set ``gnat_argc`` and
``gnat_argv`` from the ``argc`` and ``argv`` values passed to
it.


.. _Search_Paths_for_gnatbind:

Search Paths for ``gnatbind``
-----------------------------

The binder takes the name of an ALI file as its argument and needs to
locate source files as well as other ALI files to verify object consistency.

For source files, it follows exactly the same search rules as ``gcc``
(see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`). For ALI files the
directories searched are:

* The directory containing the ALI file named in the command line, unless
  the switch :switch:`-I-` is specified.

* All directories specified by :switch:`-I`
  switches on the ``gnatbind``
  command line, in the order given.

  .. index:: ADA_PRJ_OBJECTS_FILE

* Each of the directories listed in the text file whose name is given
  by the :envvar:`ADA_PRJ_OBJECTS_FILE` environment variable.

  :envvar:`ADA_PRJ_OBJECTS_FILE` is normally set by gnatmake or by the gnat
  driver when project files are used. It should not normally be set
  by other means.

  .. index:: ADA_OBJECTS_PATH

* Each of the directories listed in the value of the
  :envvar:`ADA_OBJECTS_PATH` environment variable.
  Construct this value
  exactly as the :envvar:`PATH` environment variable: a list of directory
  names separated by colons (semicolons when working with the NT version
  of GNAT).

* The content of the :file:`ada_object_path` file which is part of the GNAT
  installation tree and is used to store standard libraries such as the
  GNAT Run-Time Library (RTL) unless the switch :switch:`-nostdlib` is
  specified. See :ref:`Installing_a_library`

.. index:: -I  (gnatbind)
.. index:: -aI  (gnatbind)
.. index:: -aO  (gnatbind)

In the binder the switch :switch:`-I`
is used to specify both source and
library file paths. Use :switch:`-aI`
instead if you want to specify
source paths only, and :switch:`-aO`
if you want to specify library paths
only. This means that for the binder
:switch:`-I{dir}` is equivalent to
:switch:`-aI{dir}`
:switch:`-aO`{dir}`.
The binder generates the bind file (a C language source file) in the
current working directory.

.. index:: Ada
.. index:: System
.. index:: Interfaces
.. index:: GNAT

The packages ``Ada``, ``System``, and ``Interfaces`` and their
children make up the GNAT Run-Time Library, together with the package
GNAT and its children, which contain a set of useful additional
library functions provided by GNAT. The sources for these units are
needed by the compiler and are kept together in one directory. 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, you need not specify these directory names when compiling
or binding. Either the environment variables or the built-in defaults
cause these files to be found.

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


.. _Examples_of_gnatbind_Usage:

Examples of ``gnatbind`` Usage
------------------------------

Here are some examples of ``gnatbind`` invocations:

  ::

     gnatbind hello

  The main program ``Hello`` (source program in :file:`hello.adb`) is
  bound using the standard switch settings. The generated main program is
  :file:`b~hello.adb`. This is the normal, default use of the binder.

  ::

     gnatbind hello -o mainprog.adb

  The main program ``Hello`` (source program in :file:`hello.adb`) is
  bound using the standard switch settings. The generated main program is
  :file:`mainprog.adb` with the associated spec in
  :file:`mainprog.ads`. Note that you must specify the body here not the
  spec. Note that if this option is used, then linking must be done manually,
  since gnatlink will not be able to find the generated file.


.. _Linking_with_gnatlink:

Linking with ``gnatlink``
=========================

.. index:: ! gnatlink

This chapter discusses ``gnatlink``, a tool that links
an Ada program and builds an executable file. This utility
invokes the system linker (via the ``gcc`` command)
with a correct list of object files and library references.
``gnatlink`` automatically determines the list of files and
references for the Ada part of a program. It uses the binder file
generated by the ``gnatbind`` to determine this list.

.. _Running_gnatlink:

Running ``gnatlink``
--------------------

The form of the ``gnatlink`` command is


.. code-block:: sh

    $ gnatlink [ switches ] mainprog [.ali]
               [ non-Ada objects ] [ linker options ]



The arguments of ``gnatlink`` (switches, main ``ALI`` file,
non-Ada objects
or linker options) may be in any order, provided that no non-Ada object may
be mistaken for a main :file:`ALI` file.
Any file name :file:`F` without the :file:`.ali`
extension will be taken as the main :file:`ALI` file if a file exists
whose name is the concatenation of :file:`F` and :file:`.ali`.

:file:`mainprog.ali` references the ALI file of the main program.
The :file:`.ali` extension of this file can be omitted. From this
reference, ``gnatlink`` locates the corresponding binder file
:file:`b~mainprog.adb` and, using the information in this file along
with the list of non-Ada objects and linker options, constructs a
linker command file to create the executable.

The arguments other than the ``gnatlink`` switches and the main
:file:`ALI` file are passed to the linker uninterpreted.
They typically include the names of
object files for units written in other languages than Ada and any library
references required to resolve references in any of these foreign language
units, or in ``Import`` pragmas in any Ada units.

``linker options`` is an optional list of linker specific
switches.
The default linker called by gnatlink is ``gcc`` which in
turn calls the appropriate system linker.

One useful option for the linker is :switch:`-s`: it reduces the size of the
executable by removing all symbol table and relocation information from the
executable.

Standard options for the linker such as :switch:`-lmy_lib` or
:switch:`-Ldir` can be added as is.
For options that are not recognized by
``gcc`` as linker options, use the ``gcc`` switches
:switch:`-Xlinker` or :switch:`-Wl,`.

Refer to the GCC documentation for
details.

Here is an example showing how to generate a linker map:

.. code-block:: sh

     $ gnatlink my_prog -Wl,-Map,MAPFILE


Using ``linker options`` it is possible to set the program stack and
heap size.
See :ref:`Setting_Stack_Size_from_gnatlink` and
:ref:`Setting_Heap_Size_from_gnatlink`.

``gnatlink`` determines the list of objects required by the Ada
program and prepends them to the list of objects passed to the linker.
``gnatlink`` also gathers any arguments set by the use of
``pragma Linker_Options`` and adds them to the list of arguments
presented to the linker.


.. _Switches_for_gnatlink:

Switches for ``gnatlink``
-------------------------

The following switches are available with the ``gnatlink`` utility:

.. index:: --version  (gnatlink)

:switch:`--version`
  Display Copyright and version, then exit disregarding all other options.


.. index:: --help  (gnatlink)

:switch:`--help`
  If :switch:`--version` was not used, display usage, then exit disregarding
  all other options.


.. index:: Command line length
.. index:: -f  (gnatlink)

:switch:`-f`
  On some targets, the command line length is limited, and ``gnatlink``
  will generate a separate file for the linker if the list of object files
  is too long.
  The :switch:`-f` switch forces this file
  to be generated even if
  the limit is not exceeded. This is useful in some cases to deal with
  special situations where the command line length is exceeded.


.. index:: Debugging information, including
.. index:: -g  (gnatlink)

:switch:`-g`
  The option to include debugging information causes the Ada bind file (in
  other words, :file:`b~mainprog.adb`) to be compiled with :switch:`-g`.
  In addition, the binder does not delete the :file:`b~mainprog.adb`,
  :file:`b~mainprog.o` and :file:`b~mainprog.ali` files.
  Without :switch:`-g`, the binder removes these files by default.

.. index:: -n  (gnatlink)

:switch:`-n`
  Do not compile the file generated by the binder. This may be used when
  a link is rerun with different options, but there is no need to recompile
  the binder file.


.. index:: -v  (gnatlink)

:switch:`-v`
  Verbose mode. Causes additional information to be output, including a full
  list of the included object files.
  This switch option is most useful when you want
  to see what set of object files are being used in the link step.


.. index:: -v -v  (gnatlink)

:switch:`-v -v`
  Very verbose mode. Requests that the compiler operate in verbose mode when
  it compiles the binder file, and that the system linker run in verbose mode.


.. index:: -o  (gnatlink)

:switch:`-o {exec-name}`
  ``exec-name`` specifies an alternate name for the generated
  executable program. If this switch is omitted, the executable has the same
  name as the main unit. For example, ``gnatlink try.ali`` creates
  an executable called :file:`try`.


.. index:: -B  (gnatlink)

:switch:`-B{dir}`
  Load compiler executables (for example, ``gnat1``, the Ada compiler)
  from ``dir`` instead of the default location. Only use this switch
  when multiple versions of the GNAT compiler are available.
  See the ``Directory Options`` section in :title:`The_GNU_Compiler_Collection`
  for further details. You would normally use the :switch:`-b` or
  :switch:`-V` switch instead.


.. index:: -M  (gnatlink)

:switch:`-M`
  When linking an executable, create a map file. The name of the map file
  has the same name as the executable with extension ".map".


.. index:: -M=  (gnatlink)

:switch:`-M={mapfile}`
  When linking an executable, create a map file. The name of the map file is
  ``mapfile``.


.. index:: --GCC=compiler_name  (gnatlink)

:switch:`--GCC={compiler_name}`
  Program used for compiling the binder file. The default is
  ``gcc``. You need to use quotes around ``compiler_name`` if
  ``compiler_name`` contains spaces or other separator characters.
  As an example ``--GCC="foo -x -y"`` will instruct ``gnatlink`` to
  use ``foo -x -y`` as your compiler. Note that switch ``-c`` is always
  inserted after your command name. Thus in the above example the compiler
  command that will be used by ``gnatlink`` will be ``foo -c -x -y``.
  A limitation of this syntax is that the name and path name of the executable
  itself must not include any embedded spaces. If the compiler executable is
  different from the default one (gcc or <prefix>-gcc), then the back end
  switches in the ALI file are not used to compile the binder generated source.
  For example, this is the case with ``--GCC="foo -x -y"``. But the back end
  switches will be used for ``--GCC="gcc -gnatv"``. If several
  ``--GCC=compiler_name`` are used, only the last ``compiler_name``
  is taken into account. However, all the additional switches are also taken
  into account. Thus,
  ``--GCC="foo -x -y" --GCC="bar -z -t"`` is equivalent to
  ``--GCC="bar -x -y -z -t"``.


.. index:: --LINK=  (gnatlink)

:switch:`--LINK={name}`
  ``name`` is the name of the linker to be invoked. This is especially
  useful in mixed language programs since languages such as C++ require
  their own linker to be used. When this switch is omitted, the default
  name for the linker is ``gcc``. When this switch is used, the
  specified linker is called instead of ``gcc`` with exactly the same
  parameters that would have been passed to ``gcc`` so if the desired
  linker requires different parameters it is necessary to use a wrapper
  script that massages the parameters before invoking the real linker. It
  may be useful to control the exact invocation by using the verbose
  switch.


.. _Using_the_GNU_make_Utility:

Using the GNU ``make`` Utility
==============================

.. index:: make (GNU), GNU make

This chapter offers some examples of makefiles that solve specific
problems. It does not explain how to write a makefile, nor does it try to replace the
``gnatmake`` utility (:ref:`The_GNAT_Make_Program_gnatmake`).

All the examples in this section are specific to the GNU version of
make. Although ``make`` is a standard utility, and the basic language
is the same, these examples use some advanced features found only in
``GNU make``.

.. _Using_gnatmake_in_a_Makefile:

Using gnatmake in a Makefile
----------------------------

.. index makefile (GNU make)

Complex project organizations can be handled in a very powerful way by
using GNU make combined with gnatmake. For instance, here is a Makefile
which allows you to build each subsystem of a big project into a separate
shared library. Such a makefile allows you to significantly reduce the link
time of very big applications while maintaining full coherence at
each step of the build process.

The list of dependencies are handled automatically by
``gnatmake``. The Makefile is simply used to call gnatmake in each of
the appropriate directories.

Note that you should also read the example on how to automatically
create the list of directories
(:ref:`Automatically_Creating_a_List_of_Directories`)
which might help you in case your project has a lot of subdirectories.


.. code-block:: makefile

  ## This Makefile is intended to be used with the following directory
  ## configuration:
  ##  - The sources are split into a series of csc (computer software components)
  ##    Each of these csc is put in its own directory.
  ##    Their name are referenced by the directory names.
  ##    They will be compiled into shared library (although this would also work
  ##    with static libraries)
  ##  - The main program (and possibly other packages that do not belong to any
  ##    csc) is put in the top level directory (where the Makefile is).
  ##       toplevel_dir __ first_csc  (sources) __ lib (will contain the library)
  ##                    \\_ second_csc (sources) __ lib (will contain the library)
  ##                    \\_ ...
  ## Although this Makefile is build for shared library, it is easy to modify
  ## to build partial link objects instead (modify the lines with -shared and
  ## gnatlink below)
  ##
  ## With this makefile, you can change any file in the system or add any new
  ## file, and everything will be recompiled correctly (only the relevant shared
  ## objects will be recompiled, and the main program will be re-linked).

  # The list of computer software component for your project. This might be
  # generated automatically.
  CSC_LIST=aa bb cc

  # Name of the main program (no extension)
  MAIN=main

  # If we need to build objects with -fPIC, uncomment the following line
  #NEED_FPIC=-fPIC

  # The following variable should give the directory containing libgnat.so
  # You can get this directory through 'gnatls -v'. This is usually the last
  # directory in the Object_Path.
  GLIB=...

  # The directories for the libraries
  # (This macro expands the list of CSC to the list of shared libraries, you
  # could simply use the expanded form:
  # LIB_DIR=aa/lib/libaa.so bb/lib/libbb.so cc/lib/libcc.so
  LIB_DIR=${foreach dir,${CSC_LIST},${dir}/lib/lib${dir}.so}

  ${MAIN}: objects ${LIB_DIR}
      gnatbind ${MAIN} ${CSC_LIST:%=-aO%/lib} -shared
      gnatlink ${MAIN} ${CSC_LIST:%=-l%}

  objects::
      # recompile the sources
      gnatmake -c -i ${MAIN}.adb ${NEED_FPIC} ${CSC_LIST:%=-I%}

  # Note: In a future version of GNAT, the following commands will be simplified
  # by a new tool, gnatmlib
  ${LIB_DIR}:
      mkdir -p ${dir $@ }
      cd ${dir $@ } && gcc -shared -o ${notdir $@ } ../*.o -L${GLIB} -lgnat
      cd ${dir $@ } && cp -f ../*.ali .

  # The dependencies for the modules
  # Note that we have to force the expansion of *.o, since in some cases
  # make won't be able to do it itself.
  aa/lib/libaa.so: ${wildcard aa/*.o}
  bb/lib/libbb.so: ${wildcard bb/*.o}
  cc/lib/libcc.so: ${wildcard cc/*.o}

  # Make sure all of the shared libraries are in the path before starting the
  # program
  run::
      LD_LIBRARY_PATH=`pwd`/aa/lib:`pwd`/bb/lib:`pwd`/cc/lib ./${MAIN}

  clean::
      ${RM} -rf ${CSC_LIST:%=%/lib}
      ${RM} ${CSC_LIST:%=%/*.ali}
      ${RM} ${CSC_LIST:%=%/*.o}
      ${RM} *.o *.ali ${MAIN}


.. _Automatically_Creating_a_List_of_Directories:

Automatically Creating a List of Directories
--------------------------------------------

In most makefiles, you will have to specify a list of directories, and
store it in a variable. For small projects, it is often easier to
specify each of them by hand, since you then have full control over what
is the proper order for these directories, which ones should be
included.

However, in larger projects, which might involve hundreds of
subdirectories, it might be more convenient to generate this list
automatically.

The example below presents two methods. The first one, although less
general, gives you more control over the list. It involves wildcard
characters, that are automatically expanded by ``make``. Its
shortcoming is that you need to explicitly specify some of the
organization of your project, such as for instance the directory tree
depth, whether some directories are found in a separate tree, etc.

The second method is the most general one. It requires an external
program, called ``find``, which is standard on all Unix systems. All
the directories found under a given root directory will be added to the
list.

.. code-block:: makefile

  # The examples below are based on the following directory hierarchy:
  # All the directories can contain any number of files
  # ROOT_DIRECTORY ->  a  ->  aa  ->  aaa
  #                       ->  ab
  #                       ->  ac
  #                ->  b  ->  ba  ->  baa
  #                       ->  bb
  #                       ->  bc
  # This Makefile creates a variable called DIRS, that can be reused any time
  # you need this list (see the other examples in this section)

  # The root of your project's directory hierarchy
  ROOT_DIRECTORY=.

  ####
  # First method: specify explicitly the list of directories
  # This allows you to specify any subset of all the directories you need.
  ####

  DIRS := a/aa/ a/ab/ b/ba/

  ####
  # Second method: use wildcards
  # Note that the argument(s) to wildcard below should end with a '/'.
  # Since wildcards also return file names, we have to filter them out
  # to avoid duplicate directory names.
  # We thus use make's ``dir`` and ``sort`` functions.
  # It sets DIRs to the following value (note that the directories aaa and baa
  # are not given, unless you change the arguments to wildcard).
  # DIRS= ./a/a/ ./b/ ./a/aa/ ./a/ab/ ./a/ac/ ./b/ba/ ./b/bb/ ./b/bc/
  ####

  DIRS := ${sort ${dir ${wildcard ${ROOT_DIRECTORY}/*/
                      ${ROOT_DIRECTORY}/*/*/}}}

  ####
  # Third method: use an external program
  # This command is much faster if run on local disks, avoiding NFS slowdowns.
  # This is the most complete command: it sets DIRs to the following value:
  # DIRS= ./a ./a/aa ./a/aa/aaa ./a/ab ./a/ac ./b ./b/ba ./b/ba/baa ./b/bb ./b/bc
  ####

  DIRS := ${shell find ${ROOT_DIRECTORY} -type d -print}



.. _Generating_the_Command_Line_Switches:

Generating the Command Line Switches
------------------------------------

Once you have created the list of directories as explained in the
previous section (:ref:`Automatically_Creating_a_List_of_Directories`),
you can easily generate the command line arguments to pass to gnatmake.

For the sake of completeness, this example assumes that the source path
is not the same as the object path, and that you have two separate lists
of directories.

.. code-block:: makefile

  # see "Automatically creating a list of directories" to create
  # these variables
  SOURCE_DIRS=
  OBJECT_DIRS=

  GNATMAKE_SWITCHES := ${patsubst %,-aI%,${SOURCE_DIRS}}
  GNATMAKE_SWITCHES += ${patsubst %,-aO%,${OBJECT_DIRS}}

  all:
          gnatmake ${GNATMAKE_SWITCHES} main_unit


.. _Overcoming_Command_Line_Length_Limits:

Overcoming Command Line Length Limits
-------------------------------------

One problem that might be encountered on big projects is that many
operating systems limit the length of the command line. It is thus hard to give
gnatmake the list of source and object directories.

This example shows how you can set up environment variables, which will
make ``gnatmake`` behave exactly as if the directories had been
specified on the command line, but have a much higher length limit (or
even none on most systems).

It assumes that you have created a list of directories in your Makefile,
using one of the methods presented in
:ref:`Automatically_Creating_a_List_of_Directories`.
For the sake of completeness, we assume that the object
path (where the ALI files are found) is different from the sources patch.

Note a small trick in the Makefile below: for efficiency reasons, we
create two temporary variables (SOURCE_LIST and OBJECT_LIST), that are
expanded immediately by ``make``. This way we overcome the standard
make behavior which is to expand the variables only when they are
actually used.

On Windows, if you are using the standard Windows command shell, you must
replace colons with semicolons in the assignments to these variables.

.. code-block:: makefile

  # In this example, we create both ADA_INCLUDE_PATH and ADA_OBJECTS_PATH.
  # This is the same thing as putting the -I arguments on the command line.
  # (the equivalent of using -aI on the command line would be to define
  #  only ADA_INCLUDE_PATH, the equivalent of -aO is ADA_OBJECTS_PATH).
  # You can of course have different values for these variables.
  #
  # Note also that we need to keep the previous values of these variables, since
  # they might have been set before running 'make' to specify where the GNAT
  # library is installed.

  # see "Automatically creating a list of directories" to create these
  # variables
  SOURCE_DIRS=
  OBJECT_DIRS=

  empty:=
  space:=${empty} ${empty}
  SOURCE_LIST := ${subst ${space},:,${SOURCE_DIRS}}
  OBJECT_LIST := ${subst ${space},:,${OBJECT_DIRS}}
  ADA_INCLUDE_PATH += ${SOURCE_LIST}
  ADA_OBJECTS_PATH += ${OBJECT_LIST}
  export ADA_INCLUDE_PATH
  export ADA_OBJECTS_PATH

  all:
          gnatmake main_unit

.. _GNATLLVM:

GNAT with the LLVM Back End
===========================

This section outlines the usage of the GNAT compiler with the LLVM
back end and highlights its key limitations. Certain GNAT versions,
referred to as GNAT LLVM, include an alternative LLVM back end
alongside the GCC back end, providing access to utilities that operate
at the LLVM Intermediate Representation (IR) level. This also enhances
safety by facilitating dissimilar redundancy through diverse code
generation techniques, allowing for the creation of two distinct
binaries from the same source code.

Although both GNAT LLVM and the GCC-based GNAT follow most ABI rules,
there are some cases where there you may encounter an incompatibility
between the two compilers.  One such case for the 64-bit Intel X86 is
a difference in parameter passing when a structure that consists of 64
bits is passed. The native LLVM handling (and hence that of GNAT LLVM)
and ``clang`` disagree in this case. GCC follows ``clang``. The formal
ABI agrees with LLVM.

In any case, we don't recommend you link code compiled with GNAT LLVM
to code compiled by the GCC version of GNAT. This is a specific case
of the general rule that you should compile all your Ada code with the
same version of GNAT. Both ``gnatmake`` and ``gprbuild`` ensure this
is done.

You may, however, run into this incompatibility if you pass such a
record between C and Ada. In general, we recommend keeping the data
passed between C and Ada as simple as practical.

GNAT LLVM currently provides limited support for debugging data. It
provides full line number information for declarations and statements,
and complete debugging data for all types.

In some situations, a name in the source may not be available.  For
example, renamings are not currently emitted into the debugging data.

In addition, debugging information may be confusing if you have
``out`` parameters to subprograms. If you have a procedure with only
one ``out`` parameter, GNAT LLVM converts that to a function returning
an object of that type. If you have multiple ``out`` parameters or
have a function that also has an ``out`` parameter, GNAT LLVM converts
that subprogram into a function that returns a record where each field
is either an ``out`` parameter or the function return value, if any.
The debug information reflects these transformations and not the original
Ada source code.

GNAT LLVM doesn't fully implement the :switch:`-fstack-check` switch.
When you specify it, the code generated by GNAT LLVM tests for allocating
overly-large items on the stack, but not all cases of stack overflow.  For
example, if you have a very deep recursion where each call only uses a
small amount of stack and the total stack depth exceeds the amount of
available stack, the program will be terminated by a signal instead of
raising an Ada exception.

GNAT LLVM doesn't support the ``Scalar_Storage_Order`` attribute except when
it's used to confirm the chosen storage order. This is because this facility
is provided by GCC but not by LLVM.

GNAT LLVM doesn't support Convention C++, which provides so-called
'name mangling' by encoding parameter and return datatypes into a
function name.

The inline assembler in GNAT LLVM is not yet feature complete. For example, it
can't handle more than one output variable, and it doesn't support all
constraints.

.. only:: PRO

    Unlike the GCC versions of GNAT, GNAT LLVM doesn't include any
    Ada libraries. You can obtain source packages from GNATtracker and
    build them with the compiler configuration appropriate for your
    project. AdaCore internally builds and tests the GNAT Components
    Collection, XML/Ada, and AUnit libraries to ensure compatibility
    with GNAT LLVM, but not all options of those libraries are
    currently supported with all targets of GNAT LLVM. If you need to
    use any of these libraries, please open a support ticket.

We provide two options that you can use to build code with GNAT LLVM:

* GNAT LLVM includes a version of ``gnatmake`` called
  ``llvm-gnatmake``, which is equivalent to ``gnatmake`` and has the
  same switches, except that it uses GNAT LLVM instead of the GCC
  version of GNAT.

* ``gprbuild`` can detect and use GNAT LLVM when it is installed.

  ``gprbuild`` uses the first applicable compiler on the executable search
  path, including GNAT LLVM. An easy way to build with GNAT LLVM is to make
  it available on the operating system's search path before any other Ada
  compiler (such as the GCC version of GNAT). To avoid accidentally using a
  different compiler than the one you want to use, we recommend explicitly
  selecting GNAT LLVM in your existing GPR project file by adding
  :code:`for Toolchain_Name ("Ada") use "GNAT_LLVM";`. You can also
  generate an explicit toolchain configuration file with ``gprconfig`` and
  use it with ``gprbuild``; see the *GPRbuild and GPR Companion Tools
  User's Guide* for details. You can determine from the first line of the
  :file:`.ali` file which version of GNAT built that file because it
  contains either :code:`GNAT` or :code:`GNAT-LLVM`.

.. only:: PRO

    If your project uses one of the libraries packaged with the GCC
    version of GNAT, it is important that you use the GPR tools from
    the GNAT LLVM package when building with GNAT LLVM. Otherwise,
    ``gprbuild`` would try to use the precompiled libraries shipped with
    the GCC version of GNAT, mixing those objects with code generated
    by GNAT LLVM, which is not supported.

GNAT LLVM understands the same target triplets as the GCC version of
GNAT.

.. only:: PRO

  It provides the same runtimes.

---

### Gcc Ada Doc Gnat Ugn Elaboration Order Handling In Gnat (`gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst`)

.. role:: switch(samp)

.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing

.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit


.. _Elaboration_Order_Handling_in_GNAT:

**********************************
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 you can control the order of elaboration of program units in
GNAT, either automatically or with explicit programming features.

.. _Elaboration_Code:

Elaboration Code
================

Ada defines the term *execution* as the process by which a construct achieves
its run-time effect. This process is also referred to as **elaboration** for
declarations and *evaluation* for expressions.

The execution model in Ada allows for certain sections of an Ada program to be
executed prior to execution of the program itself, primarily with the intent of
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.

* The execution of a partition involves running the environment task for that
  partition.

* The environment task executes all elaboration code (if available) for all
  units within that partition. This code is said to be executed at
  **elaboration time**.

* The environment task executes the Ada program (if available) for that
  partition.

In addition to the Ada terminology, this appendix defines the following terms:

* *Invocation*

  The act of calling a subprogram, instantiating a generic, or activating a
  task.

* *Scenario*

  A construct that is elaborated or invoked by elaboration code is referred to
  as an *elaboration scenario* or simply a **scenario**. GNAT recognizes the
  following scenarios:

  - ``'Access`` of entries, operators, and subprograms

  - Activation of tasks

  - Calls to entries, operators, and subprograms

  - Instantiations of generic templates

* *Target*

  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.

  - For activation of tasks, the target is the task body

  - For calls to entries, operators, and subprograms, the target is the entry,
    operator, or subprogram being invoked.

  - For instantiations of generic templates, the target is the generic template
    being instantiated.

Elaboration code may appear in two distinct contexts:

* *Library level*

  A scenario appears at the library level when it is encapsulated by a package
  [body] compilation unit, ignoring any other package [body] declarations in
  between.

  .. code-block:: ada

     with Server;
     package Client is
        procedure Proc;

        package Nested is
           Val : ... := Server.Func;
        end Nested;
     end Client;

  In the example above, the call to ``Server.Func`` is an elaboration scenario
  because it appears at the library level of package ``Client``. Note that the
  declaration of package ``Nested`` is ignored according to the definition
  given above. As a result, the call to ``Server.Func`` will be invoked when
  the spec of unit ``Client`` is elaborated.

* *Package body statements*

  A scenario appears within the statement sequence of a package body when it is
  bounded by the region starting from the ``begin`` keyword of the package body
  and ending at the ``end`` keyword of the package body.

  .. code-block:: ada

     package body Client is
        procedure Proc is
        begin
           ...
        end Proc;
     begin
        Proc;
     end Client;

  In the example above, the call to ``Proc`` is an elaboration scenario because
  it appears within the statement sequence of package body ``Client``. As a
  result, the call to ``Proc`` will be invoked when the body of ``Client`` is
  elaborated.

.. _Elaboration_Order:

Elaboration Order
=================

The sequence by which the elaboration code of all units within a partition is
executed is referred to as **elaboration order**.

Within a single unit, elaboration code is executed in sequential order.

  .. code-block:: ada

     package body Client is
        Result : ... := Server.Func;

        procedure Proc is
           package Inst is new Server.Gen;
        begin
           Inst.Eval (Result);
        end Proc;
     begin
        Proc;
     end Client;

In the example above, the elaboration order within package body ``Client`` is
as follows:

1. The object declaration of ``Result`` is elaborated.

   * Function ``Server.Func`` is invoked.

2. The subprogram body of ``Proc`` is elaborated.

3. Procedure ``Proc`` is invoked.

   * Generic unit ``Server.Gen`` is instantiated as ``Inst``.

   * Instance ``Inst`` is elaborated.

   * Procedure ``Inst.Eval`` is invoked.

The elaboration order of all units within a partition depends on the following
factors:

* |withed| units

* parent units

* purity of units

* preelaborability of units

* presence of elaboration-control pragmas

* invocations performed in elaboration code

A program may have several possible elaboration orders depending on
its structure:

  .. code-block:: ada

     package Server is
        function Func (Index : Integer) return Integer;
     end Server;

  .. code-block:: ada

     package body Server is
        Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5);

        function Func (Index : Integer) return Integer is
        begin
           return Results (Index);
        end Func;
     end Server;

  .. code-block:: ada

     with Server;
     package Client is
        Val : constant Integer := Server.Func (3);
     end Client;

  .. code-block:: ada

     with Client;
     procedure Main is begin null; end Main;

The following elaboration order exhibits a fundamental problem referred to as
*access-before-elaboration* or simply **ABE**.

  ::

     spec of Server
     spec of Client
     body of Server
     body of Main

The elaboration of ``Server``'s spec materializes function ``Func``, making it
callable. The elaboration of ``Client``'s spec elaborates the declaration of
``Val``. This invokes function ``Server.Func``, however the body of
``Server.Func`` has not been elaborated yet because ``Server``'s body comes
after ``Client``'s spec in the elaboration order. As a result, the value of
constant ``Val`` is now undefined.

Without any guarantees from the language, an undetected ABE problem may hinder
proper initialization of data, which in turn may lead to undefined behavior at
run time. To prevent such ABE problems, Ada employs dynamic checks in the same
vein as index or null exclusion checks. A failed ABE check raises exception
``Program_Error``.

The following elaboration order avoids the ABE problem and the program can be
successfully elaborated.

  ::

     spec of Server
     body of Server
     spec of Client
     body of Main

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,
however a compiler may not always find such an order due to complications with
respect to control and data flow.

.. _Checking_the_Elaboration_Order:

Checking the Elaboration Order
==============================

To avoid placing the entire elaboration-order burden on the programmer, Ada
provides three lines of defense:

* *Static semantics*

  Static semantic rules restrict the possible choice of elaboration order. For
  instance, if unit Client |withs| unit Server, then the spec of Server is
  always elaborated prior to Client. The same principle applies to child units
  - the spec of a parent unit is always elaborated prior to the child unit.

* *Dynamic semantics*

  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:

  - *Restrictions on calls*

    An entry, operator, or subprogram can be called from elaboration code only
    when the corresponding body has been elaborated.

  - *Restrictions on instantiations*

    A generic unit can be instantiated by elaboration code only when the
    corresponding body has been elaborated.

  - *Restrictions on task activation*

    A task can be activated by elaboration code only when the body of the
    associated task type has been elaborated.

  The restrictions above can be summarized by the following rule:

  *If a target has a body, then this body must be elaborated prior to the
  scenario that invokes the target.*

* *Elaboration control*

  Ada provides pragmas for you to specify the desired elaboration
  order.

.. _Controlling_the_Elaboration_Order_in_Ada:

Controlling the Elaboration Order in Ada
========================================

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 that does not require a completing body does not suffer
  from ABE problems.

  .. code-block:: ada

     package Pack is
        generic
           type Element is private;
        package Containers is
           type Element_Array is array (1 .. 10) of Element;
        end Containers;
     end Pack;

  In the example above, package ``Pack`` does not require a body because it
  does not contain any constructs which require completion in a body. As a
  result, generic ``Pack.Containers`` can be instantiated without encountering
  any ABE problems.

.. index:: pragma Pure

* *pragma Pure*

  Pragma ``Pure`` places sufficient restrictions on a unit to guarantee that no
  scenario within the unit can result in an ABE problem.

.. index:: pragma Preelaborate

* *pragma Preelaborate*

  Pragma ``Preelaborate`` is slightly less restrictive than pragma ``Pure``,
  but still strong enough to prevent ABE problems within a unit.

.. index:: pragma Elaborate_Body

* *pragma Elaborate_Body*

  Pragma ``Elaborate_Body`` requires that the body of a unit is elaborated
  immediately after its spec. This restriction guarantees that no client
  scenario can invoke a server target before the target body has been
  elaborated because the spec and body are effectively "glued" together.

  .. code-block:: ada

     package Server is
        pragma Elaborate_Body;

        function Func return Integer;
     end Server;

  .. code-block:: ada

     package body Server is
        function Func return Integer is
        begin
           ...
        end Func;
     end Server;

  .. code-block:: ada

     with Server;
     package Client is
        Val : constant Integer := Server.Func;
     end Client;

  In the example above, pragma ``Elaborate_Body`` guarantees the following
  elaboration order:

  ::

     spec of Server
     body of Server
     spec of Client

  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:

  ::

     spec of Server
     spec of Client
     body of Server

  where ``Client`` invokes ``Server.Func``, but the body of ``Server.Func`` has
  not been elaborated yet.

The pragmas outlined above allow a server unit to guarantee safe elaboration
use by client units. Thus it is a good rule to mark units as ``Pure`` or
``Preelaborate``, and if this is not possible, mark them as ``Elaborate_Body``.

There are however situations where ``Pure``, ``Preelaborate``, and
``Elaborate_Body`` are not applicable. Ada provides another set of pragmas for
use by client units to help ensure the elaboration safety of server units they
depend on.

.. index:: pragma Elaborate (Unit)

* *pragma Elaborate (Unit)*

  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.

  .. code-block:: ada

     package Server is
        function Func return Integer;
     end Server;

  .. code-block:: ada

     package body Server is
        function Func return Integer is
        begin
           ...
        end Func;
     end Server;

  .. code-block:: ada

     with Server;
     pragma Elaborate (Server);
     package Client is
        Val : constant Integer := Server.Func;
     end Client;

  In the example above, pragma ``Elaborate`` guarantees the following
  elaboration order:

  ::

     spec of Server
     body of Server
     spec of Client

  Removing pragma ``Elaborate`` could result in the following incorrect
  elaboration order:

  ::

     spec of Server
     spec of Client
     body of Server

  where ``Client`` invokes ``Server.Func``, but the body of ``Server.Func``
  has not been elaborated yet.

.. index:: pragma Elaborate_All (Unit)

* *pragma Elaborate_All (Unit)*

  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

     package Math is
        function Factorial (Val : Natural) return Natural;
     end Math;

  .. code-block:: ada

     package body Math is
        function Factorial (Val : Natural) return Natural is
        begin
           ...;
        end Factorial;
     end Math;

  .. code-block:: ada

     package Computer is
        type Operation_Kind is (None, Op_Factorial);

        function Compute
          (Val : Natural;
           Op  : Operation_Kind) return Natural;
     end Computer;

  .. code-block:: ada

     with Math;
     package body Computer is
        function Compute
          (Val : Natural;
           Op  : Operation_Kind) return Natural
        is
           if Op = Op_Factorial then
              return Math.Factorial (Val);
           end if;

           return 0;
        end Compute;
     end Computer;

  .. code-block:: ada

     with Computer;
     pragma Elaborate_All (Computer);
     package Client is
        Val : constant Natural :=
                Computer.Compute (123, Computer.Op_Factorial);
     end Client;

  In the example above, pragma ``Elaborate_All`` can result in the following
  elaboration order:

  ::

     spec of Math
     body of Math
     spec of Computer
     body of Computer
     spec of Client

  Note that there are several allowable suborders for the specs and bodies of
  ``Math`` and ``Computer``, but the point is that these specs and bodies will
  be elaborated prior to ``Client``.

  Removing pragma ``Elaborate_All`` could result in the following incorrect
  elaboration order:

  ::

     spec of Math
     spec of Computer
     body of Computer
     spec of Client
     body of Math

  where ``Client`` invokes ``Computer.Compute``, which in turn invokes
  ``Math.Factorial``, but the body of ``Math.Factorial`` has not been
  elaborated yet.

All pragmas shown above can be summarized by the following rule:

*If a client unit elaborates a server target directly or indirectly, then if
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 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
  executable program.

* *One or more incorrect elaboration orders exist*

  In this case a compiler can build an executable program, but
  ``Program_Error`` will be raised when the program is run.

* *Several elaboration orders exist, some correct, some incorrect*

  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 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
  run successfully. This state may be guaranteed by following the outlined
  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
orders exist) even if maintenance changes the bodies of targets.

.. _Controlling_the_Elaboration_Order_in_GNAT:

Controlling the Elaboration Order in GNAT
=========================================

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

* *Dynamic elaboration model*

  This is the most permissive of the three elaboration models and emulates the
  behavior specified by the Ada Reference Manual. When the dynamic model is in
  effect, GNAT makes the following assumptions:

  - All code within all units in a partition is considered to be elaboration
    code.

  - Some of the invocations in elaboration code may not take place at run time
    due to conditional execution.

  GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
  that invoke internal targets. In addition, GNAT generates run-time checks for
  all external targets and for all scenarios that may exhibit ABE problems.

  The elaboration order is obtained by honoring all |with| clauses, purity and
  preelaborability of units, and elaboration-control pragmas. The dynamic model
  attempts to take all invocations in elaboration code into account. If an
  invocation leads to a circularity, GNAT ignores the invocation based on the
  assumptions stated above. An order obtained using the dynamic model may fail
  an ABE check at run time when GNAT ignored an invocation.

  You enable the dynamic model with the compiler switch :switch:`-gnatE`.

.. index:: Static elaboration model

* *Static elaboration model*

  This is the middle ground of the three models. When the static model is in
  effect, GNAT makes the following assumptions:

  - Only code at the library level and in package body statements within all
    units in a partition is considered to be elaboration code.

  - All invocations in elaboration will take place at run time, regardless of
    conditional execution.

  GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
  that invoke internal targets. In addition, GNAT generates run-time checks for
  all external targets and for all scenarios that may exhibit ABE problems.

  The elaboration order is obtained by honoring all |with| clauses, purity and
  preelaborability of units, presence of elaboration-control pragmas, and all
  invocations in elaboration code. An order obtained using the static model is
  guaranteed to be ABE problem-free, excluding dispatching calls and
  access-to-subprogram types.

  The static model is the default model in GNAT.

.. index:: SPARK elaboration model

* *SPARK elaboration model*

  This is the most conservative of the three models and enforces the SPARK
  rules of elaboration as defined in the SPARK Reference Manual, section 7.7.
  The SPARK model is in effect only when a scenario and a target reside in a
  region subject to ``SPARK_Mode On``, otherwise the dynamic or static model
  is in effect.

  The SPARK model is enabled with compiler switch :switch:`-gnatd.v`.

.. index:: Legacy elaboration models

* *Legacy elaboration models*

  In addition to the three elaboration models outlined above, GNAT provides the
  following legacy models:

  - `Legacy elaboration-checking model` available in pre-18.x versions of GNAT.
    You can enable this model with compiler switch :switch:`-gnatH`.

  - `Legacy elaboration-order model` available in pre-20.x versions of GNAT.
    You can enable this model with binder switch :switch:`-H`.

.. index:: Relaxed elaboration mode

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
=========================

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:

  - The server unit is compiled with the dynamic model.

  - The server unit is a GNAT implementation unit from the ``Ada``, ``GNAT``,
    ``Interfaces``, or ``System`` hierarchies.

  - The server unit has pragma ``Pure`` or ``Preelaborate``.

  - The client unit has an explicit ``Elaborate_All`` pragma for the server
    unit.

These rules ensure that elaboration checks are not omitted. If the rules are
violated, the binder emits a warning:

  ::

     warning: "x.ads" has dynamic elaboration checks and with's
     warning:   "y.ads" which has static elaboration checks

You can suppress these warnings by specifying binder switch :switch:`-ws`.

.. _ABE_Diagnostics:

ABE Diagnostics
===============

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 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 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.

  .. code-block:: ada

     package body Guaranteed_ABE is
        function ABE return Integer;

        Val : constant Integer := ABE;

        function ABE return Integer is
        begin
          ...
        end ABE;
     end Guaranteed_ABE;

In the example above, the elaboration of ``Guaranteed_ABE``'s body elaborates
the declaration of ``Val``. This invokes function ``ABE``, however the body of
``ABE`` has not been elaborated yet. GNAT emits the following diagnostic:

  ::

     4.    Val : constant Integer := ABE;
                                     |
        >>> warning: cannot call "ABE" before body seen
        >>> 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.

  .. code-block:: ada

      1. package body Conditional_ABE is
      2.    procedure Force_Body is null;
      3.
      4.    generic
      5.       with function Func return Integer;
      6.    package Gen is
      7.       Val : constant Integer := Func;
      8.    end Gen;
      9.
     10.    function ABE return Integer;
     11.
     12.    function Cause_ABE return Boolean is
     13.       package Inst is new Gen (ABE);
     14.    begin
     15.       ...
     16.    end Cause_ABE;
     17.
     18.    Val : constant Boolean := Cause_ABE;
     19.
     20.    function ABE return Integer is
     21.    begin
     22.       ...
     23.    end ABE;
     24.
     25.    Safe : constant Boolean := Cause_ABE;
     26. end Conditional_ABE;

In the example above, the elaboration of package body ``Conditional_ABE``
elaborates the declaration of ``Val``. This invokes function ``Cause_ABE``,
which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of
``Inst`` invokes function ``ABE``, however the body of ``ABE`` has not been
elaborated yet. GNAT emits the following diagnostic:

  ::

     13.       package Inst is new Gen (ABE);
               |
         >>> warning: in instantiation at line 7
         >>> warning: cannot call "ABE" before body seen
         >>> warning: Program_Error may be raised at run time
         >>> warning:   body of unit "Conditional_ABE" elaborated
         >>> warning:   function "Cause_ABE" called at line 18
         >>> warning:   function "ABE" called at line 7, instance at line 13

Note that the same ABE problem does not occur with the elaboration of
declaration ``Safe`` because the body of function ``ABE`` has already been
elaborated at that point.

.. _SPARK_Diagnostics:

SPARK Diagnostics
=================

GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference
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.

  ::

     1. with Server;
     2. package body SPARK_Diagnostics with SPARK_Mode is
     3.    Val : constant Integer := Server.Func;
                                           |
        >>> call to "Func" during elaboration in SPARK
        >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server"
        >>>   body of unit "SPARK_Model" elaborated
        >>>   function "Func" called at line 3

     4. end SPARK_Diagnostics;

.. _Elaboration_Circularities:

Elaboration Circularities
=========================

An **elaboration circularity** occurs whenever the elaboration of a set of
units enters a deadlocked state, where each unit is waiting for another unit
to be elaborated. This situation may be the result of improper use of |with|
clauses, elaboration-control pragmas, or invocations in elaboration code.

The following example exhibits an elaboration circularity.

  .. code-block:: ada

     with B; pragma Elaborate (B);
     package A is
     end A;

  .. code-block:: ada

     package B is
        procedure Force_Body;
     end B;

  .. code-block:: ada

     with C;
     package body B is
        procedure Force_Body is null;

        Elab : constant Integer := C.Func;
     end B;

  .. code-block:: ada

     package C is
        function Func return Integer;
     end C;

  .. code-block:: ada

     with A;
     package body C is
        function Func return Integer is
        begin
           ...
        end Func;
     end C;

The binder emits the following diagnostic:

  ::

     error: Elaboration circularity detected
     info:
     info:    Reason:
     info:
     info:      unit "a (spec)" depends on its own elaboration
     info:
     info:    Circularity:
     info:
     info:      unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)"
     info:      unit "b (body)" is in the closure of pragma Elaborate
     info:      unit "b (body)" invokes a construct of unit "c (body)" at elaboration time
     info:      unit "c (body)" has with clause for unit "a (spec)"
     info:
     info:    Suggestions:
     info:
     info:      remove pragma Elaborate for unit "b (body)" in unit "a (spec)"
     info:      use the dynamic elaboration model (compiler switch -gnatE)

The diagnostic consist of the following sections:

* Reason

  This section provides a short explanation describing why the set of units
  could not be ordered.

* Circularity

  This section enumerates the units comprising the deadlocked set, along with
  their interdependencies.

* Suggestions

  This section enumerates various tactics for eliminating the circularity.

.. _Resolving_Elaboration_Circularities:

Resolving Elaboration Circularities
===================================

The most desirable option from the point of view of long-term maintenance is to
rearrange the program so that the elaboration problems are avoided. One useful
technique is to place the elaboration code into separate child packages.
Another is to move some of the initialization code to explicitly invoked
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, 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
invocations at elaboration time, the binder may suggest one or more of the
following tactics to eliminate the circularity:

* Pragma Elaborate elimination

  ::

     remove pragma Elaborate for unit "..." in unit "..."

  The binder suggests this tactic when it has determined that:

  - 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
    prior to the unit containing the pragma.

  - The removal of the pragma will enable the successful ordering of the units.

  You should remove the pragma as advised and rebuild the program.

* Pragma Elaborate_All elimination

  ::

     remove pragma Elaborate_All for unit "..." in unit "..."

  The binder suggests this tactic when it has determined that:

  - 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|
    closure will still be elaborated prior to the unit containing the pragma.

  - The removal of the pragma will enable the successful ordering of the units.

  You should remove the pragma as advised and rebuild the program.

* Pragma Elaborate_All downgrade

  ::

     change pragma Elaborate_All for unit "..." to Elaborate in unit "..."

  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.

  You should update the pragma as advised and rebuild the program.

* Pragma Elaborate_Body elimination

  ::

     remove pragma Elaborate_Body in unit "..."

  The binder suggests this tactic when it has determined that:

  - pragma ``Elaborate_Body`` prevents a set of units from being elaborated.

  - The removal of the pragma will enable the successful ordering of the units.

  Note that the binder cannot determine whether the pragma is required for
  other purposes, such as guaranteeing the initialization of a variable
  declared in the spec by elaboration code in the body.

  If the pragma is not required for another purpose, you should remove
  the pragma as advised and rebuild the program.

* Use of pragma Restrictions

  ::

     use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code)

  The binder suggests this tactic when it has determined that a task
  activation at elaboration time:

  - Prevents a set of units from being elaborated.

  Note that the binder cannot determine with certainty whether the task will
  block at elaboration time.

  The programmer should create a configuration file, place the pragma within,
  update the general compilation arguments, and rebuild the program.

* Use of dynamic elaboration model

  ::

     use the dynamic elaboration model (compiler switch -gnatE)

  This tactic is suggested when the binder has determined that an invocation at
  elaboration time:

  - Prevents a set of units from being elaborated.

  - The use of the dynamic model will enable the successful ordering of the
    units.

  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 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 global compilation arguments.

* Use of detailed invocation information

  ::

     use detailed invocation information (compiler switch -gnatd_F)

  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.

  You should analyze this information to determine which units should
  be compiled with the dynamic model.

* Forced-dependency elimination

  ::

     remove the dependency of unit "..." on unit "..." from the argument of 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.

  You should edit the forced-elaboration-order file, remove the
  dependency, and rebind the program.

* All forced-dependency elimination

  ::

     remove switch -f

  The binder suggests this tactic when editing the
  forced-elaboration-order file is not an option.

  You should remove binder switch :switch:`-f` from the binder
  arguments and rebind.

* Multiple-circularities diagnostic

  ::

     diagnose all circularities (binder switch -d_C)

  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.

  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, 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
  :switch:`-H`.

* Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
  switch :switch:`-gnatH` and binder switch :switch:`-H`.

* Use the relaxed static-elaboration model, with compiler switches
  :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`.

* Use the relaxed dynamic-elaboration model, with compiler switches
  :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch
  :switch:`-H`.

.. _Elaboration_Related_Compiler_Switches:

Elaboration-related Compiler Switches
=====================================

GNAT has several switches that affect the elaboration model and consequently
the elaboration order chosen by the binder.

.. index:: -gnatE  (gnat)

:switch:`-gnatE`
  Dynamic elaboration checking mode enabled

  When this switch is in effect, GNAT activates the dynamic model.

.. index:: -gnatel  (gnat)

:switch:`-gnatel`
  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
  ``Elaborate`` and ``Elaborate_All`` pragmas to order units.

  When this switch is in effect, GNAT will emit the following supplementary
  information depending on the elaboration model in effect.

  - *Dynamic model*

    GNAT will indicate missing ``Elaborate`` and ``Elaborate_All`` pragmas for
    all library-level scenarios within the partition.

  - *Static model*

    GNAT will indicate all scenarios invoked during elaboration. In addition,
    it will provide detailed traceback when an implicit ``Elaborate`` or
    ``Elaborate_All`` pragma is generated.

  - *SPARK model*

    GNAT will indicate how an elaboration requirement is met by the context of
    a unit. This diagnostic requires compiler switch :switch:`-gnatd.v`.

    ::

       1. with Server; pragma Elaborate_All (Server);
       2. package Client with SPARK_Mode is
       3.    Val : constant Integer := Server.Func;
                                             |
          >>> info: call to "Func" during elaboration in SPARK
          >>> info: "Elaborate_All" requirement for unit "Server" met by pragma at line 1

       4. end Client;

.. index:: -gnatH  (gnat)

:switch:`-gnatH`
  Legacy elaboration checking mode enabled

  When this switch is in effect, GNAT will utilize the pre-18.x elaboration
  model.

.. index:: -gnatJ  (gnat)

:switch:`-gnatJ`
  Relaxed elaboration checking mode enabled

  When this switch is in effect, GNAT will not process certain scenarios,
  resulting in a more permissive elaboration model. Note that this may
  eliminate some diagnostics and run-time checks.

.. index:: -gnatw.f  (gnat)

:switch:`-gnatw.f`
  Turn on warnings for suspicious Subp'Access

  When this switch is in effect, GNAT will treat ``'Access`` of an entry,
  operator, or subprogram as a potential call to the target and issue warnings:

  ::

     1. package body Attribute_Call is
     2.    function Func return Integer;
     3.    type Func_Ptr is access function return Integer;
     4.
     5.    Ptr : constant Func_Ptr := Func'Access;
                                          |
        >>> warning: "Access" attribute of "Func" before body seen
        >>> warning: possible Program_Error on later references
        >>> warning:   body of unit "Attribute_Call" elaborated
        >>> warning:   "Access" of "Func" taken at line 5

     6.
     7.    function Func return Integer is
     8.    begin
     9.       ...
    10.    end Func;
    11. end Attribute_Call;

  In the example above, the elaboration of declaration ``Ptr`` is assigned
  ``Func'Access`` before the body of ``Func`` has been elaborated.

.. index:: -gnatwl  (gnat)

:switch:`-gnatwl`
  Turn on warnings for elaboration problems

  When this switch is in effect, GNAT emits diagnostics in the form of warnings
  concerning various elaboration problems. The warnings are enabled by default.
  The switch is provided in case all warnings are suppressed, but elaboration
  warnings are still desired.

:switch:`-gnatwL`
  Turn off warnings for elaboration problems

  When this switch is in effect, GNAT no longer emits any diagnostics in the
  form of warnings. Selective suppression of elaboration problems is possible
  using ``pragma Warnings (Off)``.

  ::

     1. package body Selective_Suppression is
     2.    function ABE return Integer;
     3.
     4.    Val_1 : constant Integer := ABE;
                                       |
        >>> warning: cannot call "ABE" before body seen
        >>> warning: Program_Error will be raised at run time

     5.
     6.    pragma Warnings (Off);
     7.    Val_2 : constant Integer := ABE;
     8.    pragma Warnings (On);
     9.
    10.    function ABE return Integer is
    11.    begin
    12.       ...
    13.    end ABE;
    14. end Selective_Suppression;

  Note that suppressing elaboration warnings does not eliminate run-time
  checks. The example above will still fail at run time with an ABE.

.. _Summary_of_Procedures_for_Elaboration_Control:

Summary of Procedures for Elaboration Control
=============================================

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, 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, you have several
options:

* 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. You enable elaboration warnings with compiler switch
  :switch:`-gnatwl`.

* Cosider the tactics given in the suggestions section of the circularity
  diagnostic.

* If none of the steps outlined above resolve the circularity, use a more
  permissive elaboration model, in the following order:

  - Use the pre-20.x legacy elaboration-order model, with binder switch
    :switch:`-H`.

  - Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
    switch :switch:`-gnatH` and binder switch :switch:`-H`.

  - Use the relaxed static elaboration model, with compiler switches
    :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`.

  - Use the relaxed dynamic elaboration model, with compiler switches
    :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch
    :switch:`-H`.

.. _Inspecting_the_Chosen_Elaboration_Order:

Inspecting the Chosen Elaboration Order
=======================================

To see the elaboration order chosen by the binder, inspect the contents of file
`b~xxx.adb`. On certain targets, this file appears as `b_xxx.adb`. The
elaboration order appears as a sequence of calls to ``Elab_Body`` and
``Elab_Spec``, interspersed with assignments to `Exxx` which indicates that a
particular unit is elaborated. For example:

  ::

     System.Soft_Links'Elab_Body;
     E14 := True;
     System.Secondary_Stack'Elab_Body;
     E18 := True;
     System.Exception_Table'Elab_Body;
     E24 := True;
     Ada.Io_Exceptions'Elab_Spec;
     E67 := True;
     Ada.Tags'Elab_Spec;
     Ada.Streams'Elab_Spec;
     E43 := True;
     Interfaces.C'Elab_Spec;
     E69 := True;
     System.Finalization_Root'Elab_Spec;
     E60 := True;
     System.Os_Lib'Elab_Body;
     E71 := True;
     System.Finalization_Implementation'Elab_Spec;
     System.Finalization_Implementation'Elab_Body;
     E62 := True;
     Ada.Finalization'Elab_Spec;
     E58 := True;
     Ada.Finalization.List_Controller'Elab_Spec;
     E76 := True;
     System.File_Control_Block'Elab_Spec;
     E74 := True;
     System.File_Io'Elab_Body;
     E56 := True;
     Ada.Tags'Elab_Body;
     E45 := True;
     Ada.Text_Io'Elab_Spec;
     Ada.Text_Io'Elab_Body;
     E07 := True;

Note also binder switch :switch:`-l`, which outputs the chosen elaboration
order and provides a more readable form of the above:

  ::

     ada (spec)
     interfaces (spec)
     system (spec)
     system.case_util (spec)
     system.case_util (body)
     system.concat_2 (spec)
     system.concat_2 (body)
     system.concat_3 (spec)
     system.concat_3 (body)
     system.htable (spec)
     system.parameters (spec)
     system.parameters (body)
     system.crtl (spec)
     interfaces.c_streams (spec)
     interfaces.c_streams (body)
     system.restrictions (spec)
     system.restrictions (body)
     system.standard_library (spec)
     system.exceptions (spec)
     system.exceptions (body)
     system.storage_elements (spec)
     system.storage_elements (body)
     system.secondary_stack (spec)
     system.stack_checking (spec)
     system.stack_checking (body)
     system.string_hash (spec)
     system.string_hash (body)
     system.htable (body)
     system.strings (spec)
     system.strings (body)
     system.traceback (spec)
     system.traceback (body)
     system.traceback_entries (spec)
     system.traceback_entries (body)
     ada.exceptions (spec)
     ada.exceptions.last_chance_handler (spec)
     system.soft_links (spec)
     system.soft_links (body)
     ada.exceptions.last_chance_handler (body)
     system.secondary_stack (body)
     system.exception_table (spec)
     system.exception_table (body)
     ada.io_exceptions (spec)
     ada.tags (spec)
     ada.streams (spec)
     interfaces.c (spec)
     interfaces.c (body)
     system.finalization_root (spec)
     system.finalization_root (body)
     system.memory (spec)
     system.memory (body)
     system.standard_library (body)
     system.os_lib (spec)
     system.os_lib (body)
     system.unsigned_types (spec)
     system.stream_attributes (spec)
     system.stream_attributes (body)
     system.finalization_implementation (spec)
     system.finalization_implementation (body)
     ada.finalization (spec)
     ada.finalization (body)
     ada.finalization.list_controller (spec)
     ada.finalization.list_controller (body)
     system.file_control_block (spec)
     system.file_io (spec)
     system.file_io (body)
     system.val_uns (spec)
     system.val_util (spec)
     system.val_util (body)
     system.val_uns (body)
     system.wch_con (spec)
     system.wch_con (body)
     system.wch_cnv (spec)
     system.wch_jis (spec)
     system.wch_jis (body)
     system.wch_cnv (body)
     system.wch_stw (spec)
     system.wch_stw (body)
     ada.tags (body)
     ada.exceptions (body)
     ada.text_io (spec)
     ada.text_io (body)
     text_io (spec)
     gdbstr (body)

---

### Gcc Ada Doc Gnat Ugn Example Of Binder Output (`gcc/ada/doc/gnat_ugn/example_of_binder_output.rst`)

.. _Example_of_Binder_Output_File:

*****************************
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.
Comments have been added for clarification purposes.


.. code-block:: ada

  --  The package is called Ada_Main unless this name is actually used
  --  as a unit name in the partition, in which case some other unique
  --  name is used.

  pragma Ada_95;
  with System;
  package ada_main is
     pragma Warnings (Off);

     --  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.

     gnat_argc : Integer;
     gnat_argv : System.Address;
     gnat_envp : System.Address;

     --  The actual variables are stored in a library routine. This
     --  is useful for some shared library situations, where there
     --  are problems if variables are not in the library.

     pragma Import (C, gnat_argc);
     pragma Import (C, gnat_argv);
     pragma Import (C, gnat_envp);

     --  The exit status is similarly an external location

     gnat_exit_status : Integer;
     pragma Import (C, gnat_exit_status);

     GNAT_Version : constant String :=
                      "GNAT Version: Pro 7.4.0w (20141119-49)" & ASCII.NUL;
     pragma Export (C, GNAT_Version, "__gnat_version");

     Ada_Main_Program_Name : constant String := "_ada_hello" & ASCII.NUL;
     pragma Export (C, Ada_Main_Program_Name, "__gnat_ada_main_program_name");

     --  This is the generated adainit routine that performs
     --  initialization at the start of execution. In the case
     --  where Ada is the main program, this main program makes
     --  a call to adainit at program startup.

     procedure adainit;
     pragma Export (C, adainit, "adainit");

     --  This is the generated adafinal routine that performs
     --  finalization at the end of execution. In the case where
     --  Ada is the main program, this main program makes a call
     --  to adafinal at program termination.

     procedure adafinal;
     pragma Export (C, adafinal, "adafinal");

     --  This routine is called at the start of execution. It is
     --  a dummy routine that is used by the debugger to breakpoint
     --  at the start of execution.

     --  This is the actual generated main program (it would be
     --  suppressed if the no main program switch were used). As
     --  required by standard system conventions, this program has
     --  the external name main.

     function main
       (argc : Integer;
        argv : System.Address;
        envp : System.Address)
        return Integer;
     pragma Export (C, main, "main");

     --  The following set of constants give the version
     --  identification values for every unit in the bound
     --  partition. This identification is computed from all
     --  dependent semantic units, and corresponds to the
     --  string that would be returned by use of the
     --  Body_Version or Version attributes.

     --  The following Export pragmas export the version numbers
     --  with symbolic names ending in B (for body) or S
     --  (for spec) so that they can be located in a link. The
     --  information provided here is sufficient to track down
     --  the exact versions of units used in a given build.

     type Version_32 is mod 2 ** 32;
     u00001 : constant Version_32 := 16#8ad6e54a#;
     pragma Export (C, u00001, "helloB");
     u00002 : constant Version_32 := 16#fbff4c67#;
     pragma Export (C, u00002, "system__standard_libraryB");
     u00003 : constant Version_32 := 16#1ec6fd90#;
     pragma Export (C, u00003, "system__standard_libraryS");
     u00004 : constant Version_32 := 16#3ffc8e18#;
     pragma Export (C, u00004, "adaS");
     u00005 : constant Version_32 := 16#28f088c2#;
     pragma Export (C, u00005, "ada__text_ioB");
     u00006 : constant Version_32 := 16#f372c8ac#;
     pragma Export (C, u00006, "ada__text_ioS");
     u00007 : constant Version_32 := 16#2c143749#;
     pragma Export (C, u00007, "ada__exceptionsB");
     u00008 : constant Version_32 := 16#f4f0cce8#;
     pragma Export (C, u00008, "ada__exceptionsS");
     u00009 : constant Version_32 := 16#a46739c0#;
     pragma Export (C, u00009, "ada__exceptions__last_chance_handlerB");
     u00010 : constant Version_32 := 16#3aac8c92#;
     pragma Export (C, u00010, "ada__exceptions__last_chance_handlerS");
     u00011 : constant Version_32 := 16#1d274481#;
     pragma Export (C, u00011, "systemS");
     u00012 : constant Version_32 := 16#a207fefe#;
     pragma Export (C, u00012, "system__soft_linksB");
     u00013 : constant Version_32 := 16#467d9556#;
     pragma Export (C, u00013, "system__soft_linksS");
     u00014 : constant Version_32 := 16#b01dad17#;
     pragma Export (C, u00014, "system__parametersB");
     u00015 : constant Version_32 := 16#630d49fe#;
     pragma Export (C, u00015, "system__parametersS");
     u00016 : constant Version_32 := 16#b19b6653#;
     pragma Export (C, u00016, "system__secondary_stackB");
     u00017 : constant Version_32 := 16#b6468be8#;
     pragma Export (C, u00017, "system__secondary_stackS");
     u00018 : constant Version_32 := 16#39a03df9#;
     pragma Export (C, u00018, "system__storage_elementsB");
     u00019 : constant Version_32 := 16#30e40e85#;
     pragma Export (C, u00019, "system__storage_elementsS");
     u00020 : constant Version_32 := 16#41837d1e#;
     pragma Export (C, u00020, "system__stack_checkingB");
     u00021 : constant Version_32 := 16#93982f69#;
     pragma Export (C, u00021, "system__stack_checkingS");
     u00022 : constant Version_32 := 16#393398c1#;
     pragma Export (C, u00022, "system__exception_tableB");
     u00023 : constant Version_32 := 16#b33e2294#;
     pragma Export (C, u00023, "system__exception_tableS");
     u00024 : constant Version_32 := 16#ce4af020#;
     pragma Export (C, u00024, "system__exceptionsB");
     u00025 : constant Version_32 := 16#75442977#;
     pragma Export (C, u00025, "system__exceptionsS");
     u00026 : constant Version_32 := 16#37d758f1#;
     pragma Export (C, u00026, "system__exceptions__machineS");
     u00027 : constant Version_32 := 16#b895431d#;
     pragma Export (C, u00027, "system__exceptions_debugB");
     u00028 : constant Version_32 := 16#aec55d3f#;
     pragma Export (C, u00028, "system__exceptions_debugS");
     u00029 : constant Version_32 := 16#570325c8#;
     pragma Export (C, u00029, "system__img_intB");
     u00030 : constant Version_32 := 16#1ffca443#;
     pragma Export (C, u00030, "system__img_intS");
     u00031 : constant Version_32 := 16#b98c3e16#;
     pragma Export (C, u00031, "system__tracebackB");
     u00032 : constant Version_32 := 16#831a9d5a#;
     pragma Export (C, u00032, "system__tracebackS");
     u00033 : constant Version_32 := 16#9ed49525#;
     pragma Export (C, u00033, "system__traceback_entriesB");
     u00034 : constant Version_32 := 16#1d7cb2f1#;
     pragma Export (C, u00034, "system__traceback_entriesS");
     u00035 : constant Version_32 := 16#8c33a517#;
     pragma Export (C, u00035, "system__wch_conB");
     u00036 : constant Version_32 := 16#065a6653#;
     pragma Export (C, u00036, "system__wch_conS");
     u00037 : constant Version_32 := 16#9721e840#;
     pragma Export (C, u00037, "system__wch_stwB");
     u00038 : constant Version_32 := 16#2b4b4a52#;
     pragma Export (C, u00038, "system__wch_stwS");
     u00039 : constant Version_32 := 16#92b797cb#;
     pragma Export (C, u00039, "system__wch_cnvB");
     u00040 : constant Version_32 := 16#09eddca0#;
     pragma Export (C, u00040, "system__wch_cnvS");
     u00041 : constant Version_32 := 16#6033a23f#;
     pragma Export (C, u00041, "interfacesS");
     u00042 : constant Version_32 := 16#ece6fdb6#;
     pragma Export (C, u00042, "system__wch_jisB");
     u00043 : constant Version_32 := 16#899dc581#;
     pragma Export (C, u00043, "system__wch_jisS");
     u00044 : constant Version_32 := 16#10558b11#;
     pragma Export (C, u00044, "ada__streamsB");
     u00045 : constant Version_32 := 16#2e6701ab#;
     pragma Export (C, u00045, "ada__streamsS");
     u00046 : constant Version_32 := 16#db5c917c#;
     pragma Export (C, u00046, "ada__io_exceptionsS");
     u00047 : constant Version_32 := 16#12c8cd7d#;
     pragma Export (C, u00047, "ada__tagsB");
     u00048 : constant Version_32 := 16#ce72c228#;
     pragma Export (C, u00048, "ada__tagsS");
     u00049 : constant Version_32 := 16#c3335bfd#;
     pragma Export (C, u00049, "system__htableB");
     u00050 : constant Version_32 := 16#99e5f76b#;
     pragma Export (C, u00050, "system__htableS");
     u00051 : constant Version_32 := 16#089f5cd0#;
     pragma Export (C, u00051, "system__string_hashB");
     u00052 : constant Version_32 := 16#3bbb9c15#;
     pragma Export (C, u00052, "system__string_hashS");
     u00053 : constant Version_32 := 16#807fe041#;
     pragma Export (C, u00053, "system__unsigned_typesS");
     u00054 : constant Version_32 := 16#d27be59e#;
     pragma Export (C, u00054, "system__val_lluB");
     u00055 : constant Version_32 := 16#fa8db733#;
     pragma Export (C, u00055, "system__val_lluS");
     u00056 : constant Version_32 := 16#27b600b2#;
     pragma Export (C, u00056, "system__val_utilB");
     u00057 : constant Version_32 := 16#b187f27f#;
     pragma Export (C, u00057, "system__val_utilS");
     u00058 : constant Version_32 := 16#d1060688#;
     pragma Export (C, u00058, "system__case_utilB");
     u00059 : constant Version_32 := 16#392e2d56#;
     pragma Export (C, u00059, "system__case_utilS");
     u00060 : constant Version_32 := 16#84a27f0d#;
     pragma Export (C, u00060, "interfaces__c_streamsB");
     u00061 : constant Version_32 := 16#8bb5f2c0#;
     pragma Export (C, u00061, "interfaces__c_streamsS");
     u00062 : constant Version_32 := 16#6db6928f#;
     pragma Export (C, u00062, "system__crtlS");
     u00063 : constant Version_32 := 16#4e6a342b#;
     pragma Export (C, u00063, "system__file_ioB");
     u00064 : constant Version_32 := 16#ba56a5e4#;
     pragma Export (C, u00064, "system__file_ioS");
     u00065 : constant Version_32 := 16#b7ab275c#;
     pragma Export (C, u00065, "ada__finalizationB");
     u00066 : constant Version_32 := 16#19f764ca#;
     pragma Export (C, u00066, "ada__finalizationS");
     u00067 : constant Version_32 := 16#95817ed8#;
     pragma Export (C, u00067, "system__finalization_rootB");
     u00068 : constant Version_32 := 16#52d53711#;
     pragma Export (C, u00068, "system__finalization_rootS");
     u00069 : constant Version_32 := 16#769e25e6#;
     pragma Export (C, u00069, "interfaces__cB");
     u00070 : constant Version_32 := 16#4a38bedb#;
     pragma Export (C, u00070, "interfaces__cS");
     u00071 : constant Version_32 := 16#07e6ee66#;
     pragma Export (C, u00071, "system__os_libB");
     u00072 : constant Version_32 := 16#d7b69782#;
     pragma Export (C, u00072, "system__os_libS");
     u00073 : constant Version_32 := 16#1a817b8e#;
     pragma Export (C, u00073, "system__stringsB");
     u00074 : constant Version_32 := 16#639855e7#;
     pragma Export (C, u00074, "system__stringsS");
     u00075 : constant Version_32 := 16#e0b8de29#;
     pragma Export (C, u00075, "system__file_control_blockS");
     u00076 : constant Version_32 := 16#b5b2aca1#;
     pragma Export (C, u00076, "system__finalization_mastersB");
     u00077 : constant Version_32 := 16#69316dc1#;
     pragma Export (C, u00077, "system__finalization_mastersS");
     u00078 : constant Version_32 := 16#57a37a42#;
     pragma Export (C, u00078, "system__address_imageB");
     u00079 : constant Version_32 := 16#bccbd9bb#;
     pragma Export (C, u00079, "system__address_imageS");
     u00080 : constant Version_32 := 16#7268f812#;
     pragma Export (C, u00080, "system__img_boolB");
     u00081 : constant Version_32 := 16#e8fe356a#;
     pragma Export (C, u00081, "system__img_boolS");
     u00082 : constant Version_32 := 16#d7aac20c#;
     pragma Export (C, u00082, "system__ioB");
     u00083 : constant Version_32 := 16#8365b3ce#;
     pragma Export (C, u00083, "system__ioS");
     u00084 : constant Version_32 := 16#6d4d969a#;
     pragma Export (C, u00084, "system__storage_poolsB");
     u00085 : constant Version_32 := 16#e87cc305#;
     pragma Export (C, u00085, "system__storage_poolsS");
     u00086 : constant Version_32 := 16#e34550ca#;
     pragma Export (C, u00086, "system__pool_globalB");
     u00087 : constant Version_32 := 16#c88d2d16#;
     pragma Export (C, u00087, "system__pool_globalS");
     u00088 : constant Version_32 := 16#9d39c675#;
     pragma Export (C, u00088, "system__memoryB");
     u00089 : constant Version_32 := 16#445a22b5#;
     pragma Export (C, u00089, "system__memoryS");
     u00090 : constant Version_32 := 16#6a859064#;
     pragma Export (C, u00090, "system__storage_pools__subpoolsB");
     u00091 : constant Version_32 := 16#e3b008dc#;
     pragma Export (C, u00091, "system__storage_pools__subpoolsS");
     u00092 : constant Version_32 := 16#63f11652#;
     pragma Export (C, u00092, "system__storage_pools__subpools__finalizationB");
     u00093 : constant Version_32 := 16#fe2f4b3a#;
     pragma Export (C, u00093, "system__storage_pools__subpools__finalizationS");

     --  BEGIN ELABORATION ORDER
     --  ada%s
     --  interfaces%s
     --  system%s
     --  system.case_util%s
     --  system.case_util%b
     --  system.htable%s
     --  system.img_bool%s
     --  system.img_bool%b
     --  system.img_int%s
     --  system.img_int%b
     --  system.io%s
     --  system.io%b
     --  system.parameters%s
     --  system.parameters%b
     --  system.crtl%s
     --  interfaces.c_streams%s
     --  interfaces.c_streams%b
     --  system.standard_library%s
     --  system.exceptions_debug%s
     --  system.exceptions_debug%b
     --  system.storage_elements%s
     --  system.storage_elements%b
     --  system.stack_checking%s
     --  system.stack_checking%b
     --  system.string_hash%s
     --  system.string_hash%b
     --  system.htable%b
     --  system.strings%s
     --  system.strings%b
     --  system.os_lib%s
     --  system.traceback_entries%s
     --  system.traceback_entries%b
     --  ada.exceptions%s
     --  system.soft_links%s
     --  system.unsigned_types%s
     --  system.val_llu%s
     --  system.val_util%s
     --  system.val_util%b
     --  system.val_llu%b
     --  system.wch_con%s
     --  system.wch_con%b
     --  system.wch_cnv%s
     --  system.wch_jis%s
     --  system.wch_jis%b
     --  system.wch_cnv%b
     --  system.wch_stw%s
     --  system.wch_stw%b
     --  ada.exceptions.last_chance_handler%s
     --  ada.exceptions.last_chance_handler%b
     --  system.address_image%s
     --  system.exception_table%s
     --  system.exception_table%b
     --  ada.io_exceptions%s
     --  ada.tags%s
     --  ada.streams%s
     --  ada.streams%b
     --  interfaces.c%s
     --  system.exceptions%s
     --  system.exceptions%b
     --  system.exceptions.machine%s
     --  system.finalization_root%s
     --  system.finalization_root%b
     --  ada.finalization%s
     --  ada.finalization%b
     --  system.storage_pools%s
     --  system.storage_pools%b
     --  system.finalization_masters%s
     --  system.storage_pools.subpools%s
     --  system.storage_pools.subpools.finalization%s
     --  system.storage_pools.subpools.finalization%b
     --  system.memory%s
     --  system.memory%b
     --  system.standard_library%b
     --  system.pool_global%s
     --  system.pool_global%b
     --  system.file_control_block%s
     --  system.file_io%s
     --  system.secondary_stack%s
     --  system.file_io%b
     --  system.storage_pools.subpools%b
     --  system.finalization_masters%b
     --  interfaces.c%b
     --  ada.tags%b
     --  system.soft_links%b
     --  system.os_lib%b
     --  system.secondary_stack%b
     --  system.address_image%b
     --  system.traceback%s
     --  ada.exceptions%b
     --  system.traceback%b
     --  ada.text_io%s
     --  ada.text_io%b
     --  hello%b
     --  END ELABORATION ORDER

  end ada_main;

.. code-block:: ada

  pragma Ada_95;
  --  The following source file name pragmas allow the generated file
  --  names to be unique for different main programs. They are needed
  --  since the package name will always be Ada_Main.

  pragma Source_File_Name (ada_main, Spec_File_Name => "b~hello.ads");
  pragma Source_File_Name (ada_main, Body_File_Name => "b~hello.adb");

  pragma Suppress (Overflow_Check);
  with Ada.Exceptions;

  --  Generated package body for Ada_Main starts here

  package body ada_main is
     pragma Warnings (Off);

     --  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");
     E13 : Short_Integer; pragma Import (Ada, E13, "system__soft_links_E");
     E23 : Short_Integer; pragma Import (Ada, E23, "system__exception_table_E");
     E46 : Short_Integer; pragma Import (Ada, E46, "ada__io_exceptions_E");
     E48 : Short_Integer; pragma Import (Ada, E48, "ada__tags_E");
     E45 : Short_Integer; pragma Import (Ada, E45, "ada__streams_E");
     E70 : Short_Integer; pragma Import (Ada, E70, "interfaces__c_E");
     E25 : Short_Integer; pragma Import (Ada, E25, "system__exceptions_E");
     E68 : Short_Integer; pragma Import (Ada, E68, "system__finalization_root_E");
     E66 : Short_Integer; pragma Import (Ada, E66, "ada__finalization_E");
     E85 : Short_Integer; pragma Import (Ada, E85, "system__storage_pools_E");
     E77 : Short_Integer; pragma Import (Ada, E77, "system__finalization_masters_E");
     E91 : Short_Integer; pragma Import (Ada, E91, "system__storage_pools__subpools_E");
     E87 : Short_Integer; pragma Import (Ada, E87, "system__pool_global_E");
     E75 : Short_Integer; pragma Import (Ada, E75, "system__file_control_block_E");
     E64 : Short_Integer; pragma Import (Ada, E64, "system__file_io_E");
     E17 : Short_Integer; pragma Import (Ada, E17, "system__secondary_stack_E");
     E06 : Short_Integer; pragma Import (Ada, E06, "ada__text_io_E");

     Local_Priority_Specific_Dispatching : constant String := "";
     Local_Interrupt_States : constant String := "";

     Is_Elaborated : Boolean := False;

     procedure finalize_library is
     begin
        E06 := E06 - 1;
        declare
           procedure F1;
           pragma Import (Ada, F1, "ada__text_io__finalize_spec");
        begin
           F1;
        end;
        E77 := E77 - 1;
        E91 := E91 - 1;
        declare
           procedure F2;
           pragma Import (Ada, F2, "system__file_io__finalize_body");
        begin
           E64 := E64 - 1;
           F2;
        end;
        declare
           procedure F3;
           pragma Import (Ada, F3, "system__file_control_block__finalize_spec");
        begin
           E75 := E75 - 1;
           F3;
        end;
        E87 := E87 - 1;
        declare
           procedure F4;
           pragma Import (Ada, F4, "system__pool_global__finalize_spec");
        begin
           F4;
        end;
        declare
           procedure F5;
           pragma Import (Ada, F5, "system__storage_pools__subpools__finalize_spec");
        begin
           F5;
        end;
        declare
           procedure F6;
           pragma Import (Ada, F6, "system__finalization_masters__finalize_spec");
        begin
           F6;
        end;
        declare
           procedure Reraise_Library_Exception_If_Any;
           pragma Import (Ada, Reraise_Library_Exception_If_Any, "__gnat_reraise_library_exception_if_any");
        begin
           Reraise_Library_Exception_If_Any;
        end;
     end finalize_library;

     -------------
     -- adainit --
     -------------

     procedure adainit is

        Main_Priority : Integer;
        pragma Import (C, Main_Priority, "__gl_main_priority");
        Time_Slice_Value : Integer;
        pragma Import (C, Time_Slice_Value, "__gl_time_slice_val");
        WC_Encoding : Character;
        pragma Import (C, WC_Encoding, "__gl_wc_encoding");
        Locking_Policy : Character;
        pragma Import (C, Locking_Policy, "__gl_locking_policy");
        Queuing_Policy : Character;
        pragma Import (C, Queuing_Policy, "__gl_queuing_policy");
        Task_Dispatching_Policy : Character;
        pragma Import (C, Task_Dispatching_Policy, "__gl_task_dispatching_policy");
        Priority_Specific_Dispatching : System.Address;
        pragma Import (C, Priority_Specific_Dispatching, "__gl_priority_specific_dispatching");
        Num_Specific_Dispatching : Integer;
        pragma Import (C, Num_Specific_Dispatching, "__gl_num_specific_dispatching");
        Main_CPU : Integer;
        pragma Import (C, Main_CPU, "__gl_main_cpu");
        Interrupt_States : System.Address;
        pragma Import (C, Interrupt_States, "__gl_interrupt_states");
        Num_Interrupt_States : Integer;
        pragma Import (C, Num_Interrupt_States, "__gl_num_interrupt_states");
        Unreserve_All_Interrupts : Integer;
        pragma Import (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
        Detect_Blocking : Integer;
        pragma Import (C, Detect_Blocking, "__gl_detect_blocking");
        Default_Stack_Size : Integer;
        pragma Import (C, Default_Stack_Size, "__gl_default_stack_size");
        Leap_Seconds_Support : Integer;
        pragma Import (C, Leap_Seconds_Support, "__gl_leap_seconds_support");

        procedure Runtime_Initialize;
        pragma Import (C, Runtime_Initialize, "__gnat_runtime_initialize");

        Finalize_Library_Objects : No_Param_Proc;
        pragma Import (C, Finalize_Library_Objects, "__gnat_finalize_library_objects");

     --  Start of processing for adainit

     begin

        --  Record various information for this partition.  The values
        --  are derived by the binder from information stored in the ali
        --  files by the compiler.

        if Is_Elaborated then
           return;
        end if;
        Is_Elaborated := True;
        Main_Priority := -1;
        Time_Slice_Value := -1;
        WC_Encoding := 'b';
        Locking_Policy := ' ';
        Queuing_Policy := ' ';
        Task_Dispatching_Policy := ' ';
        Priority_Specific_Dispatching :=
          Local_Priority_Specific_Dispatching'Address;
        Num_Specific_Dispatching := 0;
        Main_CPU := -1;
        Interrupt_States := Local_Interrupt_States'Address;
        Num_Interrupt_States := 0;
        Unreserve_All_Interrupts := 0;
        Detect_Blocking := 0;
        Default_Stack_Size := -1;
        Leap_Seconds_Support := 0;

        Runtime_Initialize;

        Finalize_Library_Objects := finalize_library'access;

        --  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. Also increment a reference
	--  counter for each unit.

        System.Soft_Links'Elab_Spec;
        System.Exception_Table'Elab_Body;
        E23 := E23 + 1;
        Ada.Io_Exceptions'Elab_Spec;
        E46 := E46 + 1;
        Ada.Tags'Elab_Spec;
        Ada.Streams'Elab_Spec;
        E45 := E45 + 1;
        Interfaces.C'Elab_Spec;
        System.Exceptions'Elab_Spec;
        E25 := E25 + 1;
        System.Finalization_Root'Elab_Spec;
        E68 := E68 + 1;
        Ada.Finalization'Elab_Spec;
        E66 := E66 + 1;
        System.Storage_Pools'Elab_Spec;
        E85 := E85 + 1;
        System.Finalization_Masters'Elab_Spec;
        System.Storage_Pools.Subpools'Elab_Spec;
        System.Pool_Global'Elab_Spec;
        E87 := E87 + 1;
        System.File_Control_Block'Elab_Spec;
        E75 := E75 + 1;
        System.File_Io'Elab_Body;
        E64 := E64 + 1;
        E91 := E91 + 1;
        System.Finalization_Masters'Elab_Body;
        E77 := E77 + 1;
        E70 := E70 + 1;
        Ada.Tags'Elab_Body;
        E48 := E48 + 1;
        System.Soft_Links'Elab_Body;
        E13 := E13 + 1;
        System.Os_Lib'Elab_Body;
        E72 := E72 + 1;
        System.Secondary_Stack'Elab_Body;
        E17 := E17 + 1;
        Ada.Text_Io'Elab_Spec;
        Ada.Text_Io'Elab_Body;
        E06 := E06 + 1;
     end adainit;

     --------------
     -- adafinal --
     --------------

     procedure adafinal is
        procedure s_stalib_adafinal;
        pragma Import (C, s_stalib_adafinal, "system__standard_library__adafinal");

        procedure Runtime_Finalize;
        pragma Import (C, Runtime_Finalize, "__gnat_runtime_finalize");

     begin
        if not Is_Elaborated then
           return;
        end if;
        Is_Elaborated := False;
        Runtime_Finalize;
        s_stalib_adafinal;
     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 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");

     ----------
     -- main --
     ----------

     --  main is actually a function, as in the ANSI C standard,
     --  defined to return the exit status. The three parameters
     --  are the argument count, argument values and environment
     --  pointer.

     function main
       (argc : Integer;
        argv : System.Address;
        envp : System.Address)
        return Integer
     is
        --  The initialize routine performs low level system
        --  initialization using a standard library routine which
        --  sets up signal handling and performs any other
        --  required setup. The routine can be found in file
        --  a-init.c.

        procedure initialize;
        pragma Import (C, initialize, "__gnat_initialize");

        --  The finalize routine performs low level system
        --  finalization using a standard library routine. The
        --  routine is found in file a-final.c and in the standard
        --  distribution is a dummy routine that does nothing, so
        --  really this is a hook for special user finalization.

        procedure finalize;
        pragma Import (C, finalize, "__gnat_finalize");

        --  The following is to initialize the SEH exceptions

        SEH : aliased array (1 .. 2) of Integer;

        Ensure_Reference : aliased System.Address := Ada_Main_Program_Name'Address;
        pragma Volatile (Ensure_Reference);

     --  Start of processing for main

     begin
        --  Save global variables

        gnat_argc := argc;
        gnat_argv := argv;
        gnat_envp := envp;

        --  Call low level system initialization

        Initialize (SEH'Address);

        --  Call our generated Ada initialization routine

        adainit;

        --  Now we call the main program of the partition

        Ada_Main_Program;

        --  Perform Ada finalization

        adafinal;

        --  Perform low level system finalization

        Finalize;

        --  Return the proper exit status
        return (gnat_exit_status);
     end;

  --  This section is entirely comments, so it has no effect on the
  --  compilation of the Ada_Main package. It provides the list of
  --  object files and linker options, as well as some standard
  --  libraries needed for the link. The gnatlink utility parses
  --  this b~hello.adb file to read these comment lines to generate
  --  the appropriate command line arguments for the call to the
  --  system linker. The BEGIN/END lines are used for sentinels for
  --  this parsing operation.

  --  The exact file names will of course depend on the environment,
  --  host/target and location of files on the host system.

  -- BEGIN Object file/option list
     --   ./hello.o
     --   -L./
     --   -L/usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/
     --   /usr/local/gnat/lib/gcc-lib/i686-pc-linux-gnu/2.8.1/adalib/libgnat.a
  -- END Object file/option list

  end ada_main;


The Ada code in the above example is exactly what is generated by the
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, you can use the debugger
in Ada mode to debug the generated ``Ada_Main`` package. For example,
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:

  .. code-block:: ada

     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
elaboration code in your own application).

---

### Gcc Ada Doc Gnat Ugn Getting Started With Gnat (`gcc/ada/doc/gnat_ugn/getting_started_with_gnat.rst`)

.. role:: switch(samp)

.. _Getting_Started_with_GNAT:

*************************
Getting Started with GNAT
*************************

This chapter describes how to use GNAT's command line interface to build
executable Ada programs.
On most platforms a visually oriented Integrated Development Environment
is also available: GNAT Studio.
GNAT Studio offers a graphical "look and feel", support for development in
other programming languages, comprehensive browsing features, and
many other capabilities.
For information on GNAT Studio please refer to the
:title:`GNAT Studio documentation`.


.. _System_Requirements:

System Requirements
===================

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, 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 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.

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
============

You need to take three steps to create an executable file from an Ada
source file:

*   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.

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
============================

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 named :file:`hello.adb`:


.. code-block:: ada

  with Ada.Text_IO; use Ada.Text_IO;
  procedure Hello is
  begin
     Put_Line ("Hello WORLD!");
  end Hello;

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
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`` (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 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
as the command prompt in the examples in this document):

.. code-block:: sh

  $ gcc -c hello.adb


``gcc`` is the command used to run the compiler. It is
capable of compiling programs in several languages, including Ada and
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 you must always
specify the :switch:`-c`.)

This compile command generates a file
:file:`hello.o`, which is the object
file corresponding to your Ada program. It also generates
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 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, as well as sources that depend
on such modified sources, so that 'version skew' is avoided.

.. index:: Version skew (avoided by ``gnatmake``)

.. code-block:: sh

  $ gnatmake hello.adb

The result is an executable program called :file:`hello`, which you can
run by entering:

.. code-block:: sh

  $ hello

assuming that the current directory is on the search path
for executable programs.

and, if all has gone well, you will see::

  Hello WORLD!

appear in response to this command.

.. _Running_a_Program_with_Multiple_Units:

Running a Program with Multiple Units
=====================================

Consider a slightly more complicated example with three files: a
main program and the spec and body of a package:


.. code-block:: ada

  package Greetings is
     procedure Hello;
     procedure Goodbye;
  end Greetings;

  with Ada.Text_IO; use Ada.Text_IO;
  package body Greetings is
     procedure Hello is
     begin
        Put_Line ("Hello WORLD!");
     end Hello;

     procedure Goodbye is
     begin
        Put_Line ("Goodbye WORLD!");
     end Goodbye;
  end Greetings;

  with Greetings;
  procedure Gmain is
  begin
     Greetings.Hello;
     Greetings.Goodbye;
  end Gmain;

Following the one-unit-per-file rule, place this program in the
following three separate files:



*greetings.ads*
  spec of package ``Greetings``


*greetings.adb*
  body of package ``Greetings``


*gmain.adb*
  body of main program

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 compile the body. If you want
to submit these files to the compiler for semantic checking and not code
generation, use the :switch:`-gnatc` switch:

.. code-block:: sh

  $ gcc -c greetings.ads -gnatc

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

  $ gnatmake gmain.adb

---

### Gcc Ada Doc Gnat Ugn Gnat And Program Execution (`gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst`)

.. role:: switch(samp)

.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing

.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit


.. _GNAT_and_Program_Execution:

**************************
GNAT and Program Execution
**************************

This chapter covers several topics:

* `Running and Debugging Ada Programs`_
* `Profiling`_
* `Improving Performance`_
* `Overflow Check Handling in GNAT`_
* `Performing Dimensionality Analysis in GNAT`_
* `Stack Related Facilities`_
* `Memory Management Issues`_
* `Sanitizers for Ada`_

.. _Running_and_Debugging_Ada_Programs:

Running and Debugging Ada Programs
==================================

.. index:: Debugging

This section discusses how to debug Ada programs.

The GNAT compiler handles an incorrect Ada program in three ways:

* The illegality may be a violation of the static semantics of Ada. In
  that case, GNAT diagnoses the constructs in the program that are illegal.
  It's then a straightforward matter for you to modify those parts of
  the program.

* The illegality may be a violation of the dynamic semantics of Ada. In
  that case the program compiles and executes, but may generate incorrect
  results or may terminate abnormally with some exception.

* When presented with a program that contains convoluted errors, GNAT
  itself may terminate abnormally without providing full diagnostics on
  the incorrect user program.

.. index:: Debugger

.. index:: !  gdb

.. _The_GNAT_Debugger_GDB:

The GNAT Debugger GDB
---------------------

``GDB`` is a general purpose, platform-independent debugger that
you can use to debug mixed-language programs, including compiled with ``gcc``,
and in particular is capable of debugging Ada programs compiled with
GNAT. The latest versions of ``GDB`` are Ada-aware and can handle
complex Ada data structures.

See :title:`Debugging with GDB`,
for full details on the usage of ``GDB``, including a section on
its usage on programs. That manual should be consulted for full
details. The section that follows is a brief introduction to the
philosophy and use of ``GDB``.

When programs are compiled, the compiler optionally writes debugging
information into the generated object file, including information on
line numbers and on declared types and variables. This information is
separate from the generated code. It makes the object files considerably
larger, but it does not add to the size of the actual executable that
is loaded into memory and has no impact on run-time performance. The
generation of debug information is triggered by the use of the
:switch:`-g` switch in the ``gcc`` or ``gnatmake`` command
you used to perform the compilations. It is important to emphasize that
it's a goal of GCC, and hence GNAT, that the use of this switch does
not change the generated code.

The compiler writes the debugging information in standard system formats that
are used by many tools, including debuggers and profilers. The format
of the information is typically designed to describe C types and
semantics, but GNAT implements a translation scheme which allows full
details about Ada types and variables to be encoded into these
standard C formats. Details of this encoding scheme may be found in
the file :file:`exp_dbug.ads` in the GNAT source distribution. However, the
details of this encoding are, in most cases, of no interest to a user,
since ``GDB`` automatically performs the necessary decoding.

When a program is bound and linked, the debugging information is
collected from the object files and stored in the executable image of
the program. Again, this process significantly increases the size of
the generated executable file, but does not increase the size of
the executable program in memory. Furthermore, if this program is run in
the normal manner, it runs exactly as if the debug information were
not present and takes no more actual memory.

However, if the program is run under control of ``GDB``, the
debugger is activated.  The image of the program is loaded, at which
point it is ready to run.  If you give a run command, the program
runs exactly as it would have if ``GDB`` were not present. This
is a crucial part of the ``GDB`` design philosophy: ``GDB`` is
entirely non-intrusive until a breakpoint is encountered.  If no
breakpoint is ever hit, the program runs exactly as it would if no
debugger were present. When a breakpoint is hit, ``GDB`` accesses
the debugging information and can respond to user commands to inspect
variables and more generally to report on the state of execution.

.. _Running_GDB:

Running GDB
-----------

This section describes how to initiate the debugger.

You can launch the debugger from a ``GNAT Studio`` menu or
directly from the command line. The description below covers the latter use.
You can use all the commands shown in the ``GNAT Studio`` debug console window,
but there are usually more GUI-based ways to achieve the same effect.

The command to run ``GDB`` is

  ::

     $ gdb program

where ``program`` is the name of the executable file. This
activates the debugger and results in a prompt for debugger commands.
The simplest command is simply ``run``, which causes the program to run
exactly as if the debugger were not present. The following section
describes some of the additional commands that you can give to ``GDB``.


.. _Introduction_to_GDB_Commands:

Introduction to GDB Commands
----------------------------

``GDB`` contains a large repertoire of commands.
See :title:`Debugging with GDB` for extensive documentation on the use
of these commands, together with examples of their use. Furthermore,
the command *help* invoked from within GDB activates a simple help
facility which summarizes the available commands and their options.
In this section, we summarize a few of the most commonly
used commands to give an idea of what ``GDB`` is about. You should create
a simple program with debugging information and experiment with the use of
these ``GDB`` commands on that program as you read through the
following section.

* :samp:`set args {arguments}`
    *arguments* is a list of arguments to be passed to the program on
    a subsequent run command, just as though the arguments had been
    entered on a normal invocation of the program. You do not need the
    ``set args`` command if the program does not require arguments.


* :samp:`run`
    The ``run`` command causes execution of the program to start from
    the beginning. If the program is already running, that is to say if
    you are currently positioned at a breakpoint, then a prompt will ask
    for confirmation that you want to abandon the current execution and
    restart. You can also specify program arguments on this command and
    if you specify ``run`` with no arguments, the arguments used on
    the previous command will be used again.


* :samp:`breakpoint {location}`
    This command sets a breakpoint, that is to say a point at which
    execution will halt and ``GDB`` will await further
    commands. *location* is either a line number within a file, which
    you specify in the format ``file:linenumber``, or the name of a
    subprogram. If you request a breakpoint be set on a subprogram
    that is overloaded, either a prompt will ask you to specify on
    which of those subprograms you want to breakpoint or a breakpoint
    will be set on all of them. If the program is run and execution
    encounters the breakpoint, the program stops and ``GDB``
    signals that the breakpoint was encountered by printing the line
    of code before which the program is halted.


* :samp:`catch exception {name}`
    This command causes the program execution to stop whenever exception
    ``name`` is raised.  If you omit ``name``, execution is
    suspended when any exception is raised.


* :samp:`print {expression}`
    This prints the value of the given expression. Most
    Ada expression formats are properly handled by ``GDB``, so the expression
    can contain function calls, variables, operators, and attribute references.


* :samp:`continue`
    Continues execution following a breakpoint until the next breakpoint or the
    termination of the program.


* :samp:`step`
    Executes a single line after a breakpoint. If the next statement
    is a subprogram call, execution continues into (the first statement of)
    the called subprogram.


* :samp:`next`
    Executes a single line. If this line is a subprogram call, the
    program executes that call and returns.


* :samp:`list`

    Lists a few lines around the current source location. In practice,
    it is usually more convenient to have a separate edit window open
    with the relevant source file displayed. ``emacs`` has debugging
    modes that display both the relevant source and ``GDB`` commands
    and output.  Successive applications of this command print
    subsequent lines. You can give this command an argument which is a
    line number, in which case it displays a few lines around the
    specified line.


* :samp:`backtrace`
    Displays a backtrace of the call chain. This command is typically
    used after a breakpoint has occurred to examine the sequence of calls that
    leads to the current breakpoint. The display includes one line for each
    activation record (frame) corresponding to an active subprogram.


* :samp:`up`
    At a breakpoint, ``GDB`` can display the values of variables local
    to the current frame. You can use the command ``up`` to
    examine the contents of other active frames by moving the focus up
    the stack, that is to say from callee to caller, one frame at a time.


* :samp:`down`
    Moves the focus of ``GDB`` down from the frame currently being
    examined to the frame of its callee (the reverse of the previous command),


* :samp:`frame {n}`
    Inspect the frame with the given number. The value 0 denotes the frame
    of the current breakpoint, that is to say the top of the call stack.


* :samp:`kill`
    Kills the child process in which the program is running under GDB.
    You may find this useful for several purposes:

    * It allows you to recompile and relink your program, since on many systems
      you cannot regenerate an executable file while it is running in a process.

    * You can run your program outside the debugger on systems that do not
      permit executing a program outside GDB while breakpoints are set
      within GDB.

    * It allows you to debug a core dump rather than a running process.

The above is a very short introduction to the commands that
``GDB`` provides. Important additional capabilities, including conditional
breakpoints, the ability to execute command sequences on a breakpoint,
the ability to debug at the machine instruction level and many other
features are described in detail in :title:`Debugging with GDB`.
Note that most commands can be abbreviated
(for example, "c" for ``continue`` and "bt" for ``backtrace``) and only enough
characters need be typed to disambiguate the command (e.g., "br" for
``breakpoint``).


.. _Using_Ada_Expressions:

Using Ada Expressions
---------------------

.. index:: Ada expressions (in gdb)

``GDB`` supports a very large subset of Ada expression syntax, with some
extensions. The philosophy behind the design of this subset is

  * ``GDB`` should provide basic literals and access to operations for
    arithmetic, dereferencing, field selection, indexing, and subprogram calls,
    leaving more sophisticated computations to subprograms written into the
    program (which therefore may be called from ``GDB``).

  * Type safety and strict adherence to Ada language restrictions
    are not particularly relevant in a debugging context.

  * Brevity is important to the ``GDB`` user.

Thus, for brevity, the debugger acts as if there were
implicit ``with`` and ``use`` clauses in effect for all user-written
packages, thus making it unnecessary to fully qualify most names with
their packages, regardless of context. Where this causes ambiguity,
``GDB`` asks the user's intent.

For details on the supported Ada syntax, see :title:`Debugging with GDB`.


.. _Calling_User-Defined_Subprograms:

Calling User-Defined Subprograms
--------------------------------

An important capability of ``GDB`` is the ability to call user-defined
subprograms while debugging. You do this by simply entering
a subprogram call statement in the form:

  ::

     call subprogram-name (parameters)

You can omit the keyword ``call`` in the normal case where the
``subprogram-name`` does not coincide with any of the predefined
``GDB`` commands.

The effect is to invoke the given subprogram, passing it the
list of parameters that is supplied. The parameters you specify can be expressions and
can include variables from the program being debugged. The
subprogram must be defined
at the library level within your program and ``GDB`` will call the
subprogram within the environment of your program execution (which
means that the subprogram is free to access or even modify variables
within your program).

The most important use of this facility that you can include
debugging routines that are tailored to particular data structures
in your program. You can write such debugging routines to provide a suitably
high-level description of an abstract type, rather than a low-level dump
of its physical layout. After all, the standard
``GDB print`` command only knows the physical layout of your
types, not their abstract meaning. Debugging routines can provide information
at the desired semantic level and are thus enormously useful.

For example, when debugging GNAT itself, it is crucial to have access to
the contents of the tree nodes used to represent the program internally.
But tree nodes are represented simply by an integer value (which in turn
is an index into a table of nodes).
Using the ``print`` command on a tree node would simply print this integer
value, which is not very useful. But the ``PN`` routine (defined in file
:file:`treepr.adb` in the GNAT sources) takes a tree node as input and displays
a useful high level representation of the tree node, which includes the
syntactic category of the node, its position in the source,
the descendant nodes and parent node, as well as lots of
semantic information. To study this example in more detail, you might want to
look at the body of the ``PN`` procedure in the above file.

Another useful application of this capability is to deal with situations where
complex data which are not handled suitably by GDB. For example, if you specify
Convention Fortran for a multi-dimensional array, GDB does not know that
the ordering of array elements has been switched and will not properly
address the array elements. In such a case, instead of trying to print the
elements directly from GDB, you can write a callable procedure that prints
the elements in the format you desire.


.. _Using_the_Next_Command_in_a_Function:

Using the *next* Command in a Function
--------------------------------------

When you use the ``next`` command in a function, the current source
location will advance to the next statement as usual. A special case
arises in the case of a ``return`` statement.

Part of the code for a return statement is the 'epilogue' of the function.
This is the code that returns to the caller. There is only one copy of
this epilogue code and it is typically associated with the last return
statement in the function if there is more than one return. In some
implementations, this epilogue is associated with the first statement
of the function.

The result is that if you use the ``next`` command from a return
statement that is not the last return statement of the function you
may see a strange apparent jump to the last return statement or to
the start of the function. You should simply ignore this odd jump.
The value returned is always that from the first return statement
that was stepped through.


.. _Stopping_When_Ada_Exceptions_Are_Raised:

Stopping When Ada Exceptions Are Raised
---------------------------------------

.. index:: Exceptions (in gdb)

You can set catchpoints that stop the program execution when your program
raises selected exceptions.


* :samp:`catch exception`
    Set a catchpoint that stops execution whenever (any task in the) program
    raises any exception.


* :samp:`catch exception {name}`
    Set a catchpoint that stops execution whenever (any task in the) program
    raises the exception *name*.


* :samp:`catch exception unhandled`
    Set a catchpoint that stops executing whenever (any task in the) program
    raises an exception for which there is no handler.


* :samp:`info exceptions`, :samp:`info exceptions {regexp}`
    The ``info exceptions`` command permits the user to examine all defined
    exceptions within Ada programs. With a regular expression, *regexp*, as
    argument, prints out only those exceptions whose name matches *regexp*.


.. index:: Tasks (in gdb)

.. _Ada_Tasks:

Ada Tasks
---------

``GDB`` allows the following task-related commands:


* :samp:`info tasks`
    This command shows a list of current Ada tasks, as in the following example:

    ::

       (gdb) info tasks
         ID       TID P-ID   Thread Pri State                 Name
          1   8088000   0   807e000  15 Child Activation Wait main_task
          2   80a4000   1   80ae000  15 Accept/Select Wait    b
          3   809a800   1   80a4800  15 Child Activation Wait a
       *  4   80ae800   3   80b8000  15 Running               c


    In this listing, the asterisk before the first task indicates it's
    currently running task. The first column lists the task ID used
    to refer to tasks in the following commands.


.. index:: Breakpoints and tasks

* ``break`` *linespec* ``task`` *taskid*, ``break`` *linespec* ``task`` *taskid* ``if`` ...

    These commands are like the ``break ... thread ...``.
    *linespec* specifies source lines.

    Use the qualifier :samp:`task {taskid}` with a breakpoint command
    to specify that you only want ``GDB`` to stop the program when that
    particular Ada task reaches this breakpoint. *taskid* is one of the
    numeric task identifiers assigned by ``GDB``, shown in the first
    column of the ``info tasks`` display.

    If you don't specify :samp:`task {taskid}` when you set a
    breakpoint, the breakpoint applies to *all* tasks of your
    program.

    You can use the ``task`` qualifier on conditional breakpoints as
    well; in this case, place :samp:`task {taskid}` before the
    breakpoint condition (before the ``if``).

.. index:: Task switching (in gdb)

* :samp:`task {taskno}`

    This command allows switching to the task referred by *taskno*. In
    particular, it allows browsing the backtrace of the specified
    task. You should switch back to the original task before
    continuing execution; otherwise the scheduling of the program may be
    disturbed.

For more detailed information on tasking support,
see :title:`Debugging with GDB`.


.. index:: Debugging Generic Units
.. index:: Generics

.. _Debugging_Generic_Units:

Debugging Generic Units
-----------------------

GNAT always uses the code expansion mechanism for generic
instantiation. This means that each time an instantiation occurs, the
compiler makes a complete copy of the original code, with
appropriate substitutions of formals by actuals.

You can't refer to the original generic entities in ``GDB``, but you
can debug a particular instance of a generic by using the appropriate
expanded names. For example, if we have

  .. code-block:: ada

     procedure g is

        generic package k is
           procedure kp (v1 : in out integer);
        end k;

        package body k is
           procedure kp (v1 : in out integer) is
           begin
              v1 := v1 + 1;
           end kp;
        end k;

        package k1 is new k;
        package k2 is new k;

        var : integer := 1;

     begin
        k1.kp (var);
        k2.kp (var);
        k1.kp (var);
        k2.kp (var);
     end;

Then to break on a call to procedure kp in the k2 instance, simply
use the command:

  ::

     (gdb) break g.k2.kp

When the breakpoint occurs, you can step through the code of the
instance in the normal manner and examine the values of local
variables, as you do for other units.


.. index:: Remote Debugging with gdbserver

.. _Remote_Debugging_with_gdbserver:

Remote Debugging with gdbserver
-------------------------------

On platforms that support ``gdbserver``, you can use this tool
to debug your application remotely.  This can be useful in situations
where the program needs to be run on a target host that is different
from the host used for development, particularly when the target has
a limited amount of resources (either CPU and/or memory).

To do so, start your program using ``gdbserver`` on the target machine.
``gdbserver`` automatically suspends the execution of your program
at its entry point, waiting for a debugger to connect to it.  You use the
following commands to start an application and tell ``gdbserver`` to
wait for a connection with the debugger on ``localhost`` port 4444.


  ::

     $ gdbserver localhost:4444 program
     Process program created; pid = 5685
     Listening on port 4444

Once ``gdbserver`` has started listening, you can tell the debugger to
establish a connection with this ``gdbserver``, and then start a
debugging session as if the program was being debugged on the
same host, directly under the control of ``GDB``.

  ::

     $ gdb program
     (gdb) target remote targethost:4444
     Remote debugging using targethost:4444
     0x00007f29936d0af0 in ?? () from /lib64/ld-linux-x86-64.so.
     (gdb) b foo.adb:3
     Breakpoint 1 at 0x401f0c: file foo.adb, line 3.
     (gdb) continue
     Continuing.

     Breakpoint 1, foo () at foo.adb:4
     4       end foo;

You can also use ``gdbserver`` to attach to an already running
program, in which case the execution of that program is suspended
until you have established the connection between the debugger and ``gdbserver``.

For more information on how to use ``gdbserver``, see the *Using the
gdbserver Program* section in :title:`Debugging with GDB`.  GNAT
provides support for ``gdbserver`` on x86-linux, x86-windows and
x86_64-linux.


.. index:: Abnormal Termination or Failure to Terminate

.. _GNAT_Abnormal_Termination_or_Failure_to_Terminate:

GNAT Abnormal Termination or Failure to Terminate
-------------------------------------------------

When presented with programs that contain serious errors in syntax
or semantics,
GNAT may, on rare occasions, experience problems such
as aborting with a
segmentation fault or illegal memory access, raising an internal
exception, terminating abnormally, or failing to terminate at all.
In such cases, you can activate
various features of GNAT that can help you pinpoint the construct in your
program that is the likely source of the problem.

The following strategies for you to use in such cases are presented in
increasing order of difficulty, corresponding to your experience in
using GNAT and your familiarity with compiler internals.

* Run ``gcc`` with the :switch:`-gnatf`. This switch causes all errors
  on a given line to be reported. In its absence, GNAT only displays
  the first error on a line.

  The :switch:`-gnatdO` switch causes errors to be displayed as soon as they
  are encountered, rather than after compilation is terminated. If GNAT
  terminates prematurely or goes into an infinite loop, the last error
  message displayed may help to pinpoint the culprit.

* Run ``gcc`` with the :switch:`-v` (verbose) switch. In this
  mode, ``gcc`` produces ongoing information about the progress of the
  compilation and provides the name of each procedure as code is
  generated. This switch allows you to find which Ada procedure was being
  compiled when it encountered a problem.

.. index:: -gnatdc switch

* Run ``gcc`` with the :switch:`-gnatdc` switch. This is a GNAT specific
  switch that does for the front-end what :switch:`-v` does
  for the back end. The system prints the name of each unit,
  either a compilation unit or nested unit, as it is being analyzed.

* Finally, you can start
  ``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 :ref:`The_GNAT_Debugger_GDB` 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_file name`` indicates the name of
  the source file.


.. _Naming_Conventions_for_GNAT_Source_Files:

Naming Conventions for GNAT Source Files
----------------------------------------

In order to better understand the workings of the GNAT system, the following
brief description of its organization may be helpful:

* Files with prefix :file:`sc` contain the lexical scanner.

* All files prefixed with :file:`par` are components of the parser. The
  numbers correspond to chapters of the Ada Reference Manual. For example,
  parsing of select statements can be found in :file:`par-ch9.adb`.

* All files prefixed with :file:`sem` perform semantic analysis. The
  numbers correspond to chapters of the Ada standard. For example, all
  issues involving context clauses can be found in
  :file:`sem_ch10.adb`. In addition, some features of the language
  require sufficient special processing to justify their own semantic
  files, such as :file:`sem_aggr.adb` for aggregates and
  :file:`sem_disp.adb` for dynamic dispatching.

* All files prefixed with :file:`exp` perform normalization and
  expansion of the intermediate representation (abstract syntax tree, or AST).
  The expansion has the effect of lowering the semantic level of the AST to
  a level closer to what the back end can handle. For example, it converts
  tasking operations into calls to the appropriate runtime routines.
  These files use the same numbering scheme as the parser and semantics files.
  For example, the construction of record initialization procedures is done in
  :file:`exp_ch3.adb`.

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

* The files :file:`atree.ads` and :file:`atree.adb` detail the low-level
  data structures used by the front-end.

* The files :file:`sinfo.ads` and :file:`sinfo.adb` detail the structure of
  the abstract syntax tree as produced by the parser.

* The files :file:`einfo.ads` and :file:`einfo.adb` detail the attributes of
  all entities, computed during semantic analysis.

* The files prefixed with :file:`gen_il` generate most of the functions
  defined in :file:`sinfo.ads` and :file:`einfo.ads`, which set and get
  various fields and flags of the AST.

* Library management issues are dealt with in files with prefix
  :file:`lib`.

  .. index:: Annex A (in Ada Reference Manual)

* Ada files with the prefix :file:`a-` are children of ``Ada``, as
  defined in Annex A.

  .. index:: Annex B (in Ada reference Manual)

* Files with prefix :file:`i-` are children of ``Interfaces``, as
  defined in Annex B.

  .. index::  System (package in Ada Reference Manual)

* Files with prefix :file:`s-` are children of ``System``. This includes
  both language-defined children and GNAT run-time routines.

  .. index:: GNAT (package)

* Files with prefix :file:`g-` are children of ``GNAT``. These are useful
  general-purpose packages, fully documented in their specs. All
  the other :file:`.c` files are modifications of common ``gcc`` files.


.. _Getting_Internal_Debugging_Information:

Getting Internal Debugging Information
--------------------------------------

Most compilers have internal debugging switches and modes. GNAT
does too, except GNAT internal debugging switches and modes are not
secret. A summary and full description of all the compiler and binder
debug flags are in the file :file:`debug.adb`. You must obtain the
sources of the compiler to see the full detailed effects of these flags.

The switches that print the source of the program (reconstructed from
the internal tree) are of general interest for user programs, as are the
options to print
the full internal tree and the entity table (the symbol table
information). The reconstructed source provides a readable version of the
program after the front-end has completed analysis and  expansion
and is useful when studying the performance of specific constructs.
For example, constraint checks are shown explicitly, complex aggregates
are replaced with loops and assignments, and tasking primitives
are replaced with run-time calls.


.. index:: traceback
.. index:: stack traceback
.. index:: stack unwinding

.. _Stack_Traceback:

Stack Traceback
---------------

Traceback is a mechanism to display the sequence of subprogram calls that
leads to a specified execution point in a program. Often (but not always)
the execution point is an instruction at which an exception has been raised.
This mechanism is also known as *stack unwinding* because it obtains
its information by scanning the run-time stack and recovering the activation
records of all active subprograms. Stack unwinding is one of the most
important tools for program debugging.

The first entry stored in traceback corresponds to the deepest calling level,
that is to say the subprogram currently executing the instruction
from which we want to obtain the traceback.

Note that there is no runtime performance penalty when stack traceback
is enabled and no exception is raised during program execution.

.. index:: traceback, non-symbolic

.. _Non-Symbolic_Traceback:

Non-Symbolic Traceback
^^^^^^^^^^^^^^^^^^^^^^

Note: this feature is not supported on all platforms. See
:samp:`GNAT.Traceback` spec in :file:`g-traceb.ads`
for a complete list of supported platforms.

.. rubric:: Tracebacks From an Unhandled Exception

A runtime non-symbolic traceback is a list of addresses of call
instructions.  To enable this feature you must use the :switch:`-E`
``gnatbind`` switch. With this switch, a stack traceback is stored at
runtime as part of exception information.

You can translate this information using the ``addr2line`` tool, provided that
the program is compiled with debugging options (see :ref:`Switches_for_gcc`)
and linked at a fixed position with :switch:`-no-pie`.

Here's a simple example with ``gnatmake``:

  .. code-block:: ada

     procedure STB is

        procedure P1 is
        begin
           raise Constraint_Error;
        end P1;

        procedure P2 is
        begin
           P1;
        end P2;

     begin
        P2;
     end STB;

  ::

     $ gnatmake stb -g -bargs -E -largs -no-pie
     $ stb

     Execution of stb terminated by unhandled exception
     raised CONSTRAINT_ERROR : stb.adb:5 explicit raise
     Load address: 0x400000
     Call stack traceback locations:
     0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4

As we can see, the traceback lists a sequence of addresses for the unhandled
exception ``CONSTRAINT_ERROR`` raised in procedure P1. It's easy to
see that this exception come from procedure P1. To translate these
addresses into the source lines where the calls appear, you need to
invoke the ``addr2line`` tool like this:

  ::

     $ addr2line -e stb 0x401373 0x40138b 0x40139c 0x401335 0x4011c4
        0x4011f1 0x77e892a4

     d:/stb/stb.adb:5
     d:/stb/stb.adb:10
     d:/stb/stb.adb:14
     d:/stb/b~stb.adb:197
     crtexe.c:?
     crtexe.c:?
     ??:0

The ``addr2line`` tool has several other useful options:

  =========================  ====================================================
  :samp:`-a --addresses`     to show the addresses alongside the line numbers
  :samp:`-f --functions`     to get the function name corresponding to a location
  :samp:`-p --pretty-print`  to print all the information on a single line
  :samp:`--demangle=gnat`    to use the GNAT decoding mode for the function names
  =========================  ====================================================

  ::

     $ addr2line -e stb -a -f -p --demangle=gnat 0x401373 0x40138b
        0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4

     0x00401373: stb.p1 at d:/stb/stb.adb:5
     0x0040138B: stb.p2 at d:/stb/stb.adb:10
     0x0040139C: stb at d:/stb/stb.adb:14
     0x00401335: main at d:/stb/b~stb.adb:197
     0x004011c4: ?? at crtexe.c:?
     0x004011f1: ?? at crtexe.c:?
     0x77e892a4: ?? ??:0


From this traceback, we can see that the exception was raised in :file:`stb.adb`
at line 5, which was reached from a procedure call in :file:`stb.adb` at line
10, and so on. :file:`b~std.adb` is the binder file, which contains the
call to the main program; :ref:`Running_gnatbind`. The remaining entries are
assorted runtime routines. The output will vary from platform to platform.

You can also use ``GDB`` with these traceback addresses to debug
the program. For example, we can break at a given code location, as reported
in the stack traceback::

     $ gdb -nw stb

     (gdb) break *0x401373
     Breakpoint 1 at 0x401373: file stb.adb, line 5.

It is important to note that the stack traceback addresses do not change when
debug information is included. This is particularly useful because it makes it
possible to release software without debug information (to minimize object
size), get a field report that includes a stack traceback whenever an internal
bug occurs, and then be able to retrieve the sequence of calls with the same
program compiled with debug information.

However the ``addr2line`` tool does not work with Position-Independent Code
(PIC), the historical example being Linux dynamic libraries and Windows DLLs,
which nowadays encompasse Position-Independent Executables (PIE) on recent
Linux and Windows versions.

In order to translate addresses the source lines with Position-Independent
Executables on recent Linux and Windows versions, in other words without
using the switch :switch:`-no-pie` during linking, you need to use the
``gnatsymbolize`` tool with :switch:`--load` instead of the ``addr2line``
tool. The main difference is that you need to copy the Load Address output
in the traceback ahead of the sequence of addresses. The default mode
of ``gnatsymbolize`` is equivalent to that of ``addr2line`` with the above
switches, so none of them are needed::

     $ gnatmake stb -g -bargs -E
     $ stb

     Execution of stb terminated by unhandled exception
     raised CONSTRAINT_ERROR : stb.adb:5 explicit raise
     Load address: 0x400000
     Call stack traceback locations:
     0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4

     $ gnatsymbolize --load stb 0x400000 0x401373 0x40138b 0x40139c 0x401335 \
        0x4011c4 0x4011f1 0x77e892a4

     0x00401373 Stb.P1 at stb.adb:5
     0x0040138B Stb.P2 at stb.adb:10
     0x0040139C Stb at stb.adb:14
     0x00401335 Main at b~stb.adb:197
     0x004011c4 __tmainCRTStartup at ???
     0x004011f1 mainCRTStartup at ???
     0x77e892a4 ??? at ???


.. rubric:: Tracebacks From Exception Occurrences

Non-symbolic tracebacks are obtained by using the :switch:`-E` binder switch.
The stack traceback is attached to the exception information string and you can
retrieve it in an exception handler within the Ada program by means of the
Ada facilities defined in ``Ada.Exceptions``. Here's a simple example:

  .. code-block:: ada

      with Ada.Text_IO;
      with Ada.Exceptions;

      procedure STB is

         use Ada;
         use Ada.Exceptions;

         procedure P1 is
            K : Positive := 1;
         begin
            K := K - 1;
         exception
            when E : others =>
               Text_IO.Put_Line (Exception_Information (E));
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         P2;
      end STB;

  ::

     $ gnatmake stb -g -bargs -E -largs -no-pie
     $ stb

     raised CONSTRAINT_ERROR : stb.adb:12 range check failed
     Load address: 0x400000
     Call stack traceback locations:
     0x4015e4 0x401633 0x401644 0x401461 0x4011c4 0x4011f1 0x77e892a4


.. rubric:: Tracebacks From Anywhere in a Program

You can also retrieve a stack traceback from anywhere in a program.
For this, you need to use the ``GNAT.Traceback`` API. This package includes a
procedure called ``Call_Chain`` that computes a complete stack traceback as
well as useful display procedures described below. You don't have to use
the :switch:`-E` ``gnatbind`` switch in this case because the stack traceback
mechanism is invoked explicitly.

In the following example, we compute a traceback at a specific location in the
program and display it using ``GNAT.Debug_Utilities.Image`` to convert
addresses to strings:


  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback;
      with GNAT.Debug_Utilities;
      with System;

      procedure STB is

         use Ada;
         use Ada.Text_IO;
         use GNAT;
         use GNAT.Traceback;
         use System;

         LA : constant Address := Executable_Load_Address;

         procedure P1 is
            TB  : Tracebacks_Array (1 .. 10);
            --  We are asking for a maximum of 10 stack frames.
            Len : Natural;
            --  Len will receive the actual number of stack frames returned.
         begin
            Call_Chain (TB, Len);

            Put ("In STB.P1 : ");

            for K in 1 .. Len loop
               Put (Debug_Utilities.Image_C (TB (K)));
               Put (' ');
            end loop;

            New_Line;
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         if LA /= Null_Address then
            Put_Line ("Load address: " & Debug_Utilities.Image_C (LA));
         end if;

         P2;
      end STB;

  ::

     $ gnatmake stb -g
     $ stb

     Load address: 0x400000
     In STB.P1 : 0x40F1E4 0x4014F2 0x40170B 0x40171C 0x401461 0x4011C4 \
       0x4011F1 0x77E892A4


You can get even more information by invoking the ``addr2line`` tool or
the ``gnatsymbolize`` tool as described earlier (note that the hexadecimal
addresses need to be specified in C format, with a leading '0x').

.. index:: traceback, symbolic

.. _Symbolic_Traceback:

Symbolic Traceback
^^^^^^^^^^^^^^^^^^

A symbolic traceback is a stack traceback in which procedure names are
associated with each code location.

Note that this feature is not supported on all platforms. See
:samp:`GNAT.Traceback.Symbolic` spec in :file:`g-trasym.ads` for a complete
list of currently supported platforms.

Note that the symbolic traceback requires that the program be compiled
with debug information. If you do not compile it with debug information,
only the non-symbolic information will be valid.


.. rubric:: Tracebacks From Exception Occurrences

Here is an example:

  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback.Symbolic;

      procedure STB is

         procedure P1 is
         begin
            raise Constraint_Error;
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

         procedure P3 is
         begin
            P2;
         end P3;

      begin
         P3;
      exception
         when E : others =>
            Ada.Text_IO.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
      end STB;

  ::

      $ gnatmake -g stb -bargs -E
      $ stb

      0040149F in stb.p1 at stb.adb:8
      004014B7 in stb.p2 at stb.adb:13
      004014CF in stb.p3 at stb.adb:18
      004015DD in ada.stb at stb.adb:22
      00401461 in main at b~stb.adb:168
      004011C4 in __mingw_CRTStartup at crt1.c:200
      004011F1 in mainCRTStartup at crt1.c:222
      77E892A4 in ?? at ??:0

.. rubric:: Tracebacks From Anywhere in a Program

You can get a symbolic stack traceback
from anywhere in a program, just as you can for non-symbolic tracebacks.
The first step is to obtain a non-symbolic
traceback. Then call ``Symbolic_Traceback`` to compute the symbolic
information. Here is an example:

  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback;
      with GNAT.Traceback.Symbolic;

      procedure STB is

         use Ada;
         use GNAT.Traceback;
         use GNAT.Traceback.Symbolic;

         procedure P1 is
            TB  : Tracebacks_Array (1 .. 10);
            --  We are asking for a maximum of 10 stack frames.
            Len : Natural;
            --  Len will receive the actual number of stack frames returned.
         begin
            Call_Chain (TB, Len);
            Text_IO.Put_Line (Symbolic_Traceback (TB (1 .. Len)));
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         P2;
      end STB;


.. rubric:: Automatic Symbolic Tracebacks

You may also enable symbolic tracebacks by using
the :switch:`-Es` switch to gnatbind (as in ``gprbuild -g ... -bargs -Es``).
This causes the Exception_Information to contain a symbolic
traceback, which will also be printed if an unhandled exception
terminates the program.


.. _Pretty-Printers_For_The_GNAT_Runtime:

Pretty-Printers for the GNAT runtime
------------------------------------

As discussed in :title:`Calling User-Defined Subprograms`, GDB's
``print`` command only knows about the physical layout of program data
structures and therefore normally displays only low-level dumps, which
are often hard to understand.

An example of this is when trying to display the contents of an Ada
standard container, such as ``Ada.Containers.Ordered_Maps.Map``:

  .. code-block:: ada

      with Ada.Containers.Ordered_Maps;

      procedure PP is
         package Int_To_Nat is
            new Ada.Containers.Ordered_Maps (Integer, Natural);

         Map : Int_To_Nat.Map;
      begin
         Map.Insert (1, 10);
         Map.Insert (2, 20);
         Map.Insert (3, 30);

         Map.Clear; --  BREAK HERE
      end PP;

When this program is built with debugging information and run under
``GDB`` up to the ``Map.Clear`` statement, trying to print ``Map`` will
yield information that is only relevant to the developers of the standard
containers:

  ::

      (gdb) print map
      $1 = (
        tree => (
          first => 0x64e010,
          last => 0x64e070,
          root => 0x64e040,
          length => 3,
          tc => (
            busy => 0,
            lock => 0
          )
        )
      )

Fortunately, ``GDB ``has a feature called `pretty-printers
<http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Introduction>`_,
which allows customizing how ``GDB`` displays data structures. The
``GDB`` shipped with GNAT embeds such pretty-printers for the most
common containers in the standard library.  To enable them, either run
the following command manually under ``GDB`` or add it to your
:file:`.gdbinit` file:

  ::

      python import gnatdbg; gnatdbg.setup()

Once you've done this, ``GDB``'s ``print`` command will automatically use
these pretty-printers when appropriate. Using the previous example:

  ::

      (gdb) print map
      $1 = pp.int_to_nat.map of length 3 = {
        [1] = 10,
        [2] = 20,
        [3] = 30
      }

Pretty-printers are invoked each time GDB tries to display a value,
including when displaying the arguments of a called subprogram (in
GDB's ``backtrace`` command) or when printing the value returned by a
function (in GDB's ``finish`` command).

To display a value without involving pretty-printers, you can invoke
``print`` with its ``/r`` option:

  ::

      (gdb) print/r map
      $1 = (
        tree => (...

You can also obtain finer control of pretty-printers: see `GDB's online
documentation
<http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Commands>`_
for more information.


.. index:: Profiling


.. _Profiling:

Profiling
=========

This section describes how to use the ``gprof`` profiler tool on Ada programs.

.. index:: !  gprof
.. index:: Profiling

.. _Profiling_an_Ada_Program_with_gprof:

Profiling an Ada Program with gprof
-----------------------------------

This section is not meant to be an exhaustive documentation of ``gprof``.
You can find full documentation for it in the :title:`GNU Profiler User's Guide`
documentation that is part of this GNAT distribution.

Profiling a program helps determine the parts of a program that are executed
most often and are therefore the most time-consuming.

``gprof`` is the standard GNU profiling tool; it has been enhanced to
better handle Ada programs and multitasking.
It's currently supported on the following platforms

* Linux x86/x86_64
* Windows x86/x86_64 (without PIE support)

In order to profile a program using ``gprof``, you need to perform the
following steps:

#. Instrument the code, which requires a full recompilation of the project with the
   proper switches.

#. Execute the program under the analysis conditions, i.e. with the desired
   input.

#. Analyze the results using the ``gprof`` tool.

The following sections detail the different steps and indicate how
to interpret the results.


.. _Compilation_for_profiling:

Compilation for profiling
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: -pg (gcc), for profiling
.. index:: -pg (gnatlink), for profiling

In order to profile a program, you must first to tell the compiler
to generate the necessary profiling information. You do this using the compiler switch :switch:`-pg`, which you must add to other compilation switches. You need
to specify this
switch during compilation and link stages, and you can
specified it only once when using ``gnatmake``:

  ::

     $ gnatmake -f -pg -P my_project

Note that only the objects that were compiled with the :switch:`-pg` switch will
be profiled; if you need to profile your whole project, use the :switch:`-f`
``gnatmake`` switch to force full recompilation.

Note that on Windows, ``gprof`` does not support PIE. You should add
the :switch:`-no-pie` switch to the linker flags to disable PIE.


.. _Program_execution:


Program execution
^^^^^^^^^^^^^^^^^

Once the program has been compiled for profiling, you can run it as usual.

The only constraint imposed by profiling is that the program must terminate
normally. An interrupted program (via a Ctrl-C, kill, etc.) will not be
properly analyzed.

Once the program completes execution, a data file called :file:`gmon.out` is
generated in the directory where the program was launched from. If this file
already exists, it will be overwritten by running the program.


.. _Running_gprof:

Running gprof
^^^^^^^^^^^^^

You can call the ``gprof`` tool as follows:

  ::

     $ gprof my_prog gmon.out

or simply:

  ::

    $ gprof my_prog

The complete form of the ``gprof`` command line is the following:

  ::

     $ gprof [switches] [executable [data-file]]

``gprof`` supports numerous switches, whose order does not matter. You
can find the full list of switches in the :title:`GNU Profiler
User's Guide`.

The following are the most relevant of those switches:

.. index:: --demangle (gprof)

:switch:`--demangle[={style}]`, :switch:`--no-demangle`
  These switches control whether symbol names should be demangled when
  printing output.  The default is to demangle C++ symbols.  You can use
  :switch:`--no-demangle` to turn off demangling. Different
  compilers have different mangling styles.  The optional demangling style
  argument can be used to choose an appropriate demangling style for your
  compiler, in particular Ada symbols generated by GNAT can be demangled using
  :switch:`--demangle=gnat`.


.. index:: -e (gprof)

:switch:`-e {function_name}`
  The :switch:`-e {function}` option tells ``gprof`` not to print
  information about the function ``function_name`` and its
  children in the call graph.  The function will still be listed
  as a child of any functions that call it, but its index number will be
  shown as ``[not printed]``.  You may specify more than one :switch:`-e` switch,
  but you may only include one ``function_name``  with each :switch:`-e`
  switch.


.. index:: -E (gprof)

:switch:`-E {function_name}`
  The :switch:`-E {function}` switch works like the :switch:`-e` switch, but
  execution time spent in the function (and children who were not called from
  anywhere else) will not be used to compute the percentages-of-time for
  the call graph.  You may specify more than one :switch:`-E` switch, but
  you may only include one  ``function_name`` with each :switch:`-E` switch.


.. index:: -f (gprof)

:switch:`-f {function_name}`
  The :switch:`-f {function}` switch causes ``gprof`` to limit the
  call graph to the function ``function_name`` and its children and
  their children.  You may specify more than one :switch:`-f` switch,
  but you may only include one ``function_name`` with each :switch:`-f` switch.


.. index:: -F (gprof)

:switch:`-F {function_name}`
  The :switch:`-F {function}` switch works like the :switch:`-f` switch, but
  only time spent in the function and its children and their
  children will be used to determine total-time and
  percentages-of-time for the call graph.  You may specify more than one
  :switch:`-F` switch, but you may include only one ``function_name``  with each
  :switch:`-F` switch.  The :switch:`-F` switch overrides the :switch:`-E`
  switch.


.. _Interpretation_of_profiling_results:

Interpretation of profiling results
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The results of the profiling analysis are represented by two arrays:
the 'flat profile' and the 'call graph'. You can find full
documentation of those outputs in the :title:`GNU Profiler User's Guide`.

The flat profile shows the time spent in each function of the program and how
many time it has been called. This allows you to easily locate the most
time-consuming functions.

The call graph shows, for each subprogram, the subprograms that call it,
and the subprograms that it calls. It also provides an estimate of the time
spent in each of those callers and called subprograms.



.. _Improving_Performance:

Improving Performance
=====================

.. index:: Improving performance

This section presents several topics related to program performance.
It first describes some of the tradeoffs that you need to consider
and some of the techniques for making your program run faster.

It then documents the unused subprogram/data elimination feature,
which can reduce the size of program executables.

.. _Performance_Considerations:

Performance Considerations
--------------------------

The GNAT system provides a number of options that allow a trade-off
between:

* performance of the generated code

* speed of compilation

* minimization of dependences and recompilation

* the degree of run-time checking.

The default (if you don't select any switches) aims at improving the speed
of compilation and minimizing dependences, at the expense of performance
of the generated code and consists of:

* no optimization

* no inlining of subprogram calls

* all run-time checks enabled except overflow and elaboration checks

These options are suitable for most program development purposes. This
section describes how you can modify these choices and also provides
some guidelines on debugging optimized code.


.. _Controlling_Run-Time_Checks:

Controlling Run-Time Checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, GNAT generates all run-time checks, except stack overflow
checks and checks for access before elaboration on subprogram
calls. The latter are not required in default mode because all
necessary checking is done at compile time.

.. index:: -gnatp (gcc)
.. index:: -gnato (gcc)

The GNAT switch, :switch:`-gnatp` allows you to modify this default; see
:ref:`Run-Time_Checks`.

Our experience is that the default is suitable for most development
purposes.

Elaboration checks are off by default and also not needed by default
since GNAT uses a static elaboration analysis approach that avoids the
need for run-time checking. This manual contains a full chapter
discussing the issue of elaboration checks and you should read this
chapter if the default is not satisfactory for your use,

For validity checks, the minimal checks required by the Ada Reference
Manual (for case statements and assignments to array elements) are enabled
by default. You can suppress these by using the :switch:`-gnatVn` switch.
Note that in Ada 83, there were no validity checks, so if the Ada 83 mode
is acceptable (or when comparing GNAT performance with an Ada 83 compiler),
it may be reasonable to routinely use :switch:`-gnatVn`. Validity checks
are also suppressed entirely if you use :switch:`-gnatp`.

.. index:: Overflow checks
.. index:: Checks, overflow

.. index:: Suppress
.. index:: Unsuppress
.. index:: pragma Suppress
.. index:: pragma Unsuppress

Note that the setting of the switches controls the default setting of
the checks. You may modify them using either ``pragma Suppress`` (to
remove checks) or ``pragma Unsuppress`` (to add back suppressed
checks) in your program source.


.. _Use_of_Restrictions:

Use of Restrictions
^^^^^^^^^^^^^^^^^^^

You can use pragma Restrictions to control which features are
permitted in your program. In most cases, the use of this pragma
itself does not affect the generated code (but, of course, if you
avoid relatively expensive features like finalization, you'll have
more efficient programs and that's enforceable by the use of pragma
Restrictions (No_Finalization).

One notable exception to this rule is that the possibility of task abort
results in some distributed overhead, particularly if finalization or
exception handlers are used. This is because certain sections of code
must be marked as non-abortable.

If you use neither the ``abort`` statement nor asynchronous transfer
of control (``select ... then abort``), this distributed overhead can
be removed, which may have a general positive effect in improving
overall performance, especially in code involving frequent use of
tasking constructs and controlled types, which will show much improved
performance.  The relevant restrictions pragmas are

  .. code-block:: ada

      pragma Restrictions (No_Abort_Statements);
      pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);

We recommend that you use these restriction pragmas if possible. If you do
this, it also means you can write code without worrying about the
possibility of an immediate abort at any point.


.. _Optimization_Levels:

Optimization Levels
^^^^^^^^^^^^^^^^^^^

.. index:: -O (gcc)

Without any optimization switch, the compiler's goal is to reduce the
cost of compilation and to make debugging produce the expected
results.  This means that statements are independent: if you stop the
program with a breakpoint between statements, you can then assign a
new value to any variable or change the program counter to any other
statement in the subprogram and get exactly the results you would
expect from the source code. However, the generated programs are
considerably larger and slower than when optimization is enabled.

Turning on optimization makes the compiler attempt to improve the
performance and/or code size at the expense of compilation time and
possibly the ability to debug the program.

You can pass the :switch:`-O` switch, with or without an operand
(the permitted forms with an operand are :switch:`-O0`, :switch:`-O1`,
:switch:`-O2`, :switch:`-O3`, :switch:`-Os`, :switch:`-Oz`, and
:switch:`-Og`) to ``gcc`` to control the optimization level. If you
pass multiple :switch:`-O` switches, with or without an operand,
the last such switch is the one that's used:


* :switch:`-O0`
    No optimization (the default); generates unoptimized code but has
    the fastest compilation time. Debugging is easiest with this switch.

    Note that many other compilers do substantial optimization even if
    'no optimization' is specified. With GCC, it is very unusual to
    use :switch:`-O0` for production if execution time is of any
    concern, since :switch:`-O0` means (almost) no optimization. You
    should keep this difference between GCC and other compilers in
    mind when doing performance comparisons.

* :switch:`-O1`
    Moderate optimization (same as :switch:`-O` without an operand);
    optimizes reasonably well but does not degrade compilation time
    significantly. You may not be able to see some variables in the
    debugger, and changing the value of some variables in the debugger
    may not have the effect you desire.

* :switch:`-O2`
    Extensive optimization; generates highly optimized code but has
    an increased compilation time. You may see significant impacts on
    your ability to display and modify variables in the debugger.

* :switch:`-O3`
    Full optimization; attempts more sophisticated transformations, in
    particular on loops, possibly at the cost of larger generated code.
    You may be hardly able to use the debugger at this optimization level.

* :switch:`-Os`
    Optimize for size (code and data) of resulting binary rather than
    speed; based on the :switch:`-O2` optimization level, but disables
    some of its transformations that often increase code size, as well
    as performs further optimizations designed to reduce code size.

* :switch:`-Oz`
    Optimize aggressively for size (code and data) of resulting binary
    rather than speed; may increase the number of instructions executed
    if these instructions require fewer bytes to be encoded.

* :switch:`-Og`
    Optimize for debugging experience rather than speed; based on the
    :switch:`-O1` optimization level, but attempts to eliminate all the
    negative effects of optimization on debugging.


Higher optimization levels perform more global transformations on the
program and apply more expensive analysis algorithms in order to generate
faster and more compact code. The price in compilation time, and the
resulting 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.

Since the precise set of optimizations done at each level will vary from
release to release (and sometime from target to target), it is best to think
of the optimization settings in general terms.
See the *Options That Control Optimization* section in
:title:`Using the GNU Compiler Collection (GCC)`
for details about
the :switch:`-O` settings and a number of :switch:`-f` switches that
individually enable or disable specific optimizations.

Unlike some other compilation 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.

A note regarding the use of :switch:`-O3`: The use of this optimization level
ought not to be automatically preferred over that of level :switch:`-O2`,
since it often results in larger executables which may run more slowly.
See further discussion of this point in :ref:`Inlining_of_Subprograms`.


.. _Debugging_Optimized_Code:

Debugging Optimized Code
^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Debugging optimized code
.. index:: Optimization and debugging

Although it is possible to do a reasonable amount of debugging at
nonzero optimization levels,
the higher the level the more likely that
source-level constructs will have been eliminated by optimization.
For example, if a loop is strength-reduced, the loop
control variable may be completely eliminated and thus cannot be
displayed in the debugger.
This can only happen at :switch:`-O2` or :switch:`-O3`.
Explicit temporary variables that you code might be eliminated at
level :switch:`-O1` or higher.

.. index:: -g (gcc)

The use of the :switch:`-g` switch,
which is needed for source-level debugging,
affects the size of the program executable on disk,
and indeed the debugging information can be quite large.
However, it has no effect on the generated code (and thus does not
degrade performance)

Since the compiler generates debugging tables for a compilation unit before
it performs optimizations, the optimizing transformations may invalidate some
of the debugging data.  You therefore need to anticipate certain
anomalous situations that may arise while debugging optimized code.
These are the most common cases:

* *The 'hopping Program Counter':*  Repeated ``step`` or ``next``
  commands show
  the PC bouncing back and forth in the code.  This may result from any of
  the following optimizations:

  - *Common subexpression elimination:* using a single instance of code for a
    quantity that the source computes several times.  As a result you
    may not be able to stop on what looks like a statement.

  - *Invariant code motion:* moving an expression that does not change within a
    loop to the beginning of the loop.

  - *Instruction scheduling:* moving instructions so as to
    overlap loads and stores (typically) with other code or in
    general to move computations of values closer to their uses. Often
    this causes you to pass an assignment statement without the assignment
    happening and then later bounce back to the statement when the
    value is actually needed.  Placing a breakpoint on a line of code
    and then stepping over it may, therefore, not always cause all the
    expected side-effects.

* *The 'big leap':* More commonly known as *cross-jumping*, in which
  two identical pieces of code are merged and the program counter suddenly
  jumps to a statement that is not supposed to be executed, simply because
  it (and the code following) translates to the same thing as the code
  that *was* supposed to be executed.  This effect is typically seen in
  sequences that end in a jump, such as a ``goto``, a ``return``, or
  a ``break`` in a C ``switch`` statement.

* *The 'roving variable':* The symptom is an unexpected value in a variable.
  There are various reasons for this effect:

  - In a subprogram prologue, a parameter may not yet have been moved to its
    'home'.

  - A variable may be dead and its register re-used.  This is
    probably the most common cause.

  - As mentioned above, the assignment of a value to a variable may
    have been moved.

  - A variable may be eliminated entirely by value propagation or
    other means.  In this case, GCC may incorrectly generate debugging
    information for the variable

  In general, when an unexpected value appears for a local variable or parameter
  you should first ascertain if that value was actually computed by
  your program as opposed to being incorrectly reported by the debugger.
  Record fields or
  array elements in an object designated by an access value
  are generally less of a problem once you have verified that the access
  value is sensible.
  Typically, this means checking variables in the preceding code and in the
  calling subprogram to verify that the value observed is explainable from other
  values (you must apply the procedure recursively to those
  other values); or re-running the code and stopping a little earlier
  (perhaps before the call) and stepping to better see how the variable obtained
  the value in question; or continuing to step *from* the point of the
  strange value to see if code motion had simply moved the variable's
  assignments later.

In light of such anomalies, a recommended technique is to use :switch:`-O0`
early in the software development cycle, when extensive debugging capabilities
are most needed, and then move to :switch:`-O1` and later :switch:`-O2` as
the debugger becomes less critical.
Whether to use the :switch:`-g` switch in the release version is
a release management issue.
Note that if you use :switch:`-g` you can then use the ``strip`` program
on the resulting executable,
which removes both debugging information and global symbols.


.. _Inlining_of_Subprograms:

Inlining of Subprograms
^^^^^^^^^^^^^^^^^^^^^^^

A call to a subprogram in the current unit is inlined if all the
following conditions are met:

* The optimization level is at least :switch:`-O1`.

* The called subprogram is suitable for inlining: it must be small enough
  and not contain something that the back end cannot support in inlined
  subprograms.

  .. index:: pragma Inline
  .. index:: Inline

* Any one of the following applies: ``pragma Inline`` is applied to the
  subprogram; the subprogram is local to the unit and called once from
  within it; the subprogram is small and optimization level :switch:`-O2` is
  specified; optimization level :switch:`-O3` is specified; or the subprogram
  is an expression function.

Calls to subprograms in |withed| units are normally not inlined.
To achieve inlining in those case (that is, replacement of the call by the code
in the body of the subprogram), the following conditions must all be true:

* The optimization level is at least :switch:`-O1`.

* The called subprogram is suitable for inlining: It must be small enough
  and not contain something that the back end cannot support in inlined
  subprograms.

* There is a ``pragma Inline`` for the subprogram.

* The :switch:`-gnatn` switch is used on the command line.

Even if all these conditions are met, it may not be possible for
the compiler to inline the call due to the length of the body,
or features in the body that make it impossible for the compiler
to do the inlining.

Note that specifying the :switch:`-gnatn` switch causes additional
compilation dependencies. Consider the following:

  .. code-block:: ada

      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 :switch:`-gnatn` switch specified), the
compilation of the ``Main`` procedure depends only on its own source,
:file:`main.adb`, and the spec of the package in file :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 :switch:`-gnatn` switch is present when ``Main``
is compiled, the call will be inlined if the body of ``Q`` is small
enough, but now ``Main`` depends on the body of ``R`` in
:file:`r.adb` as well as on the spec. This means that if this body is edited,
the main program must be recompiled. Note that this extra dependency
occurs whether or not the call is in fact inlined by the back end.

The use of front end inlining with :switch:`-gnatN` generates similar
additional dependencies.

.. index:: -fno-inline (gcc)

Note: The :switch:`-fno-inline` switch overrides all other conditions
and ensures that no inlining occurs, unless requested with pragma
Inline_Always for most back ends. The extra dependences resulting from
:switch:`-gnatn` will still be active, even if this switch is used to
suppress the resulting inlining actions.

.. index:: -fno-inline-functions (gcc)

For the GCC back end, you can use the
:switch:`-fno-inline-functions` switch to prevent automatic inlining
of subprograms if you use :switch:`-O3`.

.. index:: -fno-inline-small-functions (gcc)

For the GCC back end, you can use the
:switch:`-fno-inline-small-functions` switch to prevent automatic
inlining of small subprograms if you use :switch:`-O2`.

.. index:: -fno-inline-functions-called-once (gcc)

For the GC back end, you can use the
:switch:`-fno-inline-functions-called-once` switch to prevent inlining
of subprograms local to the unit and called once from within it if you
use :switch:`-O1`.

A note regarding the use of :switch:`-O3`: :switch:`-gnatn` is made up of two
sub-switches :switch:`-gnatn1` and :switch:`-gnatn2` that you can directly
specify. :switch:`-gnatn` is translated into one of them
based on the optimization level. With :switch:`-O2` or below, :switch:`-gnatn`
is equivalent to :switch:`-gnatn1` which activates pragma ``Inline`` with
moderate inlining across modules. With :switch:`-O3`, :switch:`-gnatn` is
equivalent to :switch:`-gnatn2` which activates pragma ``Inline`` with
full inlining across modules. If you have used pragma ``Inline`` in
appropriate cases, it's usually much better to use :switch:`-O2`
and :switch:`-gnatn` and avoid the use of :switch:`-O3` which has the additional
effect of inlining subprograms you did not think should be inlined. We have
found that the use of :switch:`-O3` may slow down the compilation and increase
the code size by performing excessive inlining, leading to increased
instruction cache pressure from the increased code size and thus minor
performance degradations. So the bottom line here is that you should not
automatically assume that :switch:`-O3` is better than :switch:`-O2` and
indeed you should use :switch:`-O3` only if tests show that it actually
improves performance for your program.

.. _Floating_Point_Operations:

Floating Point Operations
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Floating-Point Operations

On almost all targets, GNAT maps ``Float`` and ``Long_Float`` to the 32-bit and
64-bit standard IEEE floating-point representations and operations will
use standard IEEE arithmetic as provided by the processor. On most, but
not all, architectures, the attribute ``Machine_Overflows`` is ``False`` for these
types, meaning that the semantics of overflow is implementation-defined.
In the case of GNAT, these semantics correspond to the normal IEEE
treatment of infinities and NaN (not a number) values. For example,
1.0 / 0.0 yields plus infinitiy and 0.0 / 0.0 yields a NaN. By
avoiding explicit overflow checks, the performance is greatly improved
on many targets. However, if required, you can enable floating-point overflow
by using the pragma ``Check_Float_Overflow``.

Another consideration that applies specifically to x86 32-bit
architectures is which form of floating-point arithmetic is used.
By default, the operations use the old style x86 floating-point,
which implements an 80-bit extended precision form (on these
architectures the type ``Long_Long_Float`` corresponds to that form).
In addition, generation of efficient code in this mode means that
the extended precision form is used for intermediate results.
This may be helpful in improving the final precision of a complex
expression, but it means that the results obtained on the x86
may be different from those on other architectures and, for some
algorithms, the extra intermediate precision can be detrimental.

In addition to this old-style floating-point, all modern x86 chips
implement an alternative floating-point operation model referred
to as SSE2. In this model, there is no extended form and
execution performance is significantly enhanced. To force GNAT to use
this more modern form, use both of the switches:

   -msse2 -mfpmath=sse

A unit compiled with these switches will automatically use the more
efficient SSE2 instruction set for ``Float`` and ``Long_Float`` operations.
Note that the ABI has the same form for both floating-point models,
so you can mix units compiled with and without these switches.





.. _Vectorization_of_loops:

Vectorization of loops
^^^^^^^^^^^^^^^^^^^^^^

.. index:: Optimization Switches

The GCC and LLVM back ends have an auto-vectorizer that's enabled by
default at some optimization levels.  For the GCC back end, it's
enabled by default at :switch:`-O3` and you can request it at other
levels with :switch:`-ftree-vectorize`. For the LLVM back end, it's
enabled by default at lower levels, but you can explicitly enable or
disable it with the :switch:`-fno-vectorize`, :switch:`-fvectorize`,
:switch:`-fno-slp-vectorize`, and :switch:`-fslp-vectorize` switches.

To get auto-vectorization, you also need to make sure that the target
architecture features a supported SIMD instruction set.  For example,
for the x86 architecture, you should at least specify :switch:`-msse2`
to get significant vectorization (but you don't need to specify it for
x86-64 as it is part of the base 64-bit architecture).  Similarly, for
the PowerPC architecture, you should specify :switch:`-maltivec`.

The preferred loop form for vectorization is the ``for`` iteration scheme.
Loops with a ``while`` iteration scheme can also be vectorized if they are
very simple, but the vectorizer will quickly give up otherwise.  With either
iteration scheme, the flow of control must be straight, in particular no
``exit`` statement may appear in the loop body.  The loop may however
contain a single nested loop, if it can be vectorized when considered alone:

  .. code-block:: ada

       A : array (1..4, 1..4) of Long_Float;
       S : array (1..4) of Long_Float;

       procedure Sum is
       begin
          for I in A'Range(1) loop
             for J in A'Range(2) loop
                S (I) := S (I) + A (I, J);
             end loop;
          end loop;
       end Sum;

The vectorizable operations depend on the targeted SIMD instruction set, but
addition and some multiplication operators are generally supported, as
well as the logical operators for modular types. Note that compiling
with :switch:`-gnatp` might well reveal cases where some checks do thwart
vectorization.

Type conversions may also prevent vectorization if they involve semantics that
are not directly supported by the code generator or the SIMD instruction set.
A typical example is direct conversion from floating-point to integer types.
The solution in this case is to use the following idiom:

  .. code-block:: ada

       Integer (S'Truncation (F))

if ``S`` is the subtype of floating-point object ``F``.

In most cases, the vectorizable loops are loops that iterate over arrays.
All kinds of array types are supported, i.e. constrained array types with
static bounds:

  .. code-block:: ada

       type Array_Type is array (1 .. 4) of Long_Float;

constrained array types with dynamic bounds:


  .. code-block:: ada

     type Array_Type is array (1 .. Q.N) of Long_Float;

     type Array_Type is array (Q.K .. 4) of Long_Float;

     type Array_Type is array (Q.K .. Q.N) of Long_Float;

or unconstrained array types:

  .. code-block:: ada

      type Array_Type is array (Positive range <>) of Long_Float;

The quality of the generated code decreases when the dynamic aspect of the
array type increases, the worst code being generated for unconstrained array
types.  This is because the less information the compiler has about the
bounds of the array, the more fallback code it needs to generate in order to
fix things up at run time.

You can specify that a given loop should be subject to vectorization
preferably to other optimizations by means of pragma ``Loop_Optimize``:

  .. code-block:: ada

      pragma Loop_Optimize (Vector);

placed immediately within the loop will convey the appropriate hint to the
compiler for this loop. This is currently only supported for the GCC
back end.

You can also help the compiler generate better vectorized code
for a given loop by asserting that there are no loop-carried dependencies
in the loop.  Consider for example the procedure:

  .. code-block:: ada

      type Arr is array (1 .. 4) of Long_Float;

      procedure Add (X, Y : not null access Arr; R : not null access Arr) is
      begin
        for I in Arr'Range loop
          R(I) := X(I) + Y(I);
        end loop;
      end;

By default, the compiler cannot unconditionally vectorize the loop because
assigning to a component of the array designated by R in one iteration could
change the value read from the components of the array designated by X or Y
in a later iteration.  As a result, the compiler will generate two versions
of the loop in the object code, one vectorized and the other not vectorized,
as well as a test to select the appropriate version at run time.  This can
be overcome by another hint:

  .. code-block:: ada

     pragma Loop_Optimize (Ivdep);

placed immediately within the loop will tell the compiler that it can safely
omit the non-vectorized version of the loop as well as the run-time test.
This is also currently only supported by the GCC back end.


.. _Other_Optimization_Switches:

Other Optimization Switches
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Optimization Switches

You can also use any specialized optimization switches supported by
the back end being used.  These switches have not been extensively
tested with GNAT but can generally be expected to work. Examples of
switches in this category for the GCC back end are
:switch:`-funroll-loops` and the various target-specific :switch:`-m`
options (in particular, it has been observed that :switch:`-march=xxx`
can significantly improve performance on appropriate machines). For
full details of these switches, see the *Submodel Options* section in
the *Hardware Models and Configurations* chapter of :title:`Using the
GNU Compiler Collection (GCC)`.


.. _Optimization_and_Strict_Aliasing:

Optimization and Strict Aliasing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Aliasing
.. index:: Strict Aliasing
.. index:: No_Strict_Aliasing

The strong typing capabilities of Ada allow an optimizer to generate
efficient code in situations where other languages would be forced to
make worst case assumptions preventing such optimizations. Consider
the following example:

  .. code-block:: ada

     procedure M is
        type Int1 is new Integer;
        I1 : Int1;

        type Int2 is new Integer;
        type A2 is access Int2;
        V2 : A2;
        ...

     begin
        ...
        for J in Data'Range loop
           if Data (J) = I1 then
              V2.all := V2.all + 1;
           end if;
        end loop;
        ...
     end;

Here, since ``V2`` can only access objects of type ``Int2``
and ``I1`` is not one of them, there is no possibility that the assignment
to ``V2.all`` affects the value of ``I1``. This means that the compiler
optimizer can infer that the value ``I1`` is constant for all iterations
of the loop and load it from memory only once, before entering the loop,
instead of in every iteration (this is called load hoisting).

This kind of optimizations, based on strict type-based aliasing, is
triggered by specifying an optimization level of :switch:`-O2` or
higher (or :switch:`-Os`) for the GCC back end and :switch:`-O1` or
higher for the LLVM back end and allows the compiler to generate more
efficient code.

However, although this optimization is always correct in terms of the
formal semantics of the Ada Reference Manual, you can run into
difficulties arise if you use features like ``Unchecked_Conversion``
to break the typing system. Consider the following complete program
example:

  .. code-block:: ada

      package P1 is
         type Int1 is new Integer;
         type A1 is access Int1;

         type Int2 is new Integer;
         type A2 is access Int2;
      end P1;

      with P1; use P1;
      package P2 is
         function To_A2 (Input : A1) return A2;
      end p2;

      with Ada.Unchecked_Conversion;
      package body P2 is
         function To_A2 (Input : A1) return A2 is
            function Conv is
              new Ada.Unchecked_Conversion (A1, A2);
         begin
            return Conv (Input);
         end To_A2;
      end P2;

      with P1; use P1;
      with P2; use P2;
      with Text_IO; use Text_IO;
      procedure M is
         V1 : A1 := new Int1;
         V2 : A2 := To_A2 (V1);
      begin
         V1.all := 1;
         V2.all := 0;
         Put_Line (Int1'Image (V1.all));
      end;

This program prints out ``0`` in :switch:`-O0` mode,
but it prints out ``1`` in :switch:`-O2` mode. That's because in strict
aliasing mode, the compiler may and does assume that the assignment to
``V2.all`` could not affect the value of ``V1.all``, since different
types are involved.

This behavior is not a case of non-conformance with the standard, since
the Ada RM specifies that an unchecked conversion where the resulting
bit pattern is not a correct value of the target type can result in an
abnormal value and attempting to reference an abnormal value makes the
execution of a program erroneous.  That's the case here since the result
does not point to an object of type ``Int2``.  This means that the effect
is entirely unpredictable.

However, although that explanation may satisfy a language lawyer, in
practice, you probably expect an unchecked conversion
involving pointers to create true aliases and the behavior of printing
``1`` is questionable. In this case, the strict type-based aliasing
optimizations are clearly unwelcome.

Indeed, the compiler recognizes this possibility and the instantiation of
Unchecked_Conversion generates a warning:

  ::

     p2.adb:5:07: warning: possible aliasing problem with type "A2"
     p2.adb:5:07: warning: use -fno-strict-aliasing switch for references
     p2.adb:5:07: warning:  or use "pragma No_Strict_Aliasing (A2);"

Unfortunately the problem is only recognized when compiling the body of
package ``P2``, but the actual problematic code is generated while
compiling the body of ``M`` and this latter compilation does not see
the suspicious instance of ``Unchecked_Conversion``.

As implied by the warning message, there are approaches you can use to
avoid the unwanted strict aliasing optimizations in a case like this.

One possibility is to simply avoid the use of higher levels of optimization,
but that is quite drastic, since it throws away a number of useful
optimizations that don't involve strict aliasing assumptions.

A less drastic approach is for you to compile the program using the
:switch:`-fno-strict-aliasing` switch. Actually, it is only the
unit containing the dereferencing of the suspicious pointer
that you need to compile with that switch. So, in this case, if you compile
unit ``M`` with this switch, you get the expected
value of ``0`` printed. Analyzing which units might need
the switch can be painful, so you may find it a more reasonable approach
is to compile the entire program with options :switch:`-O2`
and :switch:`-fno-strict-aliasing`. If you obtain satisfactory performance
with this combination of options, then the
advantage is that you have avoided the entire issue of possible problematic
optimizations due to strict aliasing.

To avoid the use of compiler switches, you may use the configuration
pragma ``No_Strict_Aliasing`` with no parameters
to specify that for all access types, the strict
aliasing optimizations should be suppressed.

However, these approaches are still overkill, in that they cause
all manipulations of all access values to be deoptimized. A more
refined approach is to concentrate attention on the specific
access type identified as problematic.

The first possibility is to move the instantiation of unchecked
conversion to the unit in which the type is declared. In this
example, you would move the instantiation of ``Unchecked_Conversion``
from the body of package ``P2`` to the spec of package ``P1``.
Now, the warning disappears because any use of the access type
knows there is a suspicious unchecked conversion and the strict
aliasing optimizations are automatically suppressed for it.

If it's not practical to move the unchecked conversion to the same unit
in which the destination access type is declared (perhaps because the
source type is not visible in that unit), the second possibility is for you to
use pragma ``No_Strict_Aliasing`` for the type. You must place this pragma
in the same declarative part as the declaration of the access type:

  .. code-block:: ada

     type A2 is access Int2;
     pragma No_Strict_Aliasing (A2);

Here again, the compiler now knows that strict aliasing optimizations
should be suppressed for any dereference made through type ``A2`` and
the expected behavior is obtained.

The third possibility is to declare that one of the designated types
involved, namely ``Int1`` or ``Int2``, is allowed to alias any other
type in the universe, by using pragma ``Universal_Aliasing``:

  .. code-block:: ada

     type Int2 is new Integer;
     pragma Universal_Aliasing (Int2);

The effect is equivalent to applying pragma ``No_Strict_Aliasing`` to
every access type designating ``Int2``, in particular ``A2``, and, more
generally, to every reference made to an object of declared type ``Int2``,
so it's very powerful and effectively takes ``Int2`` out of the alias
analysis performed by the compiler in all circumstances.

You can also use this pragma used to deal with aliasing issues that arise
from the use of ``Unchecked_Conversion`` in the source code but
without the presence of access types. The typical example is code
that streams data by means of arrays of storage units (bytes):

 .. code-block:: ada

    type Byte is mod 2**System.Storage_Unit;
    for Byte'Size use System.Storage_Unit;

    type Chunk_Of_Bytes is array (1 .. 64) of Byte;

    procedure Send (S : Chunk_Of_Bytes);

    type Rec is record
       ...
    end record;

    procedure Dump (R : Rec) is
       function To_Stream is
          new Ada.Unchecked_Conversion (Rec, Chunk_Of_Bytes);
    begin
       Send (To_Stream (R));
    end;

This generates the following warning for the call to ``Send``:

  ::

     dump.adb:8:25: warning: unchecked conversion implemented by copy
     dump.adb:8:25: warning: use pragma Universal_Aliasing on either type
     dump.adb:8:25: warning: to enable RM 13.9(12) implementation permission

This occurs because the formal parameter ``S`` of ``Send`` is passed by
reference by the compiler and it's not possible to pass a reference to
``R`` directly in the call without violating strict type-based aliasing.
That's why the compiler generates a temporary of type ``Chunk_Of_Bytes``
just before the call and passes a reference to this temporary instead.

As implied by the warning message, you can avoid the temporary
(and the warning) by means of pragma ``Universal_Aliasing``:

 .. code-block:: ada

    type Chunk_Of_Bytes is array (1 .. 64) of Byte;
    pragma Universal_Aliasing (Chunk_Of_Bytes);

You can also apply this pragma to the component type instead:

 .. code-block:: ada

    type Byte is mod 2**System.Storage_Unit;
    for Byte'Size use System.Storage_Unit;
    pragma Universal_Aliasing (Byte);

and every array type whose component is ``Byte`` will inherit the pragma.

To summarize, the alias analysis performed in strict aliasing mode by
the compiler can have significant benefits. We've seen cases of large
scale application code where the execution time is increased by up to
5% when these optimizations are turned off. However, if you have code
that make significant use of unchecked conversion, you might want to
just stick with :switch:`-O1` (with the GCC back end) and avoid the
entire issue. If you get adequate performance at this level of
optimization, that's probably the safest approach. If tests show that
you really need higher levels of optimization, then you can experiment
with :switch:`-O2` and :switch:`-O2 -fno-strict-aliasing` to see how
much effect this has on size and speed of the code. If you really need
to use :switch:`-O2` with strict aliasing in effect, then you should
review any uses of unchecked conversion, particularly if you are
getting the warnings described above.


.. _Aliased_Variables_and_Optimization:

Aliased Variables and Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Aliasing

There are scenarios in which your programs may
use low level techniques to modify variables
that otherwise might be considered to be unassigned. For example,
you can pass a variable to a procedure by reference by taking
the address of the parameter and using that address to modify the
variable's value, even though the address is passed as an ``in`` parameter.
Consider the following example:

  .. code-block:: ada

     procedure P is
        Max_Length : constant Natural := 16;
        type Char_Ptr is access all Character;

        procedure Get_String(Buffer: Char_Ptr; Size : Integer);
        pragma Import (C, Get_String, "get_string");

        Name : aliased String (1 .. Max_Length) := (others => ' ');
        Temp : Char_Ptr;

        function Addr (S : String) return Char_Ptr is
           function To_Char_Ptr is
             new Ada.Unchecked_Conversion (System.Address, Char_Ptr);
        begin
           return To_Char_Ptr (S (S'First)'Address);
        end;

     begin
        Temp := Addr (Name);
        Get_String (Temp, Max_Length);
     end;

where Get_String is a C function that uses the address in ``Temp`` to
modify the variable ``Name``. This code is dubious, and arguably
erroneous, and the compiler is entitled to assume that
``Name`` is never modified, and generate code accordingly.

However, in practice, this could cause some existing code that
seems to work with no optimization to start failing at higher
levels of optimization.

What the compiler does for such cases, is to assume that marking a
variable as aliased indicates that some "funny business" may be going
on. The optimizer recognizes the ``aliased`` keyword and inhibits any
optimizations that assume the variable cannot be assigned to.  This
means that the above example will in fact "work" reliably, that is, it
will produce the expected results. However, you should nevertheless
avoid code such as this if possible because it's not portable and may not
function as you expect with all compilers.


.. _Atomic_Variables_and_Optimization:

Atomic Variables and Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Atomic

You need to take two things into consideration with regard to performance when
you use atomic variables.

First, the RM only guarantees that access to atomic variables
be atomic, but has nothing to say about how this is achieved,
though there is a strong implication that this should not be
achieved by explicit locking code. Indeed, GNAT never
generates any locking code for atomic variable access; it will
simply reject any attempt to make a variable or type atomic
if the atomic access cannot be achieved without such locking code.

That being said, it's important to understand that you cannot
assume the the program will always access the entire variable. Consider
this example:

  .. code-block:: ada

     type R is record
        A,B,C,D : Character;
     end record;
     for R'Size use 32;
     for R'Alignment use 4;

     RV : R;
     pragma Atomic (RV);
     X : Character;
     ...
     X := RV.B;

You cannot assume that the reference to ``RV.B``
will read the entire 32-bit
variable with a single load instruction. It is perfectly legitimate, if
the hardware allows it, to do a byte read of just the ``B`` field. This read
is still atomic, which is all the RM requires. GNAT can and does take
advantage of this, depending on the architecture and optimization level.
Any assumption to the contrary is non-portable and risky. Even if you
examine the assembly language and see a full 32-bit load, this might
change in a future version of the compiler.

If your application requires that all accesses to ``RV`` in this
example be full 32-bit loads, you need to make a copy for the access
as in:

  .. code-block:: ada

     declare
        RV_Copy : constant R := RV;
     begin
        X := RV_Copy.B;
     end;

Now the reference to ``RV`` must read the whole variable.
Actually, one can imagine some compiler which figures
out that the whole copy is not required (because only
the ``B`` field is actually accessed), but GNAT
certainly won't do that, and we don't know of any
compiler that would not handle this right, and the
above code will in practice work portably across
all architectures (that permit the Atomic declaration).

The second issue with atomic variables has to do with
the possible requirement of generating synchronization
code. For more details on this, consult the sections on
the pragmas Enable/Disable_Atomic_Synchronization in the
:title:``GNAT Reference Manual``. If performance is critical, and
such synchronization code is not required, you may find it
useful to disable it.


.. _Passive_Task_Optimization:

Passive Task Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Passive Task

A passive task is one which is sufficiently simple that,
in theory, a compiler could recognize it and implement it
efficiently without creating a new thread. The original design
of Ada 83 had in mind this kind of passive task optimization, but
only a few Ada 83 compilers attempted it. The reason was that
it was difficult to determine the exact conditions under which
the optimization was possible. The result is a very fragile
optimization where a very minor change in the program can
suddenly silently make a task non-optimizable.

With the revisiting of this issue in Ada 95, there was general
agreement that this approach was fundamentally flawed and the
notion of protected types was introduced. When using protected
types, the restrictions are well defined, you KNOW that the
operations will be optimized, and furthermore this optimized
performance is fully portable.

Although it would theoretically be possible for GNAT to attempt to
do this optimization, it really doesn't make sense in the
context of Ada 95 and none of the Ada 95 compilers implement
this optimization as far as we know. GNAT never
attempts to perform this optimization.

In any new Ada 95 code that you write, you should always
use protected types in place of tasks that might be able to
be optimized in this manner.
Of course, this does not help if you have legacy Ada 83 code
that depends on this optimization, but it is unusual to encounter
a case where the performance gains from this optimization
are significant.

Your program should work correctly without this optimization. If
you have performance problems, the most practical
approach is to figure out exactly where these performance problems
arise and update those particular tasks to be protected types. Note
that typically clients of the tasks who call entries will not have
to be modified, only the task definitions themselves.


.. _Text_IO_Suggestions:

``Text_IO`` Suggestions
-----------------------

.. index:: Text_IO and performance

The ``Ada.Text_IO`` package has fairly high overhead due in part to
the requirement of maintaining page and line counts. If performance
is critical, one recommendation is to use ``Stream_IO`` instead of
``Text_IO`` for large-volume output, since it has less overhead.

If you must use ``Text_IO``, note that output to the standard output and
standard error files is unbuffered by default (this provides
better behavior when output statements are used for debugging or if
the progress of a program is observed by tracking the output, e.g. by
using the Unix *tail -f* command to watch redirected output).

If you're generating large volumes of output with ``Text_IO`` and
performance is an important factor, use a designated file instead
of the standard output file or change the standard output file to
be buffered using ``Interfaces.C_Streams.setvbuf``.


.. _Reducing_Size_of_Executables_with_Unused_Subprogram/Data_Elimination:

Reducing Size of Executables with Unused Subprogram/Data Elimination
--------------------------------------------------------------------

.. index:: Uunused subprogram/data elimination

This section describes how you can eliminate unused subprograms and data from
your executable just by setting options at compilation time.

.. _About_unused_subprogram/data_elimination:

About unused subprogram/data elimination
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, an executable contains all code and data of its objects
(directly linked or coming from statically linked libraries), even data or code
never used by this executable. This feature eliminates such unused code from your
executable, thus making it smaller (in disk and in memory).

You can use this functionality on all Linux platforms except for the IA-64
architecture and on all cross platforms using the ELF binary file format.
In both cases, GNU binutils version 2.16 or later are required to enable it.

.. _Compilation_options:

Compilation options
^^^^^^^^^^^^^^^^^^^

The operation of eliminating the unused code and data from the final executable
is directly performed by the linker.

.. index:: -ffunction-sections (gcc)
.. index:: -fdata-sections (gcc)

In order to do this, it has to work with objects compiled with the
following switches passed to the GCC back end:
:switch:`-ffunction-sections` :switch:`-fdata-sections`.

These options are usable with C and Ada files.
They cause the compiler to place each
function or data in a separate section in the resulting object file.

Once you've created the objects and static libraries with these switches, the
linker can perform the dead code elimination. You can do this by specifying
the :switch:`-Wl,--gc-sections` switch to your ``gcc`` command or in the
:switch:`-largs` section of your invocation of ``gnatmake``. This causes
the linker to perform a
garbage collection and remove code and data that are never referenced.

If the linker performs a partial link (:switch:`-r` linker switch), then you
need to provide the entry point using the :switch:`-e` / :switch:`--entry`
linker switch.

Note that objects compiled without the :switch:`-ffunction-sections` and
:switch:`-fdata-sections` options can still be linked with the executable.
However, no dead code elimination can be performed on those objects (they will
be linked as is).

The GNAT static library is compiled with :switch:`-ffunction-sections`
and :switch:`-fdata-sections` on some platforms. This allows you to
eliminate the unused code and data of the GNAT library from your
executable.


.. _Example_of_unused_subprogram/data_elimination:

Example of unused subprogram/data elimination
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Here's a simple example:

  .. code-block:: ada

     with Aux;

     procedure Test is
     begin
        Aux.Used (10);
     end Test;

     package Aux is
        Used_Data   : Integer;
        Unused_Data : Integer;

        procedure Used   (Data : Integer);
        procedure Unused (Data : Integer);
     end Aux;

     package body Aux is
        procedure Used (Data : Integer) is
        begin
           Used_Data := Data;
        end Used;

        procedure Unused (Data : Integer) is
        begin
           Unused_Data := Data;
        end Unused;
     end Aux;

``Unused`` and ``Unused_Data`` are never referenced in this code
excerpt and hence may be safely removed from the final executable.

  ::

     $ gnatmake test

     $ nm test | grep used
     020015f0 T aux__unused
     02005d88 B aux__unused_data
     020015cc T aux__used
     02005d84 B aux__used_data

     $ gnatmake test -cargs -fdata-sections -ffunction-sections \\
          -largs -Wl,--gc-sections

     $ nm test | grep used
     02005350 T aux__used
     0201ffe0 B aux__used_data

You can see that the procedure ``Unused`` and the object
``Unused_Data`` are removed by the linker when you've used the
appropriate switches.


.. index:: Overflow checks
.. index:: Checks (overflow)

.. _Overflow_Check_Handling_in_GNAT:

Overflow Check Handling in GNAT
===============================

This section explains how to control the handling of overflow checks.

.. _Background:

Background
----------

Overflow checks are checks that the compiler may make to ensure
that intermediate results are not out of range. For example:

  .. code-block:: ada

     A : Integer;
     ...
     A := A + 1;

If ``A`` has the value ``Integer'Last``, the addition will cause
overflow since the result is out of range of the type ``Integer``.
In this case, execution will raise ``Constraint_Error`` if checks are
enabled.

A trickier situation arises in cases like the following:

  .. code-block:: ada

     A, C : Integer;
     ...
     A := (A + 1) + C;

where ``A`` is ``Integer'Last`` and ``C`` is ``-1``.
Here, the final result of the expression on the right hand side is
``Integer'Last`` which is in range, but the question arises whether the
intermediate addition of ``(A + 1)`` raises an overflow error.

The (perhaps surprising) answer is that the Ada language
definition does not answer this question. Instead, it leaves
it up to the implementation to do one of two things if overflow
checks are enabled.

* raise an exception (``Constraint_Error``), or

* yield the correct mathematical result which is then used in
  subsequent operations.

If the compiler chooses the first approach, the execution of this
example will indeed raise ``Constraint_Error`` if overflow checking is
enabled or result in erroneous execution if overflow checks are suppressed.

But if the compiler
chooses the second approach, it can perform both additions yielding
the correct mathematical result, which is in range, so no exception
is raised and the right result is obtained, regardless of whether
overflow checks are suppressed.

Note that in the first example, an
exception will be raised in either case, since if the compiler
gives the correct mathematical result for the addition, it will
be out of range of the target type of the assignment and thus
fails the range check.

This lack of specified behavior in the handling of overflow for
intermediate results is a source of non-portability and can thus
be problematic when you port programs. Most typically, this arises
in a situation where the original compiler did not raise an exception
and you move the application to a compiler where the check is
performed on the intermediate result and an unexpected exception is
raised.

Furthermore, when using Ada 2012's preconditions and other
assertion forms, another issue arises. Consider:

  .. code-block:: ada

       procedure P (A, B : Integer) with
         Pre => A + B <= Integer'Last;

We often want to regard arithmetic in a context such as this from a
purely mathematical point of view. So, for example, if the two actual
parameters for a call to ``P`` are both ``Integer'Last`` then the
precondition should be evaluated as ``False``. If we're executing in a
mode with run-time checks enabled for preconditions, then we would
like this precondition to fail, rather than raising an exception
because of the intermediate overflow.

However, the language definition leaves the specification of
whether the above condition fails (raising ``Assert_Error``) or
causes an intermediate overflow (raising ``Constraint_Error``)
up to the implementation.

The situation is worse in a case such as the following:

  .. code-block:: ada

       procedure Q (A, B, C : Integer) with
         Pre => A + B + C <= Integer'Last;

Consider the call

  .. code-block:: ada

       Q (A => Integer'Last, B => 1, C => -1);

From a mathematical point of view the precondition
is ``True``, but at run time we may (but are not guaranteed to) get an
exception raised because of the intermediate overflow (and we really
would prefer this precondition to be considered ``True`` at run time).


.. _Management_of_Overflows_in_GNAT:

Management of Overflows in GNAT
-------------------------------

To deal with the portability issue and with the problem of
mathematical versus run-time interpretation of the expressions in
assertions, GNAT provides comprehensive control over the handling
of intermediate overflows. It can operate in three modes, and
in addition, permits separate selection of operating modes for
the expressions within assertions (here the term 'assertions'
is used in the technical sense, which includes preconditions and so forth)
and for expressions appearing outside assertions.

The three modes are:

* *Use base type for intermediate operations* (``STRICT``)

  In this mode, all intermediate results for predefined arithmetic
  operators are computed using the base type, and the result must
  be in range of the base type. If this is not the
  case, then either an exception is raised (if overflow checks are
  enabled) or the execution is erroneous (if overflow checks are suppressed).
  This is the normal default mode.

* *Most intermediate overflows avoided* (``MINIMIZED``)

  In this mode, the compiler attempts to avoid intermediate overflows by
  using a larger integer type, typically ``Long_Long_Integer``,
  as the type in which arithmetic is
  performed for predefined arithmetic operators. This may be slightly more
  expensive at
  run time (compared to suppressing intermediate overflow checks), though
  the cost is negligible on modern 64-bit machines. For the examples given
  earlier, no intermediate overflows would have resulted in exceptions,
  since the intermediate results are all in the range of
  ``Long_Long_Integer`` (typically 64-bits on nearly all implementations
  of GNAT). In addition, if checks are enabled, this reduces the number of
  checks that must be made, so this choice may actually result in an
  improvement in space and time behavior.

  However, there are cases where ``Long_Long_Integer`` is not large
  enough. Consider the following example:

    .. code-block:: ada

           procedure R (A, B, C, D : Integer) with
             Pre => (A**2 * B**2) / (C**2 * D**2) <= 10;

  where ``A`` = ``B`` = ``C`` = ``D`` = ``Integer'Last``.
  Now the intermediate results are
  out of the range of ``Long_Long_Integer`` even though the final result
  is in range and the precondition is ``True`` from a mathematical point
  of view. In such a case, operating in this mode, an overflow occurs
  for the intermediate computation (which is why this mode
  says *most* intermediate overflows are avoided). In this case,
  an exception is raised if overflow checks are enabled, and the
  execution is erroneous if overflow checks are suppressed.

* *All intermediate overflows avoided* (``ELIMINATED``)

  In this mode, the compiler  avoids all intermediate overflows
  by using arbitrary precision arithmetic as required. In this
  mode, the above example with ``A**2 * B**2`` would
  not cause intermediate overflow, because the intermediate result
  would be evaluated using sufficient precision, and the result
  of evaluating the precondition would be ``True``.

  This mode has the advantage of avoiding any intermediate
  overflows, but at the expense of significant run-time overhead,
  including the use of a library (included automatically in this
  mode) for multiple-precision arithmetic.

  This mode provides cleaner semantics for assertions, since now
  the run-time behavior emulates true arithmetic behavior for the
  predefined arithmetic operators, meaning that there is never a
  conflict between the mathematical view of the assertion and its
  run-time behavior.

  Note that in this mode, the behavior is unaffected by whether or
  not overflow checks are suppressed, since overflow does not occur.
  Gigantic intermediate expressions can still raise
  ``Storage_Error`` as a result of attempting to compute the
  results of such expressions (e.g. ``Integer'Last ** Integer'Last``)
  but overflow is impossible.


Note that these modes apply only to the evaluation of predefined
arithmetic, membership, and comparison operators for signed integer
arithmetic.

For fixed-point arithmetic, you suppress checks. But if checks
are enabled,
fixed-point values are always checked for overflow against the
base type for intermediate expressions (i.e., such checks always
operate in the equivalent of ``STRICT`` mode).

For floating-point, on nearly all architectures, ``Machine_Overflows``
is ``False``, and IEEE infinities are generated, so overflow exceptions
are never raised. If you want to avoid infinities and check that
final results of expressions are in range, you can declare a
constrained floating-point type and range checks are carried
out in the normal manner (with infinite values always failing all
range checks).


.. _Specifying_the_Desired_Mode:

Specifying the Desired Mode
---------------------------

.. index:: pragma Overflow_Mode

You can specify
the desired mode of for handling intermediate overflow using
either the ``Overflow_Mode`` pragma or an equivalent compiler switch.
The pragma has the form:

  .. code-block:: ada

      pragma Overflow_Mode ([General =>] MODE [, [Assertions =>] MODE]);

where ``MODE`` is one of

* ``STRICT``:  intermediate overflows checked (using base type)
* ``MINIMIZED``: minimize intermediate overflows
* ``ELIMINATED``: eliminate intermediate overflows

The case is ignored, so ``MINIMIZED``, ``Minimized`` and
``minimized`` all have the same effect.

If you only specify the ``General`` parameter, the given ``MODE`` applies
to expressions both within and outside assertions. If you specify both arguments,
the value of ``General`` applies to expressions outside assertions,
and ``Assertions`` applies to expressions within assertions. For example:

  .. code-block:: ada

     pragma Overflow_Mode
       (General => Minimized, Assertions => Eliminated);

specifies that expressions outside assertions be evaluated
in 'minimize intermediate overflows' mode and expressions within
assertions be evaluated in 'eliminate intermediate overflows' mode.
This is often a reasonable choice, avoiding excessive overhead
outside assertions, but assuring a high degree of portability
when importing code from another compiler while incurring
the extra overhead for assertion expressions to ensure that
the behavior at run time matches the expected mathematical
behavior.

The ``Overflow_Mode`` pragma has the same scoping and placement
rules as pragma ``Suppress``, so you can use it either as a
configuration pragma, specifying a default for the whole
program, or in a declarative scope, where it applies to the
remaining declarations and statements in that scope.

Note that pragma ``Overflow_Mode`` does not affect whether
overflow checks are enabled or suppressed. It only controls the
method used to compute intermediate values. To control whether
overflow checking is enabled or suppressed, use pragma ``Suppress``
or ``Unsuppress`` in the usual manner.


.. index:: -gnato? (gcc)
.. index:: -gnato?? (gcc)

Additionally, you can use the compiler switch :switch:`-gnato?` or
:switch:`-gnato??` to control the checking mode default (which you can
subsequently override using the above pragmas).

Here ``?`` is one of the digits ``1`` through ``3``:

  ====== ======================================================
  ``1``  use base type for intermediate operations (``STRICT``)
  ``2``  minimize intermediate overflows (``MINIMIZED``)
  ``3``  eliminate intermediate overflows (``ELIMINATED``)
  ====== ======================================================

As with the pragma, if only one digit appears, it applies to all
cases; if two digits are given, the first applies to expressions outside
assertions and the second within assertions. Thus the equivalent
of the example pragma above would be
:switch:`-gnato23`.

If you don't provide any digits following the :switch:`-gnato`, it's
equivalent to :switch:`-gnato11`, causing all intermediate operations
to be computed using the base type (``STRICT`` mode).


.. _Default_Settings:

Default Settings
----------------

The default mode for overflow checks is

  ::

      General => Strict

which causes all computations both inside and outside assertions to use the
base type, and is equivalent to :switch:`-gnato` (with no digits following).

The pragma ``Suppress (Overflow_Check)`` disables overflow
checking but has no effect on the method used for computing
intermediate results.
The pragma ``Unsuppress (Overflow_Check)`` enables overflow
checking but has no effect on the method used for computing
intermediate results.


.. _Implementation_Notes:

Implementation Notes
--------------------

In practice, on typical 64-bit machines, the ``MINIMIZED`` mode is
reasonably efficient and you can generally use it. It also helps
to ensure compatibility with code imported from other
compilers to GNAT.

Setting all intermediate overflows checking (``STRICT`` mode)
makes sense if you want to
make sure your code is compatible with any other
Ada implementations. You may find this useful in ensuring portability
for code that is to be exported to some other compiler than GNAT.

The Ada standard allows the reassociation of expressions at
the same precedence level if no parentheses are present. For
example, ``A+B+C`` parses as though it were ``(A+B)+C``, but
the compiler can reinterpret this as ``A+(B+C)``, possibly
introducing or eliminating an overflow exception. The GNAT
compiler never takes advantage of this freedom, and the
expression ``A+B+C`` will be evaluated as ``(A+B)+C``.
If you need the other order, you can write the parentheses
explicitly ``A+(B+C)`` and GNAT will respect this order.

The use of ``ELIMINATED`` mode will cause the compiler to
automatically include an appropriate arbitrary precision
integer arithmetic package. The compiler will make calls
to this package, though only in cases where it cannot be
sure that ``Long_Long_Integer`` is sufficient to guard against
intermediate overflows. This package does not use dynamic
allocation, but it does use the secondary stack, so an
appropriate secondary stack package must be present (this
is always true for standard full Ada, but may require
specific steps for restricted run times such as ZFP).

Although ``ELIMINATED`` mode causes expressions to use arbitrary
precision arithmetic, avoiding overflow, the final result
must be in an appropriate range. This is true even if the
final result is of type ``[Long_[Long_]]Integer'Base``, which
still has the same bounds as its associated constrained
type at run-time.

Currently, the ``ELIMINATED`` mode is only available on target
platforms for which ``Long_Long_Integer`` is at least 64-bits (nearly all GNAT
platforms).



.. _Performing_Dimensionality_Analysis_in_GNAT:

Performing Dimensionality Analysis in GNAT
==========================================

.. index:: Dimensionality analysis

The GNAT compiler supports dimensionality checking. You can
specify physical units for objects and the compiler verifies that uses
of these objects are compatible with their dimension, in a fashion that is
familiar to engineering practice. The dimensions of algebraic expressions
(including powers with static exponents) are computed from their constituents.

.. index:: Dimension_System aspect
.. index:: Dimension aspect

This feature depends on Ada 2012 aspect specifications and is available for
versions 7.0.1 and later of GNAT.
The GNAT-specific aspect ``Dimension_System``
allows you to define a system of units; the aspect ``Dimension``
allows you to declare dimensioned quantities within a given system.
(These aspects are described in the *Implementation Defined Aspects*
chapter of the :title:`GNAT Reference Manual`).

The major advantage of this model is that it does not require the declaration of
multiple operators for all possible combinations of types: you is only need
to use the proper subtypes in object declarations.

.. index:: System.Dim.Mks package (GNAT library)
.. index:: MKS_Type type

The simplest way to impose dimensionality checking on a computation is to make
use of one of the instantiations of the package ``System.Dim.Generic_Mks``, which
is part of the GNAT library. This generic package defines a floating-point
type ``MKS_Type``, for which a sequence of dimension names are specified,
together with their conventional abbreviations.  You should read the following
together with the full specification of the package, in file
:file:`s-digemk.ads`.

  .. index:: s-digemk.ads file

  .. code-block:: ada

     type Mks_Type is new Float_Type
       with
        Dimension_System => (
          (Unit_Name => Meter,    Unit_Symbol => 'm',   Dim_Symbol => 'L'),
          (Unit_Name => Kilogram, Unit_Symbol => "kg",  Dim_Symbol => 'M'),
          (Unit_Name => Second,   Unit_Symbol => 's',   Dim_Symbol => 'T'),
          (Unit_Name => Ampere,   Unit_Symbol => 'A',   Dim_Symbol => 'I'),
          (Unit_Name => Kelvin,   Unit_Symbol => 'K',   Dim_Symbol => "Theta"),
          (Unit_Name => Mole,     Unit_Symbol => "mol", Dim_Symbol => 'N'),
          (Unit_Name => Candela,  Unit_Symbol => "cd",  Dim_Symbol => 'J'));

The package then defines a series of subtypes that correspond to these
conventional units. For example:

  .. code-block:: ada

     subtype Length is Mks_Type
       with
        Dimension => (Symbol => 'm', Meter  => 1, others => 0);

and similarly for ``Mass``, ``Time``, ``Electric_Current``,
``Thermodynamic_Temperature``, ``Amount_Of_Substance``, and
``Luminous_Intensity`` (the standard set of units of the SI system).

The package also defines conventional names for values of each unit, for
example:

  .. code-block:: ada

     m   : constant Length           := 1.0;
     kg  : constant Mass             := 1.0;
     s   : constant Time             := 1.0;
     A   : constant Electric_Current := 1.0;

as well as useful multiples of these units:

  .. code-block:: ada

     cm  : constant Length := 1.0E-02;
     g   : constant Mass   := 1.0E-03;
     min : constant Time   := 60.0;
     day : constant Time   := 60.0 * 24.0 * min;
    ...

There are three instantiations of ``System.Dim.Generic_Mks`` defined in the
GNAT library:

* ``System.Dim.Float_Mks`` based on ``Float`` defined in :file:`s-diflmk.ads`.
* ``System.Dim.Long_Mks`` based on ``Long_Float`` defined in :file:`s-dilomk.ads`.
* ``System.Dim.Mks`` based on ``Long_Long_Float`` defined in :file:`s-dimmks.ads`.

Using one of these packages, you can then define a derived unit by providing
the aspect that specifies its dimensions within the MKS system as well as the
string to be used for output of a value of that unit:

  .. code-block:: ada

     subtype Acceleration is Mks_Type
       with Dimension => ("m/sec^2",
                          Meter => 1,
                          Second => -2,
                          others => 0);

Here's a complete example:

  .. code-block:: ada

     with System.Dim.MKS; use System.Dim.Mks;
     with System.Dim.Mks_IO; use System.Dim.Mks_IO;
     with Text_IO; use Text_IO;
     procedure Free_Fall is
       subtype Acceleration is Mks_Type
         with Dimension => ("m/sec^2", 1, 0, -2, others => 0);
       G : constant acceleration := 9.81 * m / (s ** 2);
       T : Time := 10.0*s;
       Distance : Length;

     begin
       Put ("Gravitational constant: ");
       Put (G, Aft => 2, Exp => 0); Put_Line ("");
       Distance := 0.5 * G * T ** 2;
       Put ("distance travelled in 10 seconds of free fall ");
       Put (Distance, Aft => 2, Exp => 0);
       Put_Line ("");
     end Free_Fall;

Execution of this program yields:

  ::

     Gravitational constant:  9.81 m/sec^2
     distance travelled in 10 seconds of free fall 490.50 m

However, incorrect assignments such as:

  .. code-block:: ada

       Distance := 5.0;
       Distance := 5.0 * kg;

are rejected with the following diagnoses:

 ::

     Distance := 5.0;
        >>> dimensions mismatch in assignment
        >>> left-hand side has dimension [L]
        >>> right-hand side is dimensionless

     Distance := 5.0 * kg:
        >>> dimensions mismatch in assignment
        >>> left-hand side has dimension [L]
        >>> right-hand side has dimension [M]

The dimensions of an expression are properly displayed even if there is
no explicit subtype for it. If we add to the program:

  .. code-block:: ada

        Put ("Final velocity: ");
        Put (G * T, Aft =>2, Exp =>0);
        Put_Line ("");

the output includes:

  ::

       Final velocity: 98.10 m.s**(-1)


  .. index:: Dimensionable type
  .. index:: Dimensioned subtype

The type ``Mks_Type`` is said to be a *dimensionable type* since it has a
``Dimension_System`` aspect, and the subtypes ``Length``, ``Mass``, etc.,
are said to be *dimensioned subtypes* since each one has a ``Dimension``
aspect.

  .. index:: Dimension Vector (for a dimensioned subtype)
  .. index:: Dimension aspect
  .. index:: Dimension_System aspect

The ``Dimension`` aspect of a dimensioned subtype ``S`` defines a mapping
from the base type's Unit_Names to integer (or, more generally, rational)
values. This mapping is the *dimension vector* (also referred to as the
*dimensionality*) for that subtype, denoted by ``DV(S)``, and thus for each
object of that subtype. Intuitively, the value specified for each
``Unit_Name`` is the exponent associated with that unit; a zero value
means that the unit is not used. For example:

   .. code-block:: ada

      declare
         Acc : Acceleration;
         ...
      begin
         ...
      end;

Here ``DV(Acc)`` = ``DV(Acceleration)`` =
``(Meter=>1, Kilogram=>0, Second=>-2, Ampere=>0, Kelvin=>0, Mole=>0, Candela=>0)``.
Symbolically, we can express this as ``Meter / Second**2``.

The dimension vector of an arithmetic expression is synthesized from the
dimension vectors of its components, with compile-time dimensionality checks
that help prevent mismatches such as using an ``Acceleration`` where a
``Length`` is required.

The dimension vector of the result of an arithmetic expression *expr*, or
:samp:`DV({expr})`, is defined as follows, assuming conventional
mathematical definitions for the vector operations that are used:

* If *expr* is of the type *universal_real*, or is not of a dimensioned subtype,
  then *expr* is dimensionless; :samp:`DV({expr})` is the empty vector.

* :samp:`DV({op expr})`, where *op* is a unary operator, is :samp:`DV({expr})`

* :samp:`DV({expr1 op expr2})`, where *op* is "+" or "-", is :samp:`DV({expr1})`
  provided that :samp:`DV({expr1})` = :samp:`DV({expr2})`.
  If this condition is not met then the construct is illegal.

* :samp:`DV({expr1} * {expr2})` is :samp:`DV({expr1})` + :samp:`DV({expr2})`,
  and :samp:`DV({expr1} / {expr2})` = :samp:`DV({expr1})` - :samp:`DV({expr2})`.
  In this context if one of the *expr*\ s is dimensionless then its empty
  dimension vector is treated as ``(others => 0)``.

* :samp:`DV({expr} ** {power})` is *power* * :samp:`DV({expr})`,
  provided that *power* is a static rational value. If this condition is not
  met then the construct is illegal.

Note that, by the above rules, it is illegal to use binary "+" or "-" to
combine a dimensioned and dimensionless value.  Thus an expression such as
``acc-10.0`` is illegal, where ``acc`` is an object of subtype
``Acceleration``.

The dimensionality checks for relationals use the same rules as
for "+" and "-" except when comparing to a literal; thus

  .. code-block:: ada

        acc > len

is equivalent to

  .. code-block:: ada

       acc-len > 0.0

and is thus illegal, but

  .. code-block:: ada

        acc > 10.0

is accepted with a warning. Analogously, a conditional expression requires the
same dimension vector for each branch (with no exception for literals).

The dimension vector of a type conversion :samp:`T({expr})` is defined
as follows, based on the nature of ``T``:

* If ``T`` is a dimensioned subtype, then :samp:`DV(T({expr}))` is ``DV(T)``
  provided that either *expr* is dimensionless or
  :samp:`DV(T)` = :samp:`DV({expr})`. The conversion is illegal
  if *expr* is dimensioned and :samp:`DV({expr})` /= ``DV(T)``.
  Note that vector equality does not require that the corresponding
  Unit_Names be the same.

  As a consequence of the above rule, you can convert between
  different dimension systems that follow the same international
  system of units, with the seven physical components given in the
  standard order (length, mass, time, etc.). Thus, you can convert a
  length in meters to a length in inches (with a suitable conversion
  factor) but not, for example, to a mass in pounds.

* If ``T`` is the base type for *expr* (and the dimensionless root type of
  the dimension system), then :samp:`DV(T({expr}))` is ``DV(expr)``.
  Thus, if *expr* is of a dimensioned subtype of ``T``, the conversion may
  be regarded as a "view conversion" that preserves dimensionality.

  This rule means you can write generic code that can be instantiated
  with compatible dimensioned subtypes.  You include in the generic unit
  conversions that will consequently be present in instantiations, but
  conversions to the base type will preserve dimensionality and make it
  possible to write generic code that is correct with respect to
  dimensionality.

* Otherwise (i.e., ``T`` is neither a dimensioned subtype nor a dimensionable
  base type), :samp:`DV(T({expr}))` is the empty vector. Thus, a dimensioned
  value can be explicitly converted to a non-dimensioned subtype, which
  of course then escapes dimensionality analysis.

The dimension vector for a type qualification :samp:`T'({expr})` is the same
as for the type conversion :samp:`T({expr})`.

An assignment statement

   .. code-block:: ada

         Source := Target;

requires ``DV(Source)`` = ``DV(Target)`` and analogously for parameter
passing (the dimension vector for the actual parameter must be equal to the
dimension vector for the formal parameter).

When using dimensioned types with elementary functions, you need not
instantiate the ``Ada.Numerics.Generic_Elementary_Functions`` package using
the ``Mks_Type`` nor for any of the derived subtypes such as ``Distance``.
For functions such as ``Sqrt``, the dimensional analysis will fail when using
the subtypes because both the parameter and return are of the same type.

An example instantiation

  .. code-block:: ada

        package Mks_Numerics is new
           Ada.Numerics.Generic_Elementary_Functions (System.Dim.Mks.Mks_Type);

.. _Stack_Related_Facilities:

Stack Related Facilities
========================

This section describes some useful tools associated with stack
checking and analysis. In
particular, it deals with dynamic and static stack usage measurements.

.. _Stack_Overflow_Checking:

Stack Overflow Checking
-----------------------

.. index:: Stack Overflow Checking

.. index:: -fstack-check (gcc)

For most operating systems, ``gcc`` does not perform stack overflow
checking by default. This means that if the main environment task or
some other task exceeds the available stack space, unpredictable
behavior will occur. Most native systems offer some level of protection by
adding a guard page at the end of each task stack. This mechanism is usually
not enough for dealing properly with stack overflow situations because
a large local variable could "jump" above the guard page.
Furthermore, when the
guard page is hit, there may not be any space left on the stack for executing
the exception propagation code. Enabling stack checking avoids
such situations.

To activate stack checking, compile all units with the ``gcc`` switch
:switch:`-fstack-check`. For example:

  ::

     $ gcc -c -fstack-check package1.adb

Units compiled with this option will generate extra instructions to check
that any use of the stack (for procedure calls or for declaring local
variables in declare blocks) does not exceed the available stack space.
If the space is exceeded, a ``Storage_Error`` exception is raised.

For declared tasks, the default stack size is defined by the GNAT runtime,
whose size may be modified at bind time through the ``-d`` bind switch
(:ref:`Switches_for_gnatbind`). You can set task specific stack sizes using the
``Storage_Size`` pragma.

For the environment task, the stack size is determined by the operating system.
Consequently, to modify the size of the environment task please refer to your
operating system documentation.

When using the LLVM back end, this switch doesn't perform full stack overflow
checking, but just checks for very large local dynamic allocations.

.. _Static_Stack_Usage_Analysis:

Static Stack Usage Analysis
---------------------------

.. index:: Static Stack Usage Analysis

.. index:: -fstack-usage

A unit compiled with the :switch:`-fstack-usage` switch generate an extra file
that specifies
the maximum amount of stack used on a per-function basis.
The file has the same
basename as the target object file with a :file:`.su` extension.
Each line of this file is made up of three fields:

* The name of the function.
* A number of bytes.
* One or more qualifiers: ``static``, ``dynamic``, ``bounded``.

The second field corresponds to the size of the known part of the function
frame.

The qualifier ``static`` means that the function frame size
is purely static.
It usually means that all local variables have a static size.
In this case, the second field is a reliable measure of the function stack
utilization.

The qualifier ``dynamic`` means that the function frame size is not static.
It happens mainly when some local variables have a dynamic size. When this
qualifier appears alone, the second field is not a reliable measure
of the function stack analysis. When it is qualified with  ``bounded``, it
means that the second field is a reliable maximum of the function stack
utilization.

Compilation of a unit with the :switch:`-Wstack-usage` switch will
issue a warning for each subprogram whose stack usage might be larger
than the specified amount of bytes.  The wording of that warning is
consistent with that in the file documented above.

This is not supported by the LLVM back end.


.. _Dynamic_Stack_Usage_Analysis:

Dynamic Stack Usage Analysis
----------------------------

You can measure the maximum amount of stack used by a task by
adding a switch to ``gnatbind``, as:

  ::

      $ gnatbind -u0 file

With this option, at each task termination, its stack usage is output on
:file:`stderr`.
Note that this switch is not compatible with tools like
Valgrind and DrMemory; they will report errors.

It is not always convenient to output the stack usage when the program
is still running. Hence, you can delay this output until the
termination of the number of tasks specified as the argument of the
:switch:`-u` switch. For example:

  ::

     $ gnatbind -u100 file

buffers the stack usage information of the first 100 tasks to terminate and
outputs it when the program terminates. Results are displayed in four
columns:

  ::

     Index | Task Name | Stack Size | Stack Usage

where:

* *Index* is a number associated with each task.

* *Task Name* is the name of the task analyzed.

* *Stack Size* is the maximum size for the stack.

* *Stack Usage* is the measure done by the stack analyzer.
  In order to prevent overflow, the stack
  is not entirely analyzed, and it's not possible to know exactly how
  much has actually been used.

By default, ``gnatbind`` does not process the environment task stack,
the stack that contains the main unit. To enable processing of the
environment task stack, set the environment variable GNAT_STACK_LIMIT
to the maximum size of the environment task stack. This amount is
given in kilobytes. For example:

  ::

     $ set GNAT_STACK_LIMIT 1600

would specify to the analyzer that the environment task stack has a limit
of 1.6 megabytes. Any stack usage beyond this will be ignored by the analysis.

This is not supported by the LLVM back end.

The package ``GNAT.Task_Stack_Usage`` provides facilities to get
stack-usage reports at run time. See its body for the details.



.. _Memory_Management_Issues:

Memory Management Issues
========================

This section describes some useful memory pools provided in the GNAT library,
and in particular the GNAT Debug Pool facility, which can be used to detect
incorrect uses of access values (including 'dangling references').

.. only:: PRO or GPL

  It also describes the ``gnatmem`` tool, which can be used to track down
  "memory leaks".

.. _Some_Useful_Memory_Pools:

Some Useful Memory Pools
------------------------

.. index:: Memory Pool
.. index:: storage, pool

The ``System.Pool_Global`` package provides the ``Unbounded_No_Reclaim_Pool``
storage pool. Allocations use the standard system call ``malloc`` while
deallocations use the standard system call ``free``. No reclamation is
performed when the pool goes out of scope. For performance reasons, the
standard default Ada allocators/deallocators do not use any explicit storage
pools but if they did, they could use this storage pool without any change in
behavior. That is why this storage pool is used  when the user
makes the default implicit allocator explicit as in this example:

  .. code-block:: ada

       type T1 is access Something;
        -- no Storage pool is defined for T2

       type T2 is access Something_Else;
       for T2'Storage_Pool use T1'Storage_Pool;
       -- the above is equivalent to
       for T2'Storage_Pool use System.Pool_Global.Global_Pool_Object;

The ``System.Pool_Local`` package provides the ``Unbounded_Reclaim_Pool`` storage
pool. Its allocation strategy is similar to ``Pool_Local``
except that the all
storage allocated with this pool is reclaimed when the pool object goes out of
scope. This pool provides a explicit mechanism similar to the implicit one
provided by several Ada 83 compilers for allocations performed through a local
access type and whose purpose was to reclaim memory when exiting the
scope of a given local access. As an example, the following program does not
leak memory even though it does not perform explicit deallocation:

  .. code-block:: ada

     with System.Pool_Local;
     procedure Pooloc1 is
        procedure Internal is
           type A is access Integer;
           X : System.Pool_Local.Unbounded_Reclaim_Pool;
           for A'Storage_Pool use X;
           v : A;
        begin
           for I in 1 .. 50 loop
              v := new Integer;
           end loop;
        end Internal;
     begin
        for I in 1 .. 100 loop
           Internal;
        end loop;
     end Pooloc1;

The ``System.Pool_Size`` package implements the ``Stack_Bounded_Pool`` used when
``Storage_Size`` is specified for an access type.
The whole storage for the pool is
allocated at once, usually on the stack at the point where the access type is
elaborated. It is automatically reclaimed when exiting the scope where the
access type is defined. This package is not intended to be used directly by the
user; it is implicitly used for each declaration with a specified
``Storage_Size``:

  .. code-block:: ada

     type T1 is access Something;
     for T1'Storage_Size use 10_000;


.. _The_GNAT_Debug_Pool_Facility:

The GNAT Debug Pool Facility
----------------------------

.. index:: Debug Pool
.. index:: storage, pool, memory corruption

Using unchecked deallocation and unchecked conversion can easily
lead to incorrect memory references. The problems generated by such
references are usually difficult to find because the symptoms can be
very remote from the origin of the problem. In such cases, it is
very helpful to detect the problem as early as possible. This is the
purpose of the Storage Pool provided by ``GNAT.Debug_Pools``.

In order to use the GNAT specific debugging pool, you must
associate a debug pool object with each of the access types that may be
related to suspected memory problems. See Ada Reference Manual 13.11.

  .. code-block:: ada

     type Ptr is access Some_Type;
     Pool : GNAT.Debug_Pools.Debug_Pool;
     for Ptr'Storage_Pool use Pool;

``GNAT.Debug_Pools`` is derived from a GNAT-specific kind of
pool: the ``Checked_Pool``. Such pools, like standard Ada storage pools,
allow you to redefine allocation and deallocation strategies. They
also provide a checkpoint for each dereference through the use of
the primitive operation ``Dereference`` which is implicitly called at
each dereference of an access value.

Once you have associated an access type with a debug pool, operations on
values of the type may raise four distinct exceptions,
which correspond to four potential kinds of memory corruption:

* ``GNAT.Debug_Pools.Accessing_Not_Allocated_Storage``
* ``GNAT.Debug_Pools.Accessing_Deallocated_Storage``
* ``GNAT.Debug_Pools.Freeing_Not_Allocated_Storage``
* ``GNAT.Debug_Pools.Freeing_Deallocated_Storage``

For types associated with a Debug_Pool, dynamic allocation is performed using
the standard GNAT allocation routine. References to all allocated chunks of
memory are kept in an internal dictionary. Several deallocation strategies are
provided, allowing you to choose to release the memory to the system,
keep it allocated for further invalid access checks, or fill it with an easily
recognizable pattern for debug sessions. The memory pattern is the old IBM
hexadecimal convention: ``16#DEADBEEF#``.

See the documentation in the file :file:`g-debpoo.ads` for more
information on the various strategies.

Upon each dereference, a check is made that the access value denotes a
properly allocated memory location. Here's a complete example of use of
``Debug_Pools``, which includes typical instances of  memory corruption:

  .. code-block:: ada

      with GNAT.IO; use GNAT.IO;
      with Ada.Unchecked_Deallocation;
      with Ada.Unchecked_Conversion;
      with GNAT.Debug_Pools;
      with System.Storage_Elements;
      with Ada.Exceptions; use Ada.Exceptions;
      procedure Debug_Pool_Test is

         type T is access Integer;
         type U is access all T;

         P : GNAT.Debug_Pools.Debug_Pool;
         for T'Storage_Pool use P;

         procedure Free is new Ada.Unchecked_Deallocation (Integer, T);
         function UC is new Ada.Unchecked_Conversion (U, T);
         A, B : aliased T;

         procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line);

      begin
         Info (P);
         A := new Integer;
         B := new Integer;
         B := A;
         Info (P);
         Free (A);
         begin
            Put_Line (Integer'Image(B.all));
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         begin
            Free (B);
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         B := UC(A'Access);
         begin
            Put_Line (Integer'Image(B.all));
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         begin
            Free (B);
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         Info (P);
      end Debug_Pool_Test;

The debug pool mechanism provides the following precise diagnostics on the
execution of this erroneous program:

  ::

     Debug Pool info:
       Total allocated bytes :  0
       Total deallocated bytes :  0
       Current Water Mark:  0
       High Water Mark:  0

     Debug Pool info:
       Total allocated bytes :  8
       Total deallocated bytes :  0
       Current Water Mark:  8
       High Water Mark:  8

     raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE
     Debug Pool info:
       Total allocated bytes :  8
       Total deallocated bytes :  4
       Current Water Mark:  4
       High Water Mark:  8

.. only:: PRO or GPL

  .. _The_gnatmem_Tool:

  The ``gnatmem`` Tool
  --------------------

  .. index:: ! gnatmem

  The ``gnatmem`` utility monitors dynamic allocation and
  deallocation activity in a program, and displays information about
  incorrect deallocations and possible sources of memory leaks.
  It is designed to work for fixed-position executables that use
  a static runtime library and, in this context, provides three
  types of information:

  * General information concerning memory management, such as the total
    number of allocations and deallocations, the amount of allocated
    memory and the high water mark, i.e., the largest amount of allocated
    memory in the course of program execution.

  * Backtraces for all incorrect deallocations, which are deallocations
    that do not correspond to a valid allocation.

  * Information on each allocation that is potentially the origin of a memory
    leak.

  .. _Running_gnatmem:

  Running ``gnatmem``
  ^^^^^^^^^^^^^^^^^^^

  ``gnatmem`` makes use of the output created by the special version of
  allocation and deallocation routines that record call information. This allows
  it to obtain accurate dynamic memory usage history at a minimal cost to the
  execution speed. Note however, that ``gnatmem`` is only supported on
  GNU/Linux and Windows.

  The ``gnatmem`` command has the form

    ::

       $ gnatmem [ switches ] [ DEPTH ] user_program

  You must link your program with the instrumented version of the
  allocation and deallocation routines. You do this by linking with the
  :file:`libgmem.a` library. For correct symbolic backtrace information,
  you should also compile your program with debugging options
  (see :ref:`Switches_for_gcc`) and be linked at a fixed position (with
  :switch:`-no-pie`). For example to build :file:`my_program` with
  ``gnatmake``:

    ::

       $ gnatmake my_program -g -largs -lgmem -no-pie

  Because library :file:`libgmem.a` contains an alternate body for package
  ``System.Memory``, you should not compile and link :file:`s-memory.adb`
  when you link an executable with library :file:`libgmem.a`. In that case,
  we don't recommended specifying switch :switch:`-a` to ``gnatmake``.

  When :file:`my_program` is executed, the file :file:`gmem.out` is produced.
  This file contains information about all allocations and deallocations
  performed by the program. It is produced by the instrumented allocations and
  deallocations routines and will be used by ``gnatmem``.

  To produce symbolic backtrace information for allocations and
  deallocations performed by the GNAT run-time library, you need to use a
  version of that library that has been compiled with the :switch:`-g` switch
  (see :ref:`Rebuilding_the_GNAT_Run-Time_Library`).

  You must supply ``gnatmem``  with the :file:`gmem.out` file and the executable to
  examine. If the location of :file:`gmem.out` file was not explicitly supplied by
  :switch:`-i` switch, ``gnatmem`` assumes that this file can be found in the
  current directory. For example, after you have executed :file:`my_program`,
  :file:`gmem.out` can be analyzed by ``gnatmem`` using the command:

    ::

       $ gnatmem my_program

  This will produce the output with the following format:

    ::

        $ gnatmem my_program

        Global information
        ------------------
           Total number of allocations        :  45
           Total number of deallocations      :   6
           Final Water Mark (non freed mem)   :  11.29 Kilobytes
           High Water Mark                    :  11.40 Kilobytes

        .
        .
        .
        Allocation Root # 2
        -------------------
         Number of non freed allocations    :  11
         Final Water Mark (non freed mem)   :   1.16 Kilobytes
         High Water Mark                    :   1.27 Kilobytes
         Backtrace                          :
           my_program.adb:23 my_program.alloc
        .
        .
        .

  The first block of output gives general information. In this case, the
  Ada construct ``new`` was executed 45 times and only 6 calls to an
  ``Unchecked_Deallocation`` routine occurred.

  Subsequent paragraphs display information on all allocation roots.
  An *allocation root* is a specific point in the execution of the program
  that generates some dynamic allocation, such as a ``new``
  construct. This root is represented by an execution backtrace (or subprogram
  call stack). By default, the backtrace depth for allocations roots is 1, so
  that a root corresponds exactly to a source location. The backtrace can
  be made deeper, to make the root more specific.

  .. _Switches_for_gnatmem:

  Switches for ``gnatmem``
  ^^^^^^^^^^^^^^^^^^^^^^^^

  ``gnatmem`` recognizes the following switches:

  .. index:: -q (gnatmem)

  :switch:`-q`
    Quiet. Gives the minimum output needed to identify the origin of the
    memory leaks. Omits statistical information.


  .. index:: DEPTH switch (gnatmem)

  :switch:`{DEPTH}`
    ``DEPTH`` is an integer literal (usually between 1 and 10) which controls
    the depth of the backtraces defining allocation root. The default value for
    DEPTH is 1. The deeper the backtrace, the more precise the localization of
    the root. Note that the total number of roots can depend on this
    parameter; in other words there may be more roots when the requested
    backtrace depth is higher. You must specify this parameter *before* the
    name of the executable to be analyzed, to avoid ambiguity.


  .. index:: -b (gnatmem)

  :switch:`-b {N}`
    This switch has the same effect as just a depth parameter ``N``.


  .. index:: -i (gnatmem)

  :switch:`-i {file}`
    Do the ``gnatmem`` processing starting from :file:`file`, rather than
    :file:`gmem.out` in the current directory.


  .. index:: -m (gnatmem)

  :switch:`-m {n}`
    This switch causes ``gnatmem`` to mask the allocation roots that have less
    than ``n`` leaks.  The default value is 1. Specifying the value of 0 will allow
    examination of even the roots that did not result in leaks.


  .. index:: -s (gnatmem)

  :switch:`-s {order}`
    This switch causes ``gnatmem`` to sort the allocation roots
    according to the specified sort criteria, each identified by a
    single letter. The currently supported criteria are ``n``, ``h``,
    and ``w`` representing, respectively, the number of unfreed
    allocations, the high watermark, and the final watermark corresponding to
    a specific root. The default order is ``nwh``.


  .. index:: -t (gnatmem)

  :switch:`-t`
    This switch causes memory allocated size to be always output in bytes.
    The default ``gnatmem`` behavior is to show memory sizes less then 1 kilobyte
    in bytes, from 1 kilobyte till 1 megabyte in kilobytes and the rest in
    megabytes.


  .. _Example_of_gnatmem_Usage:

  Example of ``gnatmem`` Usage
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  The following example shows the use of ``gnatmem``
  on a simple memory-leaking program.
  Suppose that we have the following Ada program:

    .. code-block:: ada

       with Ada.Unchecked_Deallocation;
       procedure Test_Gm is

          type T is array (1..1000) of Integer;
          type Ptr is access T;
          procedure Free is new Ada.Unchecked_Deallocation (T, Ptr);
          A : Ptr;

          procedure My_Alloc is
          begin
             A := new T;
          end My_Alloc;

          procedure My_DeAlloc is
             B : Ptr := A;
          begin
             Free (B);
          end My_DeAlloc;

       begin
          My_Alloc;
          for I in 1 .. 5 loop
             for J in I .. 5 loop
                My_Alloc;
             end loop;
             My_Dealloc;
          end loop;
       end;

  The program needs to be compiled with the debugging option and linked with
  the ``gmem`` library:

    ::

       $ gnatmake -g test_gm -largs -lgmem

  We execute the program as usual:

    ::

       $ test_gm

  ``gnatmem`` is invoked simply with

    ::

       $ gnatmem test_gm

  which produces the following output (the details may vary on
  different platforms):

    ::

        Global information
        ------------------
           Total number of allocations        :  18
           Total number of deallocations      :   5
           Final Water Mark (non freed mem)   :  53.00 Kilobytes
           High Water Mark                    :  56.90 Kilobytes

        Allocation Root # 1
        -------------------
         Number of non freed allocations    :  11
         Final Water Mark (non freed mem)   :  42.97 Kilobytes
         High Water Mark                    :  46.88 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc

        Allocation Root # 2
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  10.02 Kilobytes
         High Water Mark                    :  10.02 Kilobytes
         Backtrace                          :
           s-secsta.adb:81 system.secondary_stack.ss_init

        Allocation Root # 3
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  12 Bytes
         High Water Mark                    :  12 Bytes
         Backtrace                          :
           s-secsta.adb:181 system.secondary_stack.ss_init


  Note that the GNAT runtime itself contains a certain number of
  allocations that have no corresponding deallocations,
  as shown here for root #2 and root #3.
  This is a normal behavior when the number of non-freed allocations
  is one: it allocates dynamic data structures that the run time needs for
  the complete lifetime of the program. Note also that there is only one
  allocation root in the user program, with a single line back trace:
  ``test_gm.adb:11 test_gm.my_alloc``, whereas a careful analysis of the
  program shows that ``My_Alloc`` is called at 2 different points in the
  source (line 21 and line 24). If those two allocation roots need to be
  distinguished, you can use the backtrace depth parameter:

    ::

       $ gnatmem 3 test_gm

  which produces the following output:


    ::

        Global information
        ------------------
           Total number of allocations        :  18
           Total number of deallocations      :   5
           Final Water Mark (non freed mem)   :  53.00 Kilobytes
           High Water Mark                    :  56.90 Kilobytes

        Allocation Root # 1
        -------------------
         Number of non freed allocations    :  10
         Final Water Mark (non freed mem)   :  39.06 Kilobytes
         High Water Mark                    :  42.97 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc
           test_gm.adb:24 test_gm
           b_test_gm.c:52 main

        Allocation Root # 2
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  10.02 Kilobytes
         High Water Mark                    :  10.02 Kilobytes
         Backtrace                          :
           s-secsta.adb:81  system.secondary_stack.ss_init
           s-secsta.adb:283 <system__secondary_stack___elabb>
           b_test_gm.c:33   adainit

        Allocation Root # 3
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :   3.91 Kilobytes
         High Water Mark                    :   3.91 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc
           test_gm.adb:21 test_gm
           b_test_gm.c:52 main

        Allocation Root # 4
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  12 Bytes
         High Water Mark                    :  12 Bytes
         Backtrace                          :
           s-secsta.adb:181 system.secondary_stack.ss_init
           s-secsta.adb:283 <system__secondary_stack___elabb>
           b_test_gm.c:33   adainit

  The allocation root #1 of the first example has been split in 2 roots #1
  and #3, thanks to the more precise associated backtrace.

.. _Sanitizers_for_Ada:

Sanitizers for Ada
==================

.. index:: Sanitizers

This section explains how to use sanitizers with Ada code. Sanitizers offer code
instrumentation and run-time libraries that detect certain memory issues and
undefined behaviors during execution. They provide dynamic analysis capabilities
useful for debugging and testing.

While many sanitizer capabilities overlap with Ada's built-in runtime checks,
they are particularly valuable for identifying issues that arise from unchecked
features or low-level operations.

.. _AddressSanitizer:

AddressSanitizer
----------------

.. index:: AddressSanitizer
.. index:: ASan
.. index:: -fsanitize=address

AddressSanitizer (aka ASan) is a memory error detector activated with the
:switch:`-fsanitize=address` switch. Note that many of the typical memory errors,
such as use after free or buffer overflow, are detected by Ada’s ``Access_Check``
and ``Index_Check``.

It can detect the following types of problems:

* Wrong memory overlay

  A memory overlay is a situation in which an object of one type is placed at the
  same memory location as a distinct object of a different type, thus overlaying
  one object over the other in memory. When there is an overflow because the
  objects do not overlap (like in the following example), the sanitizer can signal
  it.

    .. code-block:: ada

       procedure Wrong_Size_Overlay is
          type Block is array (Natural range <>) of Integer;

          Block4 : aliased Block := (1 .. 4 => 4);
          Block5 : Block (1 .. 5) with Address => Block4'Address;
       begin
          Block5 (Block5'Last) := 5;  --  Outside the object
       end Wrong_Size_Overlay;

  If the code is built with the :switch:`-fsanitize=address` and :switch:`-g` options,
  the following error is shown at execution time:

    ::

        ...
        SUMMARY: AddressSanitizer: stack-buffer-overflow wrong_size_overlay.adb:7 in _ada_wrong_size_overlay
        ...

* Buffer overflow

  Ada’s ``Index_Check`` detects buffer overflows caused by out-of-bounds array
  access. If run-time checks are disabled, the sanitizer can still detect such
  overflows at execution time the same way as it signalled the previous wrong
  memory overlay. Note that if both the Ada run-time checks and the sanitizer
  are enabled, the Ada run-time exception takes precedence.

    .. code-block:: ada

       procedure Buffer_Overrun is
          Size : constant := 100;
          Buffer : array (1 .. Size) of Integer := (others => 0);
          Wrong_Index : Integer := Size + 1 with Export;
       begin
          -- Access outside the boundaries
          Put_Line ("Value: " & Integer'Image (Buffer (Wrong_Index)));
       end Buffer_Overrun;

* Use after lifetime

  Ada’s ``Accessibility_Check`` helps prevent use-after-return and
  use-after-scope errors by enforcing lifetime rules. When these checks are
  bypassed using ``Unchecked_Access``, sanitizers can still detect such
  violations during execution.

    .. code-block:: ada

       with Ada.Text_IO; use Ada.Text_IO;

       procedure Use_After_Return is
          type Integer_Access is access all Integer;
          Ptr : Integer_Access;

          procedure Inner;

          procedure Inner is
             Local : aliased Integer := 42;
          begin
             Ptr := Local'Unchecked_Access;
          end Inner;

       begin
          Inner;
          --  Accessing Local after it has gone out of scope
          Put_Line ("Value: " & Integer'Image (Ptr.all));
       end Use_After_Return;

  If the code is built with the :switch:`-fsanitize=address` and :switch:`-g`
  options, the following error is shown at execution time:

    ::

        ...
        ==1793927==ERROR: AddressSanitizer: stack-use-after-return on address 0xf6fa1a409060 at pc 0xb20b6cb6cac0 bp 0xffffcc89c8b0 sp 0xffffcc89c8c8
        READ of size 4 at 0xf6fa1a409060 thread T0
            #0 0xb20b6cb6cabc in _ada_use_after_return use_after_return.adb:18
            ...

        Address 0xf6fa1a409060 is located in stack of thread T0 at offset 32 in frame
            #0 0xb20b6cb6c794 in use_after_return__inner use_after_return.adb:9

          This frame has 1 object(s):
            [32, 36) 'local' (line 10) <== Memory access at offset 32 is inside this variable
        SUMMARY: AddressSanitizer: stack-use-after-return use_after_return.adb:18 in _ada_use_after_return
        ...

* Memory leak

  A memory leak happens when a program allocates memory from the heap but fails
  to release it after it is no longer needed and loses all references to it like
  in the following example.

    .. code-block:: ada

       procedure Memory_Leak is
          type Integer_Access is access Integer;

          procedure Allocate is
             Ptr : Integer_Access := new Integer'(42);
          begin
             null;
          end Allocate;
       begin
          --  Memory leak occurs in the following procedure
         Allocate;
       end Memory_Leak;

  If the code is built with the :switch:`-fsanitize=address` and :switch:`-g`
  options, the following error is emitted at execution time showing the
  location of the offending allocation.

    ::

        ==1810634==ERROR: LeakSanitizer: detected memory leaks

        Direct leak of 4 byte(s) in 1 object(s) allocated from:
            #0 0xe3cbee4bb4a8 in __interceptor_malloc asan_malloc_linux.cpp:69
            #1 0xc15bb25d0af8 in __gnat_malloc (memory_leak+0x10af8) (BuildId: f5914a6eac10824f81d512de50b514e7d5f733be)
            #2 0xc15bb25c9060 in memory_leak__allocate memory_leak.adb:5
            ...

        SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

.. _UndefinedBehaviorSanitizer:

UndefinedBehaviorSanitizer
--------------------------

.. index:: UndefinedBehaviorSanitizer
.. index:: UBSan
.. index:: -fsanitize=undefined

UndefinedBehaviorSanitizer (aka UBSan) modifies the program at compile-time to
catch various kinds of undefined behavior during program execution.

Different sanitize options (:switch:`-fsanitize=alignment,float-cast-overflow,signed-integer-overflow`)
detect the following types of problems:

* Wrong alignment

  The :switch:`-fsanitize=alignment` flag (included also in
  :switch:`-fsanitize=undefined`) enables run-time checks for misaligned memory
  accesses, ensuring that objects are accessed at addresses that conform to the
  alignment constraints of their declared types. Violations may lead to crashes
  or performance penalties on certain architectures.

  In the following example:

    .. code-block:: ada

       with Ada.Text_IO; use Ada.Text_IO;
       with System.Storage_Elements; use System.Storage_Elements;

       procedure Misaligned_Address is
          type Aligned_Integer is new Integer with
            Alignment => 4;  -- Ensure 4-byte alignment

          Reference : Aligned_Integer := 42;  -- Properly aligned object

          -- Create a misaligned object by modifying the address manually
          Misaligned : Aligned_Integer with Address => Reference'Address + 1;

       begin
          -- This causes undefined behavior or an alignment exception on strict architectures
          Put_Line ("Misaligned Value: " & Aligned_Integer'Image (Misaligned));
       end Misaligned_Address;

  If the code is built with the :switch:`-fsanitize=alignment` and :switch:`-g`
  options, the following error is shown at execution time.

    ::

        misaligned_address.adb:15:51: runtime error: load of misaligned address 0xffffd836dd45 for type 'volatile misaligned_address__aligned_integer', which requires 4 byte alignment

* Signed integer overflow

  Ada performs range checks at runtime in arithmetic operation on signed integers
  to ensure the value is within the target type's bounds. If this check is removed,
  the :switch:`-fsanitize=signed-integer-overflow` flag (included also in
  :switch:`-fsanitize=undefined`) enables run-time checks for signed integer
  overflows.

  In the following example:

    .. code-block:: ada

       procedure Signed_Integer_Overflow is
          type Small_Int is range -128 .. 127;
          X, Y, Z : Small_Int with Export;
       begin
          X := 100;
          Y := 50;
          -- This addition will exceed 127, causing an overflow
          Z := X + Y;
       end Signed_Integer_Overflow;

  If the code is built with the :switch:`-fsanitize=signed-integer-overflow` and
  :switch:`-g` options, the following error is shown at execution time.

    ::

        signed_integer_overflow.adb:8:11: runtime error: signed integer overflow: 100 + 50 cannot be represented in type 'signed_integer_overflow__small_int'

* Float to integer overflow

  When converting a floating-point value to an integer type, Ada performs a range
  check at runtime to ensure the value is within the target type's bounds. If this
  check is removed, the sanitizer can detect overflows in conversions from
  floating point to integer types.

  In the following code:

      .. code-block:: ada

         procedure Float_Cast_Overflow is
            Flt : Float := Float'Last with Export;
            Int : Integer;
         begin
            Int := Integer (Flt); --  Overflow
         end Float_Cast_Overflow;

  If the code is built with the :switch:`-fsanitize=float-cast-overflow` and
  :switch:`-g` options, the following error is shown at execution time.

    ::

        float_cast_overflow.adb:5:20: runtime error: 3.40282e+38 is outside the range of representable values of type 'integer'

Sanitizers in mixed-language applications
-----------------------------------------

Most of the checks performed by sanitizers operate at a global level, which
means they can detect issues even when they span across language boundaries.
This applies notably to:

* All checks performed by the AddressSanitizer: wrong memory overlays, buffer
  overflows, uses after lifetime, memory leaks. These checks apply globally,
  regardless of where the objects are allocated or defined, or where they are
  destroyed

* Wrong alignment checks performed by the UndefinedBehaviorSanitizer. It will
  check whether an object created in a given language is accessed in another
  with an incompatible alignment

An interesting case that highlights the benefit of global sanitization is a
buffer overflow caused by a mismatch in language bindings. Consider the
following C function, which allocates an array of 4 characters:

      .. code-block:: c

         char *get_str (void) {
            char *str = malloc (4 * sizeof (char));
         }

This function is then bound to Ada code, which incorrectly assumes the buffer
is of size 5:

      .. code-block:: ada

         type Buffer is array (1 .. 5) of Character;

         function Get_Str return access Buffer
            with Import => True, Convention => C, External_Name => "get_str";

         Str : access Buffer := Get_Str;
         Ch  : Character     := S (S'Last);  -- Detected by AddressSanitizer as erroneous

On the Ada side, accessing ``Str (5)`` appears valid because the array type
declares five elements. However, the actual memory allocated in C only holds
four. This mismatch is not detectable by Ada run-time checks, because Ada has
no visibility into how the memory was allocated.

However, the AddressSanitizer will detect the heap buffer overflow at runtime,
halting execution and providing a clear diagnostic:

    ::

        ...
        SUMMARY: AddressSanitizer: heap-buffer-overflow buffer_overflow.adb:20 in _ada_buffer_overflow
        ...

---

### Gcc Ada Doc Gnat Ugn Gnat Utility Programs (`gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst`)

.. role:: switch(samp)

.. |rightarrow| unicode:: 0x2192

.. _GNAT_Utility_Programs:

*********************
GNAT Utility Programs
*********************

This chapter describes a number of utility programs:

.. only:: PRO or GPL

  * :ref:`The_File_Cleanup_Utility_gnatclean`
  * :ref:`The_GNAT_Library_Browser_gnatls`
  * :ref:`The_GNAT_Pretty_Printer_gnatpp`
  * :ref:`The_Body_Stub_Generator_gnatstub`
  * :ref:`The_Backtrace_Symbolizer_gnatsymbolize`

  It also describes how you can use several of these tools in conjunction
  with project files: :ref:`Using_Project_Files_with_GNAT_Tools`

.. only:: FSF

  * :ref:`The_File_Cleanup_Utility_gnatclean`
  * :ref:`The_GNAT_Library_Browser_gnatls`

Other GNAT utilities are described elsewhere in this manual:

* :ref:`Handling_Arbitrary_File_Naming_Conventions_with_gnatname`
* :ref:`File_Name_Krunching_with_gnatkr`
* :ref:`Renaming_Files_with_gnatchop`
* :ref:`Preprocessing_with_gnatprep`


.. _The_File_Cleanup_Utility_gnatclean:

The File Cleanup Utility ``gnatclean``
======================================

.. index:: File cleanup tool
.. index:: gnatclean

``gnatclean`` is a tool that deletes some files produced by the
compiler, binder and linker, including ALI files, object files, tree files,
expanded source files, library files, interface copy source files, binder
generated files and executable files.

.. _Running_gnatclean:

Running ``gnatclean``
---------------------

You run the ``gnatclean`` command as follow:

  ::

      $ gnatclean switches names

where ``names`` is a list of source file names. You may omit suffixes :file:`.ads` and
:file:`adb`. If a project file is specified using switch
:switch:`-P`, then you may completely omit ``names``.

In normal mode, ``gnatclean`` deletes the files produced by the compiler and,
if switch :switch:`-c` is not specified, produced by the binder and
linker. In information-only mode, specified by switch
:switch:`-n`, ``gnatclean`` lists the files that would have been deleted in
normal mode, but doesn't actually delete any files.


.. _Switches_for_gnatclean:

Switches for ``gnatclean``
--------------------------

``gnatclean`` recognizes the following switches:

.. index:: --version (gnatclean)

:switch:`--version`
  Display copyright and version, then exit, disregarding all other options.

.. index:: --help (gnatclean)

:switch:`--help`
  If :switch:`--version` was not specified, display usage, then exit
  disregarding all other options.

:switch:`--subdirs={subdir}`
  Actual object directory of each project file, which is the
  subdirectory ``subdir`` of the object directory specified or defaulted
  in the project file.

:switch:`--unchecked-shared-lib-imports`
  By default, shared library projects are not allowed to import static library
  projects. When this switch is specified, this restriction is lifted.

.. index:: -c (gnatclean)

:switch:`-c`
  Only attempt to delete the files produced by the compiler, not those produced
  by the binder or the linker. The files that are not to be deleted are library
  files, interface copy files, binder generated files and executable files.

.. index:: -D (gnatclean)

:switch:`-D {dir}`
  Indicate that ALI and object files should normally be found in
  directory ``dir``.

.. index:: -F (gnatclean)

:switch:`-F`
  When using project files, if some errors or warnings are detected
  during parsing and verbose mode is not in effect (the switch
  :switch:`-v` is not specified), error lines start with the full path
  name of the project file, rather than its simple file name.

.. index:: -h (gnatclean)

:switch:`-h`
  Output a message explaining the usage of ``gnatclean``.

.. index:: -n (gnatclean)

:switch:`-n`
  Informative-only mode. Do not delete any files. Output the list of the files
  that would have been deleted if this switch was not specified.

.. index:: -P (gnatclean)

:switch:`-P{project}`
  Use project file ``project``. You can specify only one such switch.
  When cleaning a project file, ``gnatclean`` deletes the files
  produced by the compilation of the immediate sources or inherited
  sources of the project files. This does not depend on whether or not
  you include executable names on the command line.

.. index:: -q (gnatclean)

:switch:`-q`
  Quiet output. If there are no errors, do not output anything, except in
  verbose mode (:switch:`-v`) or in information-only mode
  (:switch:`-n`).

.. index:: -r (gnatclean)

:switch:`-r`
  When a project file is specified (using :switch:`-P`), clean all
  imported and extended project files, recursively. If you don't
  specify this switch, ``gnatclean`` only deletes the files related to
  the main project file. This switch has no effect if you don't
  specify a project file.

.. index:: -v (gnatclean)

:switch:`-v`
  Verbose mode.

.. index:: -vP (gnatclean)

:switch:`-vP{x}`
  Indicates the verbosity of the parsing of GNAT project files.
  :ref:`Switches_Related_to_Project_Files`.

.. index:: -X (gnatclean)

:switch:`-X{name}={value}`
  Indicates that external variable ``name`` has the value ``value``.
  The Project Manager will use this value for occurrences of
  ``external(name)`` when parsing the project file.
  See :ref:`Switches_Related_to_Project_Files`.

.. index:: -aO (gnatclean)

:switch:`-aO{dir}`
  When searching for ALI and object files, look in directory ``dir``.

.. index:: -I (gnatclean)

:switch:`-I{dir}`
  Equivalent to :switch:`-aO{dir}`.

.. index:: -I- (gnatclean)

.. index:: Source files, suppressing search

:switch:`-I-`
  Do not look for ALI or object files in the directory
  where ``gnatclean`` was invoked.



.. _The_GNAT_Library_Browser_gnatls:

The GNAT Library Browser ``gnatls``
===================================

.. index:: Library browser
.. index:: ! gnatls

``gnatls`` is a tool that outputs information about compiled
units. It gives the relationship between objects, unit names and source
files. You can also use it to check the source dependencies of a unit
as well as various characteristics.

.. _Running_gnatls:

Running ``gnatls``
------------------

You run the ``gnatls`` command as follows:

  ::

      $ gnatls switches object_or_ali_file

The main argument is the list of object or :file:`ali` files
(see :ref:`The_Ada_Library_Information_Files`)
for which you are requesting information.

In the default mode, without additional options, ``gnatls`` produces a
four-column listing. Each line contains information for a specific
object. The first column gives the full path of the object, the second
column gives the name of the principal unit in the object, the third
column gives the status of the source and the fourth column gives the
full path of the source representing this unit.
Here's a simple example:


  ::

     $ gnatls *.o
     ./demo1.o            demo1            DIF demo1.adb
     ./demo2.o            demo2             OK demo2.adb
     ./hello.o            h1                OK hello.adb
     ./instr-child.o      instr.child      MOK instr-child.adb
     ./instr.o            instr             OK instr.adb
     ./tef.o              tef              DIF tef.adb
     ./text_io_example.o  text_io_example   OK text_io_example.adb
     ./tgef.o             tgef             DIF tgef.adb

You should interpret the first line as follows: the main unit, which is
contained in
object file :file:`demo1.o`, is demo1, whose main source is in
:file:`demo1.adb`. Furthermore, the version of the source used for the
compilation of demo1 has been modified (DIF). Each source file has a status
qualifier which can be:

*OK (unchanged)*
  The version of the source file used for the compilation of the
  specified unit corresponds exactly to the actual source file.

*MOK (slightly modified)*
  The version of the source file used for the compilation of the
  specified unit differs from the actual source file but not enough to
  require recompilation (e.g., only comments have been changed). If
  you run ``gnatmake`` with the option :switch:`-m` (minimal
  recompilation), it will not recompile a file marked MOK.

*DIF (modified)*
  No version of the source found on the path corresponds to the source
  used to build this object.

*??? (file not found)*
  No source file was found for this unit.

*HID (hidden,  unchanged version not first on PATH)*
  The version of the source that corresponds exactly to the source used
  for compilation has been found on the path but it is hidden by another
  version of the same source that has been modified.


.. _Switches_for_gnatls:

Switches for ``gnatls``
-----------------------

You can specify the following switches to ``gnatls``:


.. index:: --version (gnatls)

:switch:`--version`
  Display copyright and version, then exit, disregarding all other options.


.. index:: --help (gnatls)

:switch:`--help`
  If :switch:`--version` was not specified, display usage, then exit,
  disregarding all other options.


.. index:: -a (gnatls)

:switch:`-a`
  Consider all units, including those of the predefined Ada library.
  Especially useful with :switch:`-d`.


.. index:: -d (gnatls)

:switch:`-d`
  List sources that specified units depend on.


.. index:: -h (gnatls)

:switch:`-h`
  Output the list of options.


.. index:: -o (gnatls)

:switch:`-o`
  Only output information about object files.


.. index:: -s (gnatls)

:switch:`-s`
  Only output information about source files.


.. index:: -u (gnatls)

:switch:`-u`
  Only output information about compilation units.


.. index:: -files (gnatls)

:switch:`-files={file}`
  Take as arguments the files listed in text file ``file``, which may
  contain empty lines that are ignored.  Each nonempty line should
  contain the name of an existing file.  Several such switches may be
  specified on the same command.


.. index:: -aO (gnatls)

.. index:: -aI (gnatls)

.. index:: -I (gnatls)

.. index:: -I- (gnatls)

:switch:`-aO{dir}`, :switch:`-aI{dir}`, :switch:`-I{dir}`, :switch:`-I-`, :switch:`-nostdinc`
  Source path manipulation. It has the same meaning as the equivalent
  ``gnatmake`` switches (:ref:`Switches_for_gnatmake`).


.. index:: -aP (gnatls)

:switch:`-aP{dir}`
  Add ``dir`` at the beginning of the project search dir.


.. index:: --RTS (gnatls)

:switch:`--RTS={rts-path}`
  Specifies the default location of the runtime library. It has the
  same meaning as the equivalent ``gnatmake`` switch
  (:ref:`Switches_for_gnatmake`).


.. index:: -v (gnatls)

:switch:`-v`
  Verbose mode. Output the complete source, object and project paths. Don't use
  the default column layout but instead use long format giving as much as
  information possible on each requested units, including special
  characteristics such as:

  * *Preelaborable*: The unit is preelaborable in the Ada sense.

  * *No_Elab_Code*:  No elaboration code has been produced by the compiler for this unit.

  * *Pure*: The unit is pure in the Ada sense.

  * *Elaborate_Body*: The unit contains a pragma Elaborate_Body.

  * *Remote_Types*: The unit contains a pragma Remote_Types.

  * *Shared_Passive*: The unit contains a pragma Shared_Passive.

  * *Predefined*: This unit is part of the predefined environment and cannot be modified
    by the user.

  * *Remote_Call_Interface*: The unit contains a pragma Remote_Call_Interface.


.. _Example_of_gnatls_Usage:

Example of ``gnatls`` Usage
---------------------------

Here's an example of using the verbose switch. Note how the source and
object paths are affected by the :switch:`-I` switch.

  ::

      $ gnatls -v -I.. demo1.o

      GNATLS 5.03w (20041123-34)
      Copyright 1997-2004 Free Software Foundation, Inc.

      Source Search Path:
         <Current_Directory>
         ../
         /home/comar/local/adainclude/

      Object Search Path:
         <Current_Directory>
         ../
         /home/comar/local/lib/gcc-lib/x86-linux/3.4.3/adalib/

      Project Search Path:
         <Current_Directory>
         /home/comar/local/lib/gnat/

      ./demo1.o
         Unit =>
           Name   => demo1
           Kind   => subprogram body
           Flags  => No_Elab_Code
           Source => demo1.adb    modified

Here's an example of use of the dependency list.
Note the use of the :switch:`-s` switch,
which gives a simple list of source files. You may find this useful for
building specialized scripts.

  ::

      $ gnatls -d demo2.o
      ./demo2.o   demo2        OK demo2.adb
                               OK gen_list.ads
                               OK gen_list.adb
                               OK instr.ads
                               OK instr-child.ads

      $ gnatls -d -s -a demo1.o
      demo1.adb
      /home/comar/local/adainclude/ada.ads
      /home/comar/local/adainclude/a-finali.ads
      /home/comar/local/adainclude/a-filico.ads
      /home/comar/local/adainclude/a-stream.ads
      /home/comar/local/adainclude/a-tags.ads
      gen_list.ads
      gen_list.adb
      /home/comar/local/adainclude/gnat.ads
      /home/comar/local/adainclude/g-io.ads
      instr.ads
      /home/comar/local/adainclude/system.ads
      /home/comar/local/adainclude/s-exctab.ads
      /home/comar/local/adainclude/s-finimp.ads
      /home/comar/local/adainclude/s-finroo.ads
      /home/comar/local/adainclude/s-secsta.ads
      /home/comar/local/adainclude/s-stalib.ads
      /home/comar/local/adainclude/s-stoele.ads
      /home/comar/local/adainclude/s-stratt.ads
      /home/comar/local/adainclude/s-tasoli.ads
      /home/comar/local/adainclude/s-unstyp.ads
      /home/comar/local/adainclude/unchconv.ads


.. only:: PRO or GPL

   .. _The_GNAT_Pretty_Printer_gnatpp:

   The GNAT Pretty Printer ``gnatpp``
   ==================================

   .. index:: ! gnatpp
   .. index:: pretty printer

   The ``gnatpp`` tool is a utility for source reformatting / pretty
   printing. It takes an Ada source file as input and generates a
   reformatted version as output. You can specify various style
   directives via switches; e.g., identifier case conventions, rules of
   indentation, and comment layout.

   ``gnatpp`` is a project-aware tool
   (see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
   the project-related switches). The project file package that can specify
   ``gnatpp`` switches is named ``Pretty_Printer``.

   ``gnatpp`` cannot process sources that contain preprocessing
   directives.

   The ``gnatpp`` command has the form

     ::

        $ gnatpp [ switches ] filename

   where

   * ``switches`` is an optional sequence of switches defining such properties
     as the formatting rules, the source search path, and the destination for
     the output source file

   * ``filename`` is the name of the source file to reformat; wildcards
     or several file names on the same gnatpp command are allowed. The
     file name may contain path information; it does not have to follow
     the GNAT file naming rules

   Note that you no longer need to specify the Ada language version;
   ``gnatpp`` can process Ada source code written in any version from Ada 83
   onward without specifying any language version switch.


   .. _Switches_for_gnatpp:

   Switches for ``gnatpp``
   -----------------------

   The following subsections describe the various switches accepted by
   ``gnatpp``, organized by category.

   You specify a switch by supplying a name and usually also a value.
   In many cases the values for a switch with a given name are incompatible
   with each other
   (for example the switch that controls the casing of a reserved word may have
   exactly one value: upper case, lower case, or
   mixed case) and thus exactly one such switch can be in effect for an
   invocation of ``gnatpp``.
   If more than one is supplied, the last one is used.
   However, some values for the same switch are mutually compatible.
   You may supply several such switches to ``gnatpp``, but
   each must be specified in full, with both the name and the value.
   Abbreviated forms (the name appearing once, followed by each value) are
   not permitted.


   .. _Layout_Control:

   Layout Control
   ^^^^^^^^^^^^^^

   .. index:: Layout control in gnatpp

   ``gnatpp`` provides a layout switch which controls the general
   formatting style:

   .. index:: layout(gnatpp)

   :switch:`--layout=default|minimal|compact|tall`

   :switch:`default`
     The default layout is a compact style, but ``gnatpp`` adds
     alignment and puts some keywords on a separate line.
     
     ``gnatpp`` adds alignment in the the following constructs:

     * ``:`` in declarations,
     * ``:=`` in initializations in declarations,
     * ``:=`` in assignment statements,
     * ``=>`` in associations, and
     * ``at`` keywords in the component clauses in record representation
       clauses.

     In addition, ``gnatpp`` also lines up ``in`` and ``out`` keywords
     in parameter specifications.

     ``gnatpp`` places the keyword ``is`` on a separate line in a
     subprogram body in case the spec occupies more than one line.

     ``gnatpp`` places the keyword ``return`` on a separate line if a
     subprogram spec does not fit on one line.

   :switch:`minimal`
     The minimal layout will avoid changing the source layout by keeping all
     line breaks from the original source (it will not insert or delete any).
     It will add indentation where appropriate as long as it does not exceed
     the line length limit.

   :switch:`compact`
     The compact layout avoids adding line breaks and alignment by packing
     as many subexpressions on the same line as possible.

     Whole-line comments that form a paragraph are filled in typical word
     processor style (that is, moving words between lines to make them similar
     in length, except the last one which may be shorter).

     For each whole-line comment that does not end with two hyphens, inserts
     spaces if necessary after the starting two hyphens to ensure that there
     are at least two spaces preceding the first non-blank character of the
     comment.

   :switch:`tall`
     The tall layout favors adding lines breaks and alignment. It adds
     all the alignment and line breaks defined in the ``default`` option,
     and in addition:

     * Places the keyword ``loop`` in FOR and WHILE loop statements on a
       separate line
     * Places the keyword ``then`` in IF statements on a separate line
     * Places each keyword ``use`` in USE clauses on a separate line
     * Splits the line just before the keyword ``record`` in a RECORD type
       declaration
     * Indents named blocks and loop statements with respect to the name
     * When necessary, splits binary operators always before the operator
     * Inserts an extra blank before various occurrences of ``(`` and ``:``
     * When it is necessary to split a line between two subexpressions (because
       otherwise the construct would exceed --max-line-length), then all such
       subexpressions are placed on separate lines
     * Formats enumeration type declarations “vertically”, e.g. each
       enumeration literal goes on a separate line
     * Formats array type declarations “vertically”, e.g. for multidimensional
       arrays, each index_subtype_definition or discrete_subtype_definition
       goes on a separate line
     * Format aggregates “vertically” if named notation is used for all
       component_associations, e.g. each component_association goes on a
       separate line
     * Formats case statements, case expressions, and variant parts with
       additional line breaks
     * Inserts blank lines where appropriate (between bodies and other large
       constructs)
     * Similarly to the :switch:`compact` layout, two spaces are added in the
       beginning of a whole-line comment when needed


   .. _Casing_Control:

   Casing Control
   ^^^^^^^^^^^^^^

   .. index:: Casing control in gnatpp

   ``gnatpp`` allows you to specify the casing for reserved words,
   pragma names, attribute designators, and identifiers. For
   identifiers, you may define a general rule for name casing but also
   override this rule via a set of dictionary files.

   Three types of casing are supported: 'Lower Case', 'Upper Case', and
   'Mixed Case'. 'Mixed case' means that the first letter and each
   letter immediately following an underscore are converted to their
   uppercase forms and all other letters are converted to their lowercase
   forms.





   .. index:: --name-case-as-declared (gnatpp)

   :switch:`--name-case-as-declared, -nD`
     Name casing for defining occurrences are as they appear in the source file
     (this is the default).

   .. index:: --name-upper-case (gnatpp)

   :switch:`--name-upper-case, -nU`
     Names are in upper case.

   .. index:: --name-lower-case (gnatpp)

   :switch:`--name-lower-case, -nL`
     Names are in lower case.

   .. index:: --name-mixed-case (gnatpp)

   :switch:`--name-mixed-case, -nM`
     Names are in mixed case.

   .. index:: --attribute-lower-case (gnatpp)

   :switch:`--attribute-lower-case, -aL`
     Attribute designators are lower case.

   .. index:: --attribute-upper-case (gnatpp)

   :switch:`--attribute-upper-case, -aU`
     Attribute designators are upper case.

   .. index:: --attribute-mixed-case (gnatpp)

   :switch:`--attribute-mixed-case, -aM`
     Attribute designators are mixed case (this is the default).

   .. index:: --keyword-lower-case (gnatpp)

   :switch:`--keyword-lower-case, -kL`
     Keywords (technically, these are known in Ada as *reserved words*) are
     lower case (this is the default).

   .. index:: --keyword-upper-case (gnatpp)

   :switch:`--keyword-upper-case, -kU`
     Keywords are upper case.

   .. index:: --enum-case-as-declared (gnatpp)

   :switch:`--enum-case-as-declared, -neD`
     Enumeration literal casing for defining occurrences are as they appear in
     the source file. Overrides the :switch:`-n` casing setting.

   .. index:: --enum-upper-case (gnatpp)

   :switch:`--enum-upper-case, -neU`
     Enumeration literals are in upper case. Overrides the :switch:`-n` casing
     setting.

   .. index:: --enum-lower-case (gnatpp)

   :switch:`--enum-lower-case, -neL`
     Enumeration literals are in lower case. Overrides the :switch:`-n` casing
     setting.

   .. index:: --enum-mixed-case (gnatpp)

   :switch:`--enum-mixed-case, -neM`
     Enumeration literals are in mixed case. Overrides the :switch:`-n` casing
     setting.

   .. index:: --type-case-as-declared (gnatpp)

   :switch:`--type-case-as-declared, -ntD`
     Names introduced by type and subtype declarations are always
     cased as they appear in the declaration in the source file.
     Overrides the :switch:`-n` casing setting.

   .. index:: --type-upper-case (gnatpp)

   :switch:`--type-upper-case, -ntU`
     Names introduced by type and subtype declarations are always in
     upper case. Overrides the :switch:`-n` casing setting.

   .. index:: --type-lower-case (gnatpp)

   :switch:`--type-lower-case, -ntL`
     Names introduced by type and subtype declarations are always in
     lower case. Overrides the :switch:`-n` casing setting.

   .. index:: --type-mixed-case (gnatpp)

   :switch:`--type-mixed-case, -ntM`
     Names introduced by type and subtype declarations are always in
     mixed case. Overrides the :switch:`-n` casing setting.

   .. index:: --number-upper-case (gnatpp)

   :switch:`--number-upper-case, -nnU`
     Names introduced by number declarations are always in
     upper case. Overrides the :switch:`-n` casing setting.

   .. index:: --number-lower-case (gnatpp)

   :switch:`--number-lower-case, -nnL`
     Names introduced by number declarations are always in
     lower case. Overrides the :switch:`-n` casing setting.

   .. index:: --number-mixed-case (gnatpp)

   :switch:`--number-mixed-case, -nnM`
     Names introduced by number declarations are always in
     mixed case. Overrides -n casing setting.

   .. index:: --pragma-lower-case (gnatpp)

   :switch:`--pragma-lower-case, -pL`
     Pragma names are lower case.

   .. index:: --pragma-upper-case (gnatpp)

   :switch:`--pragma-upper-case, -pU`
     Pragma names are upper case.

   .. index:: --pragma-mixed-case (gnatpp)

   :switch:`--pragma-mixed-case, -pM`
     Pragma names are mixed case (this is the default).

   .. index:: --constant-case-as-non-constant (gnatpp)

   :switch:`--constant-case-as-non-constant, -cN`
     Constant object declaration names have the same case as the name casing
     (this is the default).

   .. index:: --constant-case-as-declared (gnatpp)

   :switch:`--constant-case-as-declared, -cD`
     Constant object declaration names are as they appear in the source file.

   .. index:: --constant-lower-case (gnatpp)

   :switch:`--constant-lower-case, -cL`
     Constant object declaration names are lower case.

   .. index:: --constant-upper-case (gnatpp)

   :switch:`--constan-upper-case, -cU`
     Constant object declaration names are upper case.

   .. index:: --constant-mixed-case (gnatpp)

   :switch:`--constant-mixed-case, -cM`
     Constant object declaration names are mixed case.

   .. index:: --syntax-only (gnatpp)

   :switch:`--syntax-only`
     Disable the semantic analysis (name resolution) done by libadalang.
     This means ``gnatpp`` is not able to support any of the
     "as-declared" switches.

   .. index:: --dictionary (gnatpp)

   :switch:`--dictionary={file}, -D={file}`
     Use ``file`` as a *dictionary file* that defines
     the casing for a set of specified names,
     thereby overriding the effect on these names by
     any explicit or implicit
     -n switch.
     To supply more than one dictionary file,
     use several ``--dictionary`` switches.

     ``gnatpp`` implicitly uses a *default dictionary file*
     to define the casing for the Ada predefined names and
     the names declared in the GNAT libraries.

   .. index:: --dictionary=- (gnatpp)

   :switch:`--dictionary=-, -D=-`
     Do not use the default dictionary file;
     instead, use the casing
     defined by a :switch:`-n` switch and any explicit
     dictionary file(s)

   The structure of a dictionary file, and details on the conventions
   used in the default dictionary file, are defined in :ref:`Name_Casing`.

   The :switch:`--dictionary=-` and
   :switch:`--dictionary={file}` switches are mutually
   compatible.

   This group of ``gnatpp`` switches controls the layout of comments and
   complex syntactic constructs. See :ref:`Formatting_Comments` for details
   on their effect.


   .. _General_Text_Layout_Control:

   General Text Layout Control
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^

   These switches allow control over line length and indentation.

   .. index:: --max-line-length (gnatpp)

   :switch:`--max-line-length={nnn}, -M={nnn}`
     Maximum line length, ``nnn`` from 32...256. The default value is 79


   .. index:: --indentation (gnatpp)

   :switch:`--indentation={nnn}, -i={nnn}`
     Indentation level, ``nnn`` from 1...9. The default value is 3


   .. index:: --indent-continuation (gnatpp)

   :switch:`--indent-continuation={nnn}, -cl={nnn}`
     Indentation level for continuation lines (relative to the line being
     continued), ``nnn`` from 1...9.
     The default
     value is one less than the (normal) indentation level, unless the
     indentation is set to 1 (in which case the default value for continuation
     line indentation is also 1)


   .. _Other_Formatting_Options:

   Other Formatting Options
   ^^^^^^^^^^^^^^^^^^^^^^^^

   These switches control other formatting not listed above.

   .. index:: --decimal-grouping  (gnatpp)

   :switch:`--decimal-grouping={n}`
     Put underscores in decimal literals (numeric literals without a base)
     every ``n`` characters. If a literal already has one or more
     underscores, ``gnatpp`` will not modify it. For example, with
     ``--decimal-grouping=3``, ``1000000`` is changed to
     ``1_000_000``.


   .. index:: --based-grouping  (gnatpp)

   :switch:`--based-grouping={n}`
     Same as ``--decimal-grouping``, but for based literals. For
     example, with ``--based-grouping=4``, ``16#0001FFFE#`` is
     changed to ``16#0001_FFFE#``.

   .. index:: --call-threshold (gnatpp)

   :switch:`--call-threshold={nnn}`
     If the number of parameter associations is greater than ``nnn``
     and if at least one association uses named notation, start each
     association from a new line. If ``nnn`` is 0, ``gnatpp`` does not
     check for the number of associations; this is the default.

   .. index:: --par-threshold (gnatpp)

   :switch:`--par-threshold={nnn}`
     If the number of parameter specifications is greater than ``nnn``
     (or equal to ``nnn`` in case of a function), start each specification from
     a new line. If ``nnn`` is 0, and :switch:`--no-separate-is` was not
     specified, then the ``is`` is placed on a separate line. This option is
     disabled by default.


   .. _Setting_the_Source_Search_Path:

   Setting the Source Search Path
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   To define the search path for the input source file, pass ``gnatpp``
   the same switches as the GNAT compiler, with the same effects:

   .. index:: -I (gnatpp)


   :switch:`-I{dir}`

   .. index:: -I- (gnatpp)

   :switch:`-I-`

   .. index:: -gnatec (gnatpp)

   :switch:`-gnatec={path}`


   .. _Output_File_Control-gnatpp:

   Output File Control
   ^^^^^^^^^^^^^^^^^^^

   By default, the output overwrites the input file.
   You can specify the location of the output with the following switches:


   .. index:: --replace (gnatpp)

   :switch:`--replace, -rnb`
     This is the default.
     Replace the input source file with the reformatted output without
     creating any backup copy of the input source.


   .. index:: --output-dir (gnatpp)

   :switch:`--output-dir={dir}`
     Generate the output file in directory :file:`dir` with the same
     name as the input file. If :file:`dir` is the same as the
     directory containing the input file, ``gnatpp`` does not read or
     process the input file; use ``--replace`` if you want to update
     the input file in place.


   .. index:: --pipe (gnatpp)

   :switch:`--pipe, -pipe`
     Send the output to ``Standard_Output``


   .. index:: --output (gnatpp)

   :switch:`--output={output_file}, -o={output_file}`
     Write the output into ``output_file``.
     If ``output_file`` already exists, ``gnatpp`` terminates without
     reading or processing the input file.


   .. index:: --output-force (gnatpp)

   :switch:`--output-force={output_file}, -of={output_file}`
     Write the output into ``output_file``, overwriting the existing file
     (if one is present).


   .. index:: --replace-backup (gnatpp)

   :switch:`--replace-backup, -r`
     Replace the input source file with the reformatted output and copy the
     original input source into the file whose name is obtained by appending
     the :file:`.npp` suffix to the name of the input file.
     If a file with this name already exists, ``gnatpp`` terminates without
     reading or processing the input file.


   .. index:: --replace-force-backup (gnatpp)

   :switch:`--replace-force-backup, -rf`
     Like ``--replace-backup`` except that if the file with the specified name
     already exists, it is overwritten.


   .. index:: --eol (gnatpp)

   :switch:`--eol={xxx}`
     Specifies the line-ending style of the reformatted output file. The
     ``xxx`` string specified with the switch may be:

     * *dos* - MS DOS style, lines end with CR LF characters*
     * *crlf*  - the same as *dos*
     * *unix* - UNIX style, lines end with LF character*
     * *lf* -  the same as *unix*

     The default is to use the same end-of-line convention as the input.

   .. index:: --wide-character-encoding (gnatpp)

   :switch:`--wide-character-encoding={e}, -W={e}`
     Specify the wide character encoding method for the input and output
     files. ``e`` is one of the following:

     * *8* - UTF-8 encoding

     * *b* - Brackets encoding (default value)

   You may only specify options :switch:`--output-file` and
   :switch:`--output-force` if the call to ``gnatpp`` contains only
   one file to reformat.

   You may not use the option :switch:`--eol` or
   :switch:`--wide-character-encoding` together with the
   :switch:`--pipe` option.


   .. _Other_gnatpp_Switches:

   Other ``gnatpp`` Switches
   ^^^^^^^^^^^^^^^^^^^^^^^^^

   You can also use the additional ``gnatpp`` switches defined in
   this subsection.


   .. index:: --version  (gnatpp)

   :switch:`--version`
     Display copyright and version, then exit, disregarding all other options.


   .. index:: --help  (gnatpp)

   :switch:`--help`
     Display usage, then exit, disregarding all other options.


   .. index:: -P  (gnatpp)

   :switch:`-P {file}`
     Specifies the name of the project file that describes the set of sources
     to be processed. The exact set of argument sources depends on other
     options specified; see below.


   .. index:: -U  (gnatpp)

   :switch:`-U`
     If you specify a project file but don't specify a source file,
     either directly or by means of a :switch:`--files` option,
     ``gnatpp`` processes all the units of the closure of the
     specified project. Otherwise this option has no effect.

   :switch:`-U {main_unit}`
     If you specify a project file but don't specify a source file,
     either directly or by means of :switch:`--files` option,
     ``gnatpp`` will process the closure of units rooted at
     ``main_unit``. Otherwise this option has no effect.


   .. index:: -X  (gnatpp)

   :switch:`-X{name}={value}`
     Indicates that external variable ``name`` in the specified project
     has the value ``value``. Has no effect if you don't specify a project.


   .. index:: --RTS (gnatpp)

   :switch:`--RTS={rts-path}`
     Specifies the default location of the runtime library. It has the
     same meaning as the equivalent ``gnatmake`` switch
     (:ref:`Switches_for_gnatmake`).


   .. index:: --incremental  (gnatpp)

   :switch:`--incremental`

     ``gnatpp`` will perform incremental processing on a per-file
     basis. It will only process a source file if it has been
     modified, or if files it depends on have been modified. This is
     similar to the way ``gnatmake``/``gprbuild`` only compiles files that
     need to be recompiled. You must specify a project file in this mode,
     and the gnat driver (as in *gnat pretty*) is not supported.
     (Note: this switch is not yet supported in the libadalang-based
     version of ``gnatpp``.)


   .. index:: --pp-off  (gnatpp)

   :switch:`--pp-off={xxx}`
     Use :switch:`--xxx` as the command to turn off pretty printing, instead
     of the default ``--!pp off``.


   .. index:: --pp-on  (gnatpp)

   :switch:`--pp-on={xxx}`
     Use :switch:`--xxx` as the command to turn pretty printing back on,
     instead of the default ``--!pp on``.


   .. index:: --files (gnatpp)

   :switch:`--files={filename}, -files={filename}`
     Take as arguments the files listed in text file ``file``, which
     may contain empty lines that are ignored.
     Each nonempty line should contain the name of an existing file.
     You may specify several such switches on the same command line.


   .. index:: --ignore (gnatpp)

   :switch:`--ignore={filename}`
     ``gnatpp`` will not process the sources listed in the specified file.
     You can't specify this option in incremental mode.


   .. index:: --jobs (gnatpp)

   :switch:`--jobs={n}, -j={n}`
     With :switch:`--incremental`, use *n* ``gnatpp`` processes to perform
     pretty printing in parallel. If *n* is 0, the maximum number
     processes is the number of core processors on the host.


   .. index:: --verbose (gnatpp)

   :switch:`--verbose, -v`
     Verbose mode


   .. index:: --quiet (gnatpp)

   :switch:`--quiet, -q`
     Quiet mode

   If you specify a project file, but no source files
   (either directly or by means of a :switch:`--files` option), and you
   specify the :switch:`-U`, then the set of processed sources is
   all the immediate units of the argument project.


   .. _Formatting_Rules:

   Formatting Rules
   ----------------

   The following subsections show how ``gnatpp`` treats comments,
   program layout, and name casing as well as how to disable ``gnatpp`` in
   source code regions.  They provide more details of the switches
   shown above.


   .. _Disabling_Pretty_Printing:

   Disabling Pretty Printing
   ^^^^^^^^^^^^^^^^^^^^^^^^^

   Pretty printing is highly heuristic in nature and sometimes doesn't
   do exactly what you want. If you want to format a certain region of
   code by hand, you can turn off pretty printing in that region by
   surrounding it with special comments that start with ``--!pp off``
   and ``--!pp on``. The text in that region is reproduced
   verbatim in the output with no formatting.

   To disable pretty printing for an entire file, put ``--!pp off`` at
   the top, with no following ``--!pp on``.

   You must place each of these comments on a line by themselves, with nothing
   preceding except spaces. You must have the initial text of the comment be
   exactly ``--!pp off`` or ``--!pp on`` (case sensitive), but you may
   follow it by arbitrary additional text. For example:

     .. code-block:: ada

        package Interrupts is
           --!pp off -- turn off pretty printing so "Interrupt_Kind" lines up
           type            Interrupt_Kind is
             (Asynchronous_Interrupt_Kind,
               Synchronous_Interrupt_Kind,
                     Green_Interrupt_Kind);
           --!pp on -- reenable pretty printing
           ...

   You can specify different comment strings using the :switch:`--pp-off`
   and :switch:`--pp-on` switches. For example, if you say:

     ::

        $ gnatpp --pp-off=' pp-' *.ad?

   ``gnatpp`` will recognize comments of the form ``-- pp-`` instead
   of ``--!pp off`` for disabling pretty printing. Note that you do
   not include the leading ``--`` of the comment in the argument to
   these switches.


   .. _Formatting_Comments:

   Formatting Comments
   ^^^^^^^^^^^^^^^^^^^

   Only :switch:`--layout=compact` and :switch:`--layout=tall` format comments.

   Comments in Ada code are of two kinds:

   * *whole-line comments*, which appear by themselves (possibly preceded by
     white space) on a line

   * *end-of-line comments*, which follows some other Ada code on
     the same line.

   ``gnatpp`` indents whole-line comment according to the surrounding code,
   with some exceptions. Comments that start in column 1 are kept
   there. If possible, comments are not moved so far to the right that
   the maximum line length is exceeded. Special-form comments such as
   SPARK-style ``--#...`` are left alone.

   For an end-of-line comment, ``gnatpp`` tries to leave the same
   number of spaces between the end of the preceding Ada code and the
   beginning of the comment, as it appears in the original source.

   For each whole-line comment that does not end with two hyphens or that are
   not special-form comments, ``gnatpp`` inserts spaces if necessary after the
   starting two hyphens to ensure that there are at least two spaces between
   these hyphens and the first non-blank character of the comment.

   With :switch:`--layout=compact`, ``gnatpp`` fills in whole-line
   comments that form a paragraph in typical word processor style
   (that is, moving words between lines to make the lines other than
   the last similar in length).


   .. _Name_Casing:

   Name Casing
   ^^^^^^^^^^^

   ``gnatpp`` always converts the usage occurrence of a (simple) name to
   the same casing as the corresponding defining identifier.

   You control the casing for defining occurrences via the :switch:`--name...`
   switches. With :switch:`--name-case-as-declared`, which is the default,
   defining occurrences appear exactly as in the source file where they
   are declared. The other values for this switch --
   :switch:`--name-upper-case`, :switch:`--name-lower-case`, and
   :switch:`--name-mixed-case`
   -- result in upper, lower, or mixed case, respectively. If
   ``gnatpp`` changes the casing of a defining occurrence, it
   similarly changes the casing of all the usage occurrences of this
   name.

   If the defining occurrence of a name is not in the source
   compilation unit currently being processed by ``gnatpp``,
   ``gnatpp`` changes the casing of each reference to this name
   according to the switch (subject to the dictionary file mechanism
   described below). Thus ``gnatpp`` acts as though the switch had
   affected the casing for the defining occurrence of the name.

   The options
   :switch:`--attribute...`,
   :switch:`--keyword...`,
   :switch:`--enum...`,
   :switch:`--type...`,
   :switch:`--number...`, and
   :switch:`--pragma...`
   allow finer-grained control over casing for
   attributes, keywords, enumeration literals,
   types, named numbers and pragmas, respectively.
   :switch:`--type...` cover subtypes as well.

   You may need some names to be spelled with casing conventions that
   are not covered by the upper-, lower-, and mixed-case
   transformations.  You can have ``gnatpp`` produce the correct
   casing by placing such names in a *dictionary file*, and
   specifying a :switch:`--dictionary` switch.  Specifying any
   dictionary files overrides any :switch:`--name...` switch.

   ``gnatpp`` uses a default dictionary file to choose the casing of
   Ada predefined names and the names from GNAT libraries,
   
   Each predefined entity is converted to the same casing as
   the entity in the :title:`Ada Reference Manual` (usually
   mixed case) and each entity in the GNAT libraries is cased
   the same as its declaration in the library.

   You can specify the :switch:`--dictionary=-` switch to suppress
   the use of the default dictionary file. Instead, the casing for
   predefined and GNAT-defined names is given by the :switch:`-n`
   switch or explicit dictionary files. For example, by default the
   names ``Ada.Text_IO`` and ``GNAT.OS_Lib`` appear as just shown,
   even in the presence of a :switch:`--name-upper-case` switch. To
   ensure that even such names are rendered in uppercase, you must
   specify the :switch:`--dictionary=-` switch or place these names
   in upper case in a dictionary file.

   A dictionary file is a plain text file; each line in this file is
   either a blank line (containing only space characters), an Ada comment
   line, or the specification of exactly one *casing schema*.

   A casing schema is a string with the following syntax:

     ::

        casing_schema ::= identifier | simple_identifier

        simple_identifier ::= letter{letter_or_digit}


   (See :title:`Ada Reference Manual`, Section 2.3) for the definition of the
   ``identifier`` lexical element and the ``letter_or_digit`` category.)

   You can follow a casing schema string by white space and/or an Ada-style
   comment. You can also have any amount of white space before the string.

   If you pass a dictionary file as the value of a
   :switch:`--dictionary={file}` switch, ``gnatpp`` checks every
   simple name and identifier to see if the dictionary defines
   the casing for the name or for some of its parts (the term
   'subword' is used below to denote the part of a name that is
   delimited by '_' or by the beginning or end of the word that
   doesn't contain any '_' characters):

   * if the complete name is in the dictionary, ``gnatpp`` uses the
     casing defined by the dictionary for this name; it does not check
     any subwords

   * for every subword, ``gnatpp`` checks if the dictionary contains
     the corresponding string of the form ``simple_identifier``, and
     if it does, the casing of this ``simple_identifier`` is used for
     this subword

   * if the complete name does not contain any '_' characters and if
     for this name the dictionary contains two entries -- one of the
     form ``identifier``, and another of the form
     ``simple_identifier`` -- ``gnatpp`` uses the first one to obtain
     the casing of this name

   * if you pass more than one dictionary file as ``gnatpp`` switches,
     each dictionary adds new casing exceptions and overrides all the
     existing casing exceptions set by the previous dictionaries

   * when ``gnatpp`` checks if the word or subword is in the dictionary,
     it uses a check that's not case sensitive

   For example, suppose we have the following source to reformat:

     .. code-block:: ada

        procedure test is
           name1 : integer := 1;
           name4_name3_name2 : integer := 2;
           name2_name3_name4 : Boolean;
           name1_var : Float;
        begin
           name2_name3_name4 := name4_name3_name2 > name1;
        end;

   And suppose we have two dictionaries:

     ::

        *dict1:*
           NAME1
           *NaMe3*
           *Name1*

        *dict2:*
          *NAME3*

   If ``gnatpp`` is called with the following switches:

     ::

        $ gnatpp --name-mixed-case --dictionary=dict1 --dictionary=dict2 test.adb

   then we get the following name casing in the ``gnatpp`` output:


     .. code-block:: ada

        procedure Test is
           NAME1             : Integer := 1;
           Name4_NAME3_Name2 : Integer := 2;
           Name2_NAME3_Name4 : Boolean;
           Name1_Var         : Float;
        begin
           Name2_NAME3_Name4 := Name4_NAME3_Name2 > NAME1;
        end Test;

   .. _Preprocessor_directives:

   Preprocessor Directives
   ^^^^^^^^^^^^^^^^^^^^^^^

   ``gnatpp`` has some support for preprocessor directives.
   You can use preprocessor symbols such as ``$symbol``.
   In addition, you can use conditional compilation as
   long as the program text is syntactically legal Ada code
   after removing all the preprocessor directives (lines starting
   with ``#``). For example, ``gnatpp`` can format the following:

     .. code-block:: ada

        package P is
        #IF SOMETHING
           X : constant Integer := 123;
        #ELSE
           X : constant Integer := 456;
        #END IF;
        end P;

   which will be formatted as if it were:

     .. code-block:: ada

        package P is
           X : constant Integer := 123;
           X : constant Integer := 456;
        end P;

   except that the ``#`` lines will be preserved.
   However, ``gnatpp`` cannot format the following:

     .. code-block:: ada

        procedure P is
        begin
        #IF SOMETHING
           if X = 0 then
        #ELSE
           if X = 1 then
        #END IF;
              null;
           end if;
        end P;

   because removing the ``#`` lines gives:

     .. code-block:: ada

        procedure P is
        begin
           if X = 0 then
           if X = 1 then
              null;
           end if;
        end P;

   which is not syntactically legal.

   Legacy Switches
   ^^^^^^^^^^^^^^^

   .. index:: --alignment (gnatpp)

   :switch:`--alignment, --no-alignment`
      Programs can be easier to read if certain constructs are vertically
      aligned.

        * ``:`` in declarations,
        * ``:=`` in initializations in declarations,
        * ``:=`` in assignment statements,
        * ``=>`` in associations, and
        * ``at`` keywords in the component clauses in record representation
          clauses.

   .. index:: --align-modes (gnatpp)

   :switch:`--align-modes, --no-align-modes`

      Line up ``in`` and ``out`` in parameter specifications.

   .. index:: --compact (gnatpp)

   :switch:`--compact, --no-compact`
     In calls and similar constructs, :switch:`--compact` packs as many
     subexpressions into the same line as is possible. Example:

     .. code-block:: ada

        Some_Procedure
          (Short_One, Another_Short_One,
           A_Very_Very_Very_Very_Very_Very_Very_Very_Long_One);

     On the other hand, if you specify :switch:`--no-compact`,
     ``gnatpp`` places all such subexpressions on separate lines if
     it's necessary to split a line between two subexpressions to
     avoid the construct exceeding :switch:`--max-line-length`. For
     example:

     .. code-block:: ada

        Some_Procedure
          (Short_One,
           Another_Short_One,
           A_Very_Very_Very_Very_Very_Very_Very_Very_Long_One);

   .. index:: --end-id (gnatpp)

   :switch:`--end-id, --no-end-id`
     Insert the name of a unit after ``end``. Otherwise, leave whatever comes
     after ``end``, if anything, alone.

   .. index:: --separate-is (gnatpp)

   :switch:`--separate-is, --no-separate-is`
     Place the keyword ``is`` on a separate line in a subprogram body in
     case if the spec occupies more than one line.

   .. index:: --separate-return (gnatpp)

   :switch:`--separate-return, --no-separate-return`
     If a subprogram spec does not fit on one line, place the ``return`` on
     a separate line. Otherwise try to place it in the same line as the last
     parameter specification.

   .. index:: --separate-loop (gnatpp)

   :switch:`--separate-loop, --no-separate-loop`
     Place the keyword ``loop`` in FOR and WHILE loop statements
     on a separate line.


   .. index:: --separate-then (gnatpp)

   :switch:`--separate-then, --no-separate-then`
     Place the keyword ``then`` in IF statements
     on a separate line.

   .. index:: --separate-loop-then (gnatpp)

   :switch:`--separate-loop-then, --no-separate-loop-then`
     Equivalent to :switch:`--separate-loop` :switch:`--separate-then`.

   .. index:: --split-line-before-record (gnatpp)

   :switch:`--split-line-before-record, --no-split-line-before-record`
     Split the line just before ``record`` in a record type declaration.

   .. index:: --indent-named-statements (gnatpp)

   :switch:`--indent-named-statements, --no-indent-named-statements`
     Indent block and loop statements with respect to the name.

   .. index:: --split-line-before-op (gnatpp)

   :switch:`--split-line-before-op, --no-split-line-before-op` If it
     is necessary to split a line at a binary operator, by default the
     line is split after the operator. When you specify this switch,
     it is split before the operator.

   .. index:: --use-on-new-line (gnatpp)

   :switch:`--use-on-new-line, --no-use-one-new-line`
     Start each USE clause in a context clause from a separate line.

   .. index:: --vertical-enum-types (gnatpp)

   :switch:`--vertical-enum-types, --no-vertical-enum-types`
     Format enumeration type declarations "vertically", e.g. each
     enumeration literal goes on a separate line.

   .. index:: --vertical-array-types (gnatpp)

   :switch:`--vertical-array-types, --no-vertical-array-types`
     Format array type declarations "vertically", e.g. for
     multidimensional arrays, each index_subtype_definition or
     discrete_subtype_definition goes on a separate line.

   .. index:: --vertical-named-aggregates (gnatpp)

   :switch:`--vertical-named-aggregates, --no-vertical-named-aggregates`
     Format aggregates "vertically" if named notation is used for all
     component_associations, e.g. each component_association
     goes on a separate line.

   .. index:: --vertical-case-alternatives (gnatpp)

   :switch:`--vertical-case-alternatives, --no-vertical-case-alternatives`
     Format case statements, case expressions, and variant parts with
     additional line breaks.

   .. index:: --RM-style-spacing (gnatpp)

   :switch:`--RM-style-spacing`
     Do not insert an extra blank before various occurrences of
     '(' and ':'. Alignment is off by default in this mode;
     use :switch:`--alignment` to turn it on.

   .. index:: --insert-blank-lines (gnatpp)

   :switch:`--insert-blank-lines, --no-insert-blank-lines`
     Insert blank lines where appropriate (between bodies and other large
     constructs).

   .. index:: --preserve-blank-lines (gnatpp)

   :switch:`--preserve-blank-lines, --no-preserve-blank-lines`
     Preserve blank lines in the input. By default, gnatpp will squeeze
     multiple blank lines down to one.

   .. index:: --preserve-line-breaks (gnatpp)

   :switch:`--preserve-line-breaks, --no-preserve-line-breaks`
     Preserve line breaks in the input, to the extent possible.
     By default, line breaks are also inserted at appropriate
     places.

   .. index:: --source-line-breaks (gnatpp)

   :switch:`--source-line-breaks, --no-source-line-breaks`
     Keep the line breaks from the source; do not insert or delete any
     line breaks.

   .. index:: --spaces-only (gnatpp)

   :switch:`--spaces-only, --no-spaces-only`
     Disable all formatting except for inserting and removing spaces.
     This implies --source-line-breaks.

   .. index:: -c (gnatpp)

   :switch:`--comments-unchanged, -c0`
     All comments remain unchanged.

   :switch:`--comments-gnat-indentation, -c1`
     GNAT-style comment line indentation.

   :switch:`--comments-gnat-beginning, -c3`
     GNAT-style comment beginning.

   :switch:`--comments-fill, -c4`
     Fill comment blocks.

   :switch:`--comments-special, -c5`
     Keep unchanged special form comments.

   :switch:`--comments-only`
     Format just the comments.


.. only:: PRO or GPL

  .. _The_Body_Stub_Generator_gnatstub:

  The Body Stub Generator ``gnatstub``
  ====================================

  .. index:: ! gnatstub

  ``gnatstub`` creates empty but compilable bodies
  for library unit declarations and empty but compilable
  subunits for body stubs.

  ``gnatstub`` is a project-aware tool.
  (See :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
  the project-related switches but note that ``gnatstub`` does not support
  the :switch:`-U`, :switch:`-U {main_unit}`, :switch:`--subdirs={dir}`, or
  :switch:`--no-objects-dir` switches.)
  The project file package that can specify
  ``gnatstub`` switches is named ``gnatstub``.


  By default, all program unit bodies generated by ``gnatstub``
  raise ``Program_Error``, which will catch accidental calls of
  generated stubs. You can change this behavior with switch
  :switch:`--no-exception` (see below).

  .. _Running_gnatstub:

  Running ``gnatstub``
  --------------------

  You invoke ``gnatstub`` like this:

    ::

       $ gnatstub [ switches ] {filename}

  where

  * *filename* is the name of the source file that contains a library
      unit declaration for which you want a body to be created or a
      library unit body for which you want subunits to be created for
      the body stubs declared in this body.  The file name may contain
      path information.  If the name does not follow GNAT file naming
      conventions and the set of switches does not contain a project
      file that defines naming conventions, you must explicitly
      provide the name of the body file as the value of the
      :switch:`--output={body-name}` switch.  If the file name follows
      the GNAT file naming conventions and you do not provide the name
      of the body file ``gnatstub`` uses the naming conventions for
      the generated source from the project file provided as a
      parameter of a :switch:`-P` switch if any, or creates the name file
      using the standard GNAT naming conventions.

      Note that you no longer need to specify the Ada language version;
      ``gnatstub`` can process Ada source code written in any version from
      Ada 83 onward without specifying any language version switch.

  * *switches*
      is an optional sequence of switches as described in the next section


  .. _Switches_for_gnatstub:

  Switches for ``gnatstub``
  -------------------------

  .. index:: --version (gnatstub)

  :switch:`--version`
    Display copyright and version, then exit, disregarding all other options.


  .. index:: --help (gnatstub)

  :switch:`--help`
    Display usage, then exit, disregarding all other options.


  .. index:: -P (gnatstub)

  :switch:`-P {file}`
    Indicates the name of the project file that describes the set of
    sources to be processed. You can specify an aggregate project as
    the file parameter only if it has exactly one non-aggregate
    project being aggregated.


  .. index:: -X (gnatstub)

  :switch:`-X{name}={value}`
    Indicates that external variable ``name`` in the argument project
    has the value ``value``. Has no effect if no project is specified.


  .. index:: --RTS (gnatstub)

  :switch:`--RTS={rts-path}`
    Specifies the default location of the runtime library. It has the
    same meaning as the equivalent ``gnatmake`` flag
    (:ref:`Switches_for_gnatmake`).


  .. index:: --subunits (gnatstub)

  :switch:`--subunits`
    Generate subunits for body stubs. If you specify this switch,
    ``gnatstub`` expects a library unit body as an argument file;
    otherwise a library unit declaration is expected. If a body stub
    already has a corresponding subunit, ``gnatstub`` does not
    generate anything for it.


  .. index:: --force (gnatstub)

  :switch:`--force`
    If the destination directory already contains a file with the name of the
    body file
    for the argument spec file, replace it with the generated body stub.
    This switch cannot be used together with :switch:`--subunits`.


  .. index:: --comment-header-spec (gnatstub)

  :switch:`--comment-header-spec`
    Put the comment header (i.e., all the comments preceding the
    compilation unit) from the source of the library unit declaration
    into the body stub.


  .. index:: --comment-header-sample (gnatstub)

  :switch:`--comment-header-sample`
    Put a sample comment header into the body stub.


  .. index:: --header-file (gnatstub)

  :switch:`--header-file={filename}`
    Use the content of the file as the comment header for a generated body stub.


  .. index:: --max-line-length (gnatstub)

  :switch:`--max-line-length={n}`
    (``n`` is a non-negative integer). Set the maximum line length for
    the output files. The default is 79. The maximum value that you can
    specify is 32767.


  .. index:: --indentation (gnatstub)

  :switch:`--indentation={n}`
    (``n`` is an integer from 1 to 9). Set the indentation level in
    the generated files to ``n``.
    The default indentation is 3.


  .. index:: --alphabetical-order (gnatstub)

  :switch:`--alphabetical-order`
    Order local bodies alphabetically. By default local bodies are ordered
    in the same way as the corresponding local specs in the argument
    spec file.


  .. index:: --no-exception (gnatstub)

  :switch:`--no-exception`
    Avoid raising Program_Error in the generated bodies of program unit stubs,
    except in the case of functions, where there will be value to return.


  .. index:: --no-local-header (gnatstub)

  :switch:`--no-local-header`
    Do not place a local comment header with unit name before body stub for a
    unit.


  .. index:: --files (gnatstub)

  :switch:`--files={filename}`
    Take as arguments the files listed in text file ``file``, which
    may contain empty lines that are ignored.
    You should specify the name of an existing file in each non-empty line.
    You may specify multiple :switch:`--files=` switches.


  .. index:: --output (gnatstub)

  :switch:`--output={body-name}` Body file name. You should set this
    if the argument file name does not follow the default GNAT file
    naming conventions and the naming conventions are not specified by
    a project file. If you omit both this switch and :switch:`-P`,
    ``gnatpp`` will choose the name for the body according to the
    default GNAT file naming conventions.


  .. index:: --output-dir (gnatstub)

  :switch:`--output-dir={dir-name}` The directory in which to place
    the output files.  If you do not specify this switch, ``gnatpp``
    places the generated library unit body in the current directory
    and generated sununits in the directory where the argument body is
    located.


  .. index:: --wide-character-encoding (gnatstub)

  :switch:`--wide-character-encoding={e}`
    Specify the wide character encoding method for the input and output
    files. ``e`` is one of the following:

    * *8* - UTF-8 encoding

    * *b* - Brackets encoding (default value)


  .. index:: --quiet (gnatstub)
  .. index:: -q (gnatstub)

  :switch:`--quiet` / :switch:`-q`
    Quiet mode.


  .. index:: --verbose (gnatstub)
  .. index:: -v (gnatstub)

  :switch:`--verbose` / :switch:`-v`
    Verbose mode.

  Legacy Switches
  ^^^^^^^^^^^^^^^

  Some switches have a short form, mostly for legacy reasons,
  as shown below.

  .. index:: -M (gnatstub)

  :switch:`-gnatyM{nnn}`
    :switch:`--max-line-length={nnn}`

  .. index:: -i (gnatstub)

  :switch:`-i{nnn}`
    :switch:`--indentation={nnn}`

  .. index:: -gnaty (gnatstub)

  :switch:`-gnaty{nnn}`
    :switch:`--indentation={nnn}`

  .. index:: -f (gnatstub)

  :switch:`-f`
    :switch:`--force`

  .. index:: -gnatyo (gnatstub)

  :switch:`-gnatyo`
    :switch:`--alphabetical-order`

  .. index:: -hg (gnatstub)

  :switch:`-hg`
    :switch:`--comment-header-sample`

  .. index:: -hs (gnatstub)

  :switch:`-hs`
    :switch:`--comment-header-spec`

  .. index:: -o (gnatstub)

  :switch:`-o {output-file}`
    :switch:`--output={output-file}`

  .. index:: -dir (gnatstub)

  :switch:`-dir {dir-name}`
    :switch:`--output-dir={dir-name}`

  .. index:: -W (gnatstub)

  :switch:`-W{e}`
    :switch:`--wide-character-encoding={e}`

  .. index:: -files (gnatstub)

  :switch:`-files {filename}`
    :switch:`--files={filename}`


.. only:: PRO or GPL

  .. _The_Backtrace_Symbolizer_gnatsymbolize:

  Translating Code Addresses into Source Locations with ``gnatsymbolize``
  =======================================================================

  .. index:: ! gnatsymbolize

  ``gnatsymbolize`` is a program which translates addresses into
  their corresponding filename, line number, and function names.

  Running ``gnatsymbolize``
  -------------------------

  ::

       $ gnatsymbolize [ switches ] filename [ addresses ]

  For example, consider the following Ada program:

     .. code-block:: ada

        package Pck is
           Global_Val : Integer := 0;
           procedure Call_Me_First;
        end Pck;

        with GNAT.IO; use GNAT.IO;
        with GNAT.Traceback; use GNAT.Traceback;
        with GNAT.Debug_Utilities;

        package body Pck is
           procedure Call_Me_Third is
              TB : Tracebacks_Array (1 .. 5);
              TB_len : Natural;
           begin
              Global_Val := Global_Val + 1;

              Call_Chain (TB, TB_Len);
              for K in 1 .. TB_Len loop
                 Put_Line (GNAT.Debug_Utilities.Image_C (TB (K)));
              end loop;
           end Call_Me_Third;

           procedure Call_Me_Second is
           begin
              Call_Me_Third;
           end Call_Me_Second;

           procedure Call_Me_First is
           begin
              Call_Me_Second;
           end Call_Me_First;
        end Pck;

        with GNAT.IO; use GNAT.IO;
        with GNAT.Debug_Utilities;
        with GNAT.Traceback;
        with System;

        with Pck; use Pck;

        procedure Foo is
           LA : constant System.Address := \
             GNAT.Traceback.Executable_Load_Address;

           use type System.Address;

        begin
           if LA /= System.Null_Address then
              Put_Line ("Load address: " & GNAT.Debug_Utilities.Image_C (LA));
           end if;

           Global_Val := 123;
           Call_Me_First;
        end Foo;

  This program, when built and run, prints a list of addresses which
  correspond to the traceback when inside function ``Call_Me_Third``.
  For example, on x86-64 GNU/Linux:

    ::

       $ gnatmake -g -q foo.adb
       $ ./foo
       Load address: 0x00005586C9D7D000
       0x00005586C9D81105
       0x00005586C9D8119B
       0x00005586C9D811A7
       0x00005586C9D8128C
       0x00005586C9D81069

  You can use ``gnatsymbolize``  to translate those addresses into
  code locations as follows:

    ::

       $ gnatsymbolize --load foo 0x00005586C9D7D000 0x00005586C9D81105 \
           0x00005586C9D8119B 0x00005586C9D811A7 0x00005586C9D8128C \
           0x00005586C9D81069
       0x5586c9d81105 Pck.Call_Me_Third at pck.adb:12
       0x5586c9d8119b Pck.Call_Me_Second at pck.adb:20
       0x5586c9d811a7 Pck.Call_Me_First at pck.adb:25
       0x5586c9d8128c Foo at foo.adb:6
       0x5586c9d81069 Main at b~foo.adb:199

  Switches for ``gnatsymbolize``
  ------------------------------

  You can specify the following switches for ``gnatsymbolize``:

  .. index:: --help (gnatsymbolize)

  :switch:`--help`
    Display the program's usage, and then exit, disregarding all other
    options.

  :switch:`--cache`
    Read the symbolic information from the executable and cache them
    in memory to accelerate the translation of each address
    into a symbolic location.

    Depending on the size of the executable and the number of addresses
    to translate, this may not always make ``gnatsymbolize`` faster
    overall.

  :switch:`--dump`
    If you have specified :switch:`--cache`, dump the contents of the cache to
    Standard Output. Has no effect otherwise.

  :switch:`--count={N}`
    Compute the symbolic traceback ``N`` times in a row. You use this switch
    mostly for measuring the performance of ``gnatsymbolize``,
    particularly in the case where you have specified the cache to be used.

  :switch:`--load`
    Interpret the first address as the load address of the executable.
    This is needed for position-independent executables on Linux and Windows.

  Requirements for Correct Operation
  ----------------------------------

  The translation is performed by reading the DWARF debugging
  information produced by the compiler for each unit. You must
  therefore compile all units for which the translation is to be done
  in a way that DWARF debugging information is produced. In most cases,
  you do this by simply compiling with :switch:`-g`.

  This program provides a functionality similar to ``addr2line``.
  It has fewer options to tailor its output, but has been designed
  to require fewer DWARF sections to be present in the
  executable. In particular, it works for code compiled with ``-g1``.


.. only:: PRO or GPL

   .. _Using_Project_Files_with_GNAT_Tools:

   Using Project Files with GNAT Tools
   ===================================

   This section describes how you can use project files in conjunction
   with a number of GNAT tools.
   For a comprehensive description of project files and the overall
   GNAT Project Manager facility, please refer to the
   *GNAT Project Manager* chapter in the
   *GPRbuild and GPR Companion Tools User's Guide*.

   .. index:: Project-aware tool

   If a tool can take a project file as an option and extract the needed
   information, such a tool is called a *project-aware* tool.

   .. _Switches_Related_to_Project_Files:

   Switches Related to Project Files
   ---------------------------------

   The following switches are used by the project-aware GNAT tools:

   :switch:`-P{project_file}`
      Indicates the name of the project file whose source files are to
      be processed. The exact set of sources depends on other options
      specified, see below.

   :switch:`-U`
      If you supply a project file, say for project ``proj``,
      but you don't specify any sources for ``proj`` (either by a
      project attribute or through a tool option that provides a list
      of the files to be used), process all the source files
      from projects imported either directly or indirectly by ``proj``.
      Otherwise this option has no effect.

   :switch:`-U {source_file}`
      Similar to :switch:`-U`, but if you don't specify any sources,
      process only those source files for units in the closure of
      the Ada source contained in ``source_file``. Note that this option
      expects the source file name, not the Ada unit name, as its
      parameter.

   :switch:`-X{name}={val}`
      Indicates that the external variable ``name`` in the project has the
      value ``val``. Has no effect if no project has been specified.

   :switch:`--subdirs={dir}`
      Use the ``dir`` subdirectory of the project's object directory
      (or the ``dir`` subdirectory of the project file directory if
      the project does not specify an object directory) for tool
      output files. Has no effect if you haven't specified a project
      and if you haven't specified the if :switch:`--no-objects-dir`
      switch.

   :switch:`--no-objects-dir`
      Place all the result files into the current directory (i.e., the
      directory from which the tool invocation command is issued)
      instead of the project's object directory. Has no effect if you
      haven't specified a project.

   :switch:`-eL`
      Follow all symbolic links when processing project files.

   If you specify a project file but neither a :switch:`-U` option,
   nor a :switch:`-U {main_unit}` option, nor any other explicit option to
   specify the source files, then the sources to be processed are the
   immediate sources of the specified project (i.e., the source files directly
   defined by that project, either implicitly by residing in the project
   source directories or explicitly through any of the source-related
   attributes).

   .. _Tool-specific_packages_in_project files:

   Tool-specific packages in project files
   ---------------------------------------

   Each project-aware tool may have a corresponding package in a project file;
   the package names are given elsewhere in this manual, in the sections that describe
   the respective tools.

   A tool-specific package in a project file may define the
   ``Default_Switches`` attribute indexed by "ada" (as language
   name). You set the value of this attribute to a list of switches
   that you want the tool to use when it's invoked.  You cannot
   specify project-specific switches through this attribute.

---

### Gcc Ada Doc Gnat Ugn Inline Assembler (`gcc/ada/doc/gnat_ugn/inline_assembler.rst`)

.. role:: switch(samp)

.. _Inline_Assembler:

****************
Inline Assembler
****************

.. index:: Inline Assembler

If you need to write low-level software that interacts directly
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
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
Inline Assembler.  The Inline Assembler approach offers a number of advantages,
including the following:

* No need to use non-Ada tools
* Consistent interface over different targets
* Automatic usage of the proper calling conventions
* Access to Ada constants and variables
* Definition of intrinsic routines
* 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 you are familiar with both Ada
and assembly language programming.

.. _Basic_Assembler_Syntax:

Basic Assembler Syntax
======================

The assembler used by GNAT and gcc is based not on the Intel assembly
language, but rather on a language that descends from the AT&T Unix
assembler ``as`` (and which is often referred to as 'AT&T syntax').
The following table summarizes the main features of ``as`` syntax
and points out the differences from the Intel conventions.
See the gcc ``as`` and ``gas`` (an ``as`` macro
pre-processor) documentation for further information.


| *Register names*
|   gcc / ``as``: Prefix with '%'; for example ``%eax``
|   Intel: No extra punctuation; for example ``eax``


| *Immediate operand*
|   gcc / ``as``: Prefix with '$'; for example ``$4``
|   Intel: No extra punctuation; for example ``4``


| *Address*
|   gcc / ``as``: Prefix with '$'; for example ``$loc``
|   Intel: No extra punctuation; for example ``loc``


| *Memory contents*
|   gcc / ``as``: No extra punctuation; for example ``loc``
|   Intel: Square brackets; for example ``[loc]``


| *Register contents*
|   gcc / ``as``: Parentheses; for example ``(%eax)``
|   Intel: Square brackets; for example ``[eax]``


| *Hexadecimal numbers*
|   gcc / ``as``: Leading '0x' (C language syntax); for example ``0xA0``
|   Intel: Trailing 'h'; for example ``A0h``


| *Operand size*
|   gcc / ``as``: Explicit in op code; for example ``movw`` to move a 16-bit word
|   Intel: Implicit, deduced by assembler; for example ``mov``


| *Instruction repetition*
|   gcc / ``as``: Split into two lines; for example
|     ``rep``
|     ``stosl``
|   Intel: Keep on one line; for example ``rep stosl``


| *Order of operands*
|   gcc / ``as``: Source first; for example ``movw $4, %eax``
|   Intel: Destination first; for example ``mov eax, 4``


.. _A_Simple_Example_of_Inline_Assembler:

A Simple Example of Inline Assembler
====================================

The following example generate a single assembly language statement,
``nop``, which does nothing.  Despite its lack of run-time effect,
the example is useful in illustrating the basics of
the Inline Assembler facility.

  .. code-block:: ada

     with System.Machine_Code; use System.Machine_Code;
     procedure Nothing is
     begin
        Asm ("nop");
     end Nothing;

``Asm`` is a procedure declared in package ``System.Machine_Code``;
here it takes one parameter, a *template string* that must be a static
expression that produces the generated instruction.
``Asm`` may be regarded as a compile-time procedure that parses
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, you should put the ``Nothing`` procedure
in a file named :file:`nothing.adb`.
You can build the executable in the usual way:

  ::

     $ gnatmake nothing

However, the interesting aspect of this example is not its run-time behavior
but rather the generated assembly code.
To see this output, invoke the compiler as follows:

  ::

     $ gcc -c -S -fomit-frame-pointer -gnatp nothing.adb

where the options are:

* :switch:`-c`
    compile only (no bind or link)

* :switch:`-S`
    generate assembler listing

* :switch:`-fomit-frame-pointer`
    do not set up separate stack frames

* :switch:`-gnatp`
    do not add runtime checks

This gives a human-readable assembler version of the code. The resulting
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:

  ::

     .file "nothing.adb"
     gcc2_compiled.:
     ___gnu_compiled_ada:
     .text
        .align 4
     .globl __ada_nothing
     __ada_nothing:
     #APP
        nop
     #NO_APP
        jmp L1
        .align 2,0x90
     L1:
        ret

The assembly code you included is clearly indicated by
the compiler, between the ``#APP`` and ``#NO_APP``
delimiters. The character before the 'APP' and 'NOAPP'
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 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.

Assembling the file using the command

  ::

     $ as nothing.s

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`` generates an object file called
:file:`nothing.out`.


.. _Output_Variables_in_Inline_Assembler:

Output Variables in Inline Assembler
====================================

The examples in this section, showing how to access the processor flags,
illustrate how to specify the destination operands for assembly language
statements.


  .. code-block:: ada

     with Interfaces; use Interfaces;
     with Ada.Text_IO; use Ada.Text_IO;
     with System.Machine_Code; use System.Machine_Code;
     procedure Get_Flags is
        Flags : Unsigned_32;
        use ASCII;
     begin
        Asm ("pushfl"          & LF & HT & -- push flags on stack
             "popl %%eax"      & LF & HT & -- load eax with flags
             "movl %%eax, %0",             -- store flags in variable
             Outputs => Unsigned_32'Asm_Output ("=g", Flags));
        Put_Line ("Flags register:" & Flags'Img);
     end Get_Flags;

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:

  ::

     #APP
        pushfl
        popl %eax
        movl %eax, -40(%ebp)
     #NO_APP

It would have been legal to write the Asm invocation as:

  .. code-block:: ada

     Asm ("pushfl popl %%eax movl %%eax, %0")

but in the generated assembler file, this would come out as:

  ::

     #APP
        pushfl popl %eax movl %eax, -40(%ebp)
     #NO_APP

which is not so convenient for the human reader.

We use Ada comments
at the end of each line to explain what the assembler instructions
actually do.  This is a useful convention.

When writing Inline Assembler instructions, you need to precede each register
and variable name with a percent sign.  Since the assembler already requires
a percent sign at the beginning of a register name, you need two consecutive
percent signs for such names in the Asm template string, thus ``%%eax``.
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 shown in
the third section of the Asm template string:

  ::

     movl %%eax, %0

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``:

  .. code-block:: ada

     Outputs => Unsigned_32'Asm_Output ("=g", Flags));

The output is defined by the ``Asm_Output`` attribute of the target type;
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:

  .. code-block:: ada

     Unsigned_32'Asm_Output ("=m", Flags);

the ``"m"`` (memory) constraint tells the compiler that the variable
``Flags`` should be stored in a memory variable, thus preventing
the optimizer from keeping it in a register.  In contrast,

  .. code-block:: ada

     Unsigned_32'Asm_Output ("=r", Flags);

uses the ``"r"`` (register) constraint, telling the compiler to
store the variable in a register.

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 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:

 ====== ==========================================
 *=*    output constraint
 *g*    global (i.e., can be stored anywhere)
 *m*    in memory
 *I*    a constant
 *a*    use eax
 *b*    use ebx
 *c*    use ecx
 *d*    use edx
 *S*    use esi
 *D*    use edi
 *r*    use one of eax, ebx, ecx or edx
 *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 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
integer.  Thus in

  .. code-block:: ada

     Asm ("pushfl"          & LF & HT & -- push flags on stack
          "popl %%eax"      & LF & HT & -- load eax with flags
          "movl %%eax, %0",             -- store flags in variable
          Outputs => Unsigned_32'Asm_Output ("=g", Flags));


``%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:

* Count the operands starting at 0; thus ``%0``, ``%1``, etc.

* Specify the ``Outputs`` parameter as a parenthesized comma-separated list
  of ``Asm_Output`` attributes

For example:

  .. code-block:: ada

     Asm ("movl %%eax, %0" & LF & HT &
          "movl %%ebx, %1" & LF & HT &
          "movl %%ecx, %2",
          Outputs => (Unsigned_32'Asm_Output ("=g", Var_A),   --  %0 = Var_A
                      Unsigned_32'Asm_Output ("=g", Var_B),   --  %1 = Var_B
                      Unsigned_32'Asm_Output ("=g", Var_C))); --  %2 = Var_C

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 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:

  .. code-block:: ada

     with Interfaces; use Interfaces;
     with Ada.Text_IO; use Ada.Text_IO;
     with System.Machine_Code; use System.Machine_Code;
     procedure Get_Flags_2 is
        Flags : Unsigned_32;
        use ASCII;
     begin
        Asm ("pushfl"      & LF & HT & -- push flags on stack
             "popl %%eax",             -- save flags in eax
             Outputs => Unsigned_32'Asm_Output ("=a", Flags));
        Put_Line ("Flags register:" & Flags'Img);
     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:

  ::

     #APP
        pushfl
        popl %eax
     #NO_APP
        movl %eax,-40(%ebp)

The compiler generated the store of eax into Flags after
expanding the assembler code.

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

     with Interfaces; use Interfaces;
     with Ada.Text_IO; use Ada.Text_IO;
     with System.Machine_Code; use System.Machine_Code;
     procedure Get_Flags_3 is
        Flags : Unsigned_32;
        use ASCII;
     begin
        Asm ("pushfl"  & LF & HT & -- push flags on stack
             "pop %0",             -- save flags in Flags
             Outputs => Unsigned_32'Asm_Output ("=g", Flags));
        Put_Line ("Flags register:" & Flags'Img);
     end Get_Flags_3;


.. _Input_Variables_in_Inline_Assembler:

Input Variables in Inline Assembler
===================================

The example in this section illustrates how to specify the source operands
for assembly language statements.
The procedure simply increments its input value by 1:

  .. code-block:: ada

     with Interfaces; use Interfaces;
     with Ada.Text_IO; use Ada.Text_IO;
     with System.Machine_Code; use System.Machine_Code;
     procedure Increment is

        function Incr (Value : Unsigned_32) return Unsigned_32 is
           Result : Unsigned_32;
        begin
           Asm ("incl %0",
                Outputs => Unsigned_32'Asm_Output ("=a", Result),
                Inputs  => Unsigned_32'Asm_Input ("a", Value));
           return Result;
        end Incr;

        Value : Unsigned_32;

     begin
        Value := 5;
        Put_Line ("Value before is" & Value'Img);
        Value := Incr (Value);
       Put_Line ("Value after is" & Value'Img);
     end Increment;

The ``Outputs`` parameter to ``Asm`` specifies
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 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, 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``
* execute the ``incl %eax`` instruction
* store the contents of eax into the ``Result`` variable

The resulting assembler file (with :switch:`-O2` optimization) contains:

  ::

     _increment__incr.1:
        subl $4,%esp
        movl 8(%esp),%eax
     #APP
        incl %eax
     #NO_APP
        movl %eax,%edx
        movl %ecx,(%esp)
        addl $4,%esp
        ret


.. _Inlining_Inline_Assembler_Code:

Inlining Inline Assembler Code
==============================

For a short subprogram such as the ``Incr`` function in the previous
section, the overhead of the call and return (creating / deleting the stack
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's the resulting program:

  .. code-block:: ada

     with Interfaces; use Interfaces;
     with Ada.Text_IO; use Ada.Text_IO;
     with System.Machine_Code; use System.Machine_Code;
     procedure Increment_2 is

        function Incr (Value : Unsigned_32) return Unsigned_32 is
           Result : Unsigned_32;
        begin
           Asm ("incl %0",
                Outputs => Unsigned_32'Asm_Output ("=a", Result),
                Inputs  => Unsigned_32'Asm_Input ("a", Value));
           return Result;
        end Incr;
        pragma Inline (Increment);

        Value : Unsigned_32;

     begin
        Value := 5;
        Put_Line ("Value before is" & Value'Img);
        Value := Increment (Value);
        Put_Line ("Value after is" & Value'Img);
     end Increment_2;

Compile the program with both optimization (:switch:`-O2`) and inlining
(:switch:`-gnatn`) enabled.

The ``Incr`` function is still compiled as usual, but at the
point in ``Increment`` where our function used to be called:


  ::

     pushl %edi
     call _increment__incr.1

the code for the function body directly appears:


  ::

     movl %esi,%eax
     #APP
        incl %eax
     #NO_APP
        movl %eax,%edx

thus saving the overhead of stack frame setup and an out-of-line call.


.. _Other_Asm_Functionality:

Other ``Asm`` Functionality
===========================

This section describes two important parameters to the ``Asm``
procedure: ``Clobber``, which identifies register usage;
and ``Volatile``, which inhibits unwanted optimizations.

.. _The_Clobber_Parameter:

The ``Clobber`` Parameter
-------------------------

One of the dangers of intermixing assembly language and a compiled language
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
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``, 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

     Asm ("movl %0, %%ebx" & LF & HT &
          "movl %%ebx, %1",
          Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
          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.

In such cases you need to supply the ``Clobber`` parameter to ``Asm``,
to identify the registers used by your assembly code:


  .. code-block:: ada

     Asm ("movl %0, %%ebx" & LF & HT &
          "movl %%ebx, %1",
          Outputs => Unsigned_32'Asm_Output ("=g", Var_Out),
          Inputs  => Unsigned_32'Asm_Input  ("g", Var_In),
          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,
you separate their names by commas; e.g., ``"eax, ebx"``

The ``Clobber`` parameter has several additional uses:

* Use 'register' name ``cc`` to indicate that flags might have changed
* Use 'register' name ``memory`` if you changed a memory location


.. _The_Volatile_Parameter:

The ``Volatile`` Parameter
--------------------------

.. index:: Volatile parameter

Compiler optimizations in the presence of Inline Assembler may sometimes have
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 you don't want this to happen, you can disable such optimizations by setting
the ``Volatile`` parameter to ``True``; for example:

  .. code-block:: ada

     Asm ("movl %0, %%ebx" & LF & HT &
          "movl %%ebx, %1",
          Outputs  => Unsigned_32'Asm_Output ("=g", Var_Out),
          Inputs   => Unsigned_32'Asm_Input  ("g", Var_In),
          Clobber  => "ebx",
          Volatile => True);

By default, ``Volatile`` is set to ``False`` unless there is no
``Outputs`` parameter.

Although setting ``Volatile`` to ``True`` prevents unwanted
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.

---

### Gcc Ada Doc Gnat Ugn Platform Specific Information (`gcc/ada/doc/gnat_ugn/platform_specific_information.rst`)

.. role:: switch(samp)

.. -- Non-breaking space in running text
   -- E.g. Ada |nbsp| 95

.. |nbsp| unicode:: 0xA0
   :trim:

.. _Platform_Specific_Information:

*****************************
Platform-Specific Information
*****************************

This appendix contains information relating to the implementation
of run-time libraries on various platforms. It also covers topics
related to the GNAT implementation on specific Operating Systems.

.. _`Run_Time_Libraries`:

Run-Time Libraries
==================

.. index:: Tasking and threads libraries
.. index:: Threads libraries and tasking
.. index:: Run-time libraries (platform-specific information)

The GNAT run-time implementation may vary with respect to both the
underlying threads library and the exception-handling scheme.
For threads support, the default run-time will bind to the thread
package of the underlying operating system.

For exception handling, either or both of two models are supplied:

  .. index:: Zero-Cost Exceptions
  .. index:: ZCX (Zero-Cost Exceptions)

* **Zero-Cost Exceptions** ("ZCX"),
  which uses binder-generated tables that
  are interrogated at run time to locate a handler.

  .. index:: setjmp/longjmp Exception Model
  .. index:: SJLJ (setjmp/longjmp Exception Model)

* **setjmp / longjmp** ('SJLJ'),
  which uses dynamically-set data to establish
  the set of handlers

Most programs should experience a substantial speed improvement by
being compiled with a ZCX run-time.
This is especially true for
tasking applications or applications with many exception handlers.
Note however that the ZCX run-time does not support asynchronous abort
of tasks (``abort`` and ``select-then-abort`` constructs) and will instead
implement abort by polling points in the runtime. You can also add additional
polling points explicitly if needed in your application via ``pragma
Abort_Defer``.

This section summarizes which combinations of threads and exception support
are supplied on various GNAT platforms.

.. _Summary_of_Run-Time_Configurations:

Summary of Run-Time Configurations
----------------------------------

+-----------------+--------------+-------------------------+------------+
| Platform        | Run-Time     | Tasking                 | Exceptions |
+=================+==============+=========================+============+
| GNU/Linux       | rts-native   | pthread library         | ZCX        |
|                 | (default)    |                         |            |
|                 +--------------+-------------------------+------------+
|                 | rts-sjlj     | pthread library         | SJLJ       |
+-----------------+--------------+-------------------------+------------+
| Windows         | rts-native   | native Win32 threads    | ZCX        |
|                 | (default)    |                         |            |
|                 +--------------+-------------------------+------------+
|                 | rts-sjlj     | native Win32 threads    | SJLJ       |
+-----------------+--------------+-------------------------+------------+
| Mac OS          | rts-native   | pthread library         | ZCX        |
+-----------------+--------------+-------------------------+------------+


.. _Specifying_a_Run-Time_Library:

Specifying a Run-Time Library
=============================

The :file:`adainclude` subdirectory containing the sources of the GNAT
run-time library and the :file:`adalib` subdirectory containing the
:file:`ALI` files and the static and/or shared GNAT library are located
in the gcc target-dependent area:


  ::

      target=$prefix/lib/gcc/gcc-*dumpmachine*/gcc-*dumpversion*/

As indicated above, on some platforms, several run-time libraries are supplied.
These libraries are installed in the target dependent area and
contain a complete source and binary subdirectory. The detailed description
below explains the differences between the different libraries in terms of
their thread support.

The default run-time library (when GNAT is installed) is *rts-native*.
This default run-time is selected by the means of soft links.
For example on x86-linux:

.. --
   --  $(target-dir)
   --      |
   --      +--- adainclude----------+
   --      |                        |
   --      +--- adalib-----------+  |
   --      |                     |  |
   --      +--- rts-native       |  |
   --      |    |                |  |
   --      |    +--- adainclude <---+
   --      |    |                |
   --      |    +--- adalib <----+
   --      |
   --      +--- rts-sjlj
   --           |
   --           +--- adainclude
   --           |
   --           +--- adalib

.. only:: html or latex

  .. image:: rtlibrary-structure.png

.. only:: not (html or latex)

   ::

                      $(target-dir)
                     __/ /      \ \___
             _______/   /        \    \_________________
            /          /          \                     \
           /          /            \                     \
       ADAINCLUDE  ADALIB      rts-native             rts-sjlj
          :          :            /    \                 /   \
          :          :           /      \               /     \
          :          :          /        \             /       \
          :          :         /          \           /         \
          +-------------> adainclude     adalib   adainclude   adalib
                     :                     ^
                     :                     :
                     +---------------------+

                     Run-Time Library Directory Structure
          (Upper-case names and dotted/dashed arrows represent soft links)

If you want to select the *rts-sjlj* library on a permanent basis,
you can modify these soft links with the following commands:

  ::

    $ cd $target
    $ rm -f adainclude adalib
    $ ln -s rts-sjlj/adainclude adainclude
    $ ln -s rts-sjlj/adalib adalib

Alternatively, you can specify :file:`rts-sjlj/adainclude` in the file
:file:`$target/ada_source_path` and :file:`rts-sjlj/adalib` in
:file:`$target/ada_object_path`.

.. index:: --RTS switch

You can select another run-time library temporarily
by using the :switch:`--RTS` switch, e.g., :switch:`--RTS=sjlj`


.. index:: Linux
.. index:: GNU/Linux

.. _GNU_Linux_Topics:

GNU/Linux Topics
================

This section describes topics that are specific to GNU/Linux platforms.

.. _Required_packages_on_GNU_Linux:

Required Packages on GNU/Linux
------------------------------

GNAT requires the C library developer's package to be installed.
The name of of that package depends on your GNU/Linux distribution:

* RedHat, SUSE: ``glibc-devel``;
* Debian, Ubuntu: ``libc6-dev`` (normally installed by default).

If you're using the 32-bit version of GNAT on a 64-bit version of GNU/Linux,
you'll need the 32-bit version of the following packages:

* RedHat, SUSE: ``glibc.i686``, ``glibc-devel.i686``, ``ncurses-libs.i686``
* SUSE: ``glibc-locale-base-32bit``
* Debian, Ubuntu: ``libc6:i386``, ``libc6-dev:i386``, ``lib32ncursesw5``

Other GNU/Linux distributions might choose different name
for those packages.


.. _PIE_Enabled_By_Default_On_Linux:

Position Independent Executable (PIE) Enabled by Default on Linux
-----------------------------------------------------------------

GNAT generates Position Independent Executable (PIE) code by default.
PIE binaries are loaded into random memory locations, introducing
an additional layer of protection against attacks.

Building PIE binaries requires that all of their dependencies also be
built as Position Independent. If the link of your project fails with
an error like::

      /[...]/ld: /path/to/object/file: relocation R_X86_64_32S against symbol
      `symbol name' can not be used when making a PIE object;
      recompile with -fPIE

it means the identified object file has not been built as Position
Independent.

If you are not interested in building PIE binaries, you can simply
turn this feature off by first compiling your code with :samp:`-fno-pie`
and then by linking with :samp:`-no-pie` (note the subtle but important
difference in the names of the switches -- the linker switch does **not**
have an `f` after the dash!). When using gprbuild, you do this
by updating the *Required_Switches* attribute in package `Compiler`
and, depending on your type of project, either attribute *Switches*
or attribute *Library_Options* in package `Linker`.

On the other hand, if you would like to build PIE binaries and you are
getting the error above, a quick and easy workaround to allow linking
to succeed again is to disable PIE during the link, thus temporarily
lifting the requirement that all dependencies also be Position
Independent code. To do so, you simply need to add :samp:`-no-pie` to
the list of switches passed to the linker. As part of this workaround,
there is no need to adjust the compiler switches.

From there, to be able to link your binaries with PIE and therefore
drop the :samp:`-no-pie` workaround, you'll need to get the identified
dependencies rebuilt with PIE enabled (compiled with :samp:`-fPIE`
and linked with :samp:`-pie`).

.. _Choosing_the_Scheduling_Policy_With_GNU_Linux:

.. index:: SCHED_FIFO scheduling policy
.. index:: SCHED_RR scheduling policy
.. index:: SCHED_OTHER scheduling policy

Choosing the Scheduling Policy with GNU/Linux
---------------------------------------------

When using a POSIX threads implementation, you have a choice of several
scheduling policies: ``SCHED_FIFO``, ``SCHED_RR`` and ``SCHED_OTHER``.

Typically, the default is ``SCHED_OTHER``, while using ``SCHED_FIFO``
or ``SCHED_RR`` requires special (e.g., root) privileges.

.. index:: pragma Time_Slice
.. index:: -T0 switch
.. index:: pragma Task_Dispatching_Policy


By default, GNAT uses the ``SCHED_OTHER`` policy. To specify
``SCHED_FIFO``,
you can use one of the following:

* ``pragma Time_Slice (0.0)``
* the corresponding binder switch :switch:`-T0`
* ``pragma Task_Dispatching_Policy (FIFO_Within_Priorities)``

To specify ``SCHED_RR``,
you should use ``pragma Time_Slice`` with a
value greater than 0.0, or else use the corresponding :switch:`-T`
binder switch.

To make sure a program is running as root, you can put something like
this in a library package body in your application:

  .. code-block:: ada

     function geteuid return Integer;
     pragma Import (C, geteuid, "geteuid");
     Ignore : constant Boolean :=
       (if geteuid = 0 then True else raise Program_Error with "must be root");

This gets the effective user id and if it's not 0 (i.e. root), it raises
Program_Error. Note that if you're running the code in a container, this may
not be sufficient as you may have sufficient privilege on the container,
but not on the host machine running the container, so check that you also
have sufficient privilege for running the container image.

.. _A_GNU_Linux_debug_quirk:

A GNU/Linux Debug Quirk
-----------------------

On SuSE 15, some kernels have a defect causing issues when debugging
programs using threads or Ada tasks. Due to the lack of documentation
found regarding this kernel issue, we can only provide limited
information about which kernels are impacted. Kernel version 5.3.18 is
known to be impacted and kernels in the 5.14 range or newer are
believed to fix this problem.

The bug affects the debugging of 32-bit processes on a 64-bit system.
Symptoms can vary: Unexpected ``SIGABRT`` signals being received by
the program, "The futex facility returned an unexpected error code"
error message, and inferior programs hanging indefinitely range among
the symptoms most commonly observed.

.. index:: Windows

.. _Microsoft_Windows_Topics:

Microsoft Windows Topics
========================

This section describes topics that are specific to the Microsoft Windows
platforms.


.. only:: PRO

  .. rubric:: Installing from the Command Line

  By default the GNAT installers display a GUI that prompts you to enter
  the installation path and similar information and then guides you through the
  installation process. You can also perform silent installations
  using the command-line interface.

  To install one of the GNAT installers from the command
  line, you should pass parameter :switch:`/S` (and, optionally,
  :switch:`/D=<directory>`) as command-line arguments.

   For example, for an unattended installation of
   GNAT 19.2 into the default directory :file:`C:\\GNATPRO\\19.2` you
   would run::

        gnatpro-19.2-x86-windows-bin /S

   To install into a custom directory, say, :file:`C:\\TOOLS\\GNATPRO\\19.2`::

        gnatpro-19.2-x86-windows-bin /S /D=C:\TOOLS\GNATPRO\19.2

   You can use the same syntax for all installers.

   Note that unattended installations don't modify system path, nor create file
   associations, so you need to do such activities by hand.


.. _Using_GNAT_on_Windows:

Using GNAT on Windows
---------------------

One of the strengths of the GNAT technology is that its tool set
(``gcc``, ``gnatbind``, ``gnatlink``, ``gnatmake``, the
``gdb`` debugger, etc.) is used in the same way regardless of the
platform.

On Windows, this tool set is complemented by a number of Microsoft-specific
tools that have been provided to facilitate interoperability with Windows
when this is required. With these tools:


* You can build applications using the ``CONSOLE`` or ``WINDOWS``
  subsystems.

* You can use any Dynamically Linked Library (DLL) in your Ada code (both
  relocatable and non-relocatable DLLs are supported).

* You can build Ada DLLs for use in other applications. You can write
  these applications in a language other than Ada (e.g., C, C++,
  etc). Again, both relocatable and non-relocatable Ada DLLs are
  supported.

* You can include Windows resources in your Ada application.

* You can use or create COM/DCOM objects.

Listed immediately below are all known general GNAT-for-Windows
restrictions.  We list other restrictions about specific features such
as Windows Resources and DLLs in separate sections below.

* You cannot use ``GetLastError`` and ``SetLastError``
  when tasking, protected records, or exceptions are used. In these
  cases, in order to implement Ada semantics, the GNAT run-time system
  calls certain Win32 routines that set the last error variable to 0 upon
  success. You may be able to use ``GetLastError`` and
  ``SetLastError`` when tasking, protected record, and exception
  features are not used, but it is not guaranteed to work.

* You cannot link against Microsoft C++ libraries except for
  import libraries. You must do interfacing by means of DLLs.

* You can link against Microsoft C libraries. However, the preferred
  solution is to use C/C++ compiler that comes with GNAT, since it
  doesn't require having two different development environments and makes the
  inter-language debugging experience smoother.

* When the compilation environment is located on FAT32 drives, you may
  experience recompilations of source files that have not changed if
  Daylight Saving Time (DST) state has changed since the last time files
  were compiled. NTFS drives do not have this problem.

* No components of the GNAT toolset use any entries in the Windows
  registry. The only entries installation of GNAT may create are file
  associations and PATH settings, provided you chose to
  create them at installation time, as well as some minimal
  bookkeeping information needed to correctly uninstall or integrate
  different GNAT products.


.. _Using_a_network_installation_of_GNAT:

Using a network installation of GNAT
------------------------------------

Make sure the system on which GNAT is installed is accessible from the
current machine, i.e., the install location is shared over the network.
Shared resources are accessed on Windows by means of UNC paths, which
have the format ``\\\\server\\sharename\\path``

In order to use such a network installation, simply add the UNC path of the
:file:`bin` directory of your GNAT installation in front of your PATH. For
example, if GNAT is installed in :file:`\\GNAT` directory of a share location
called :file:`c-drive` on a machine :file:`LOKI`, the following command will
make it available:

  ::

      $ path \\loki\c-drive\gnat\bin;%path%`

Be aware that every compilation using the network installation results in the
transfer of large amounts of data across the network and will likely cause
a serious performance penalty.

.. _CONSOLE_and_WINDOWS_subsystems:

CONSOLE and WINDOWS subsystems
------------------------------

.. index:: CONSOLE Subsystem
.. index:: WINDOWS Subsystem
.. index:: -mwindows

There are two main subsystems under Windows. The ``CONSOLE`` subsystem
(which is the default subsystem) always creates a console when
launching the application. This is not something desirable when the
application has a Windows GUI. To remove this console, your
application must use the ``WINDOWS`` subsystem. To do so, you must
specify the :switch:`-mwindows` linker switch.

   ::

      $ gnatmake winprog -largs -mwindows

.. _Temporary_Files:

Temporary Files
---------------

.. index:: Temporary files

You can control where temporary files get created by setting the
:envvar:`TMP` environment variable. The file will be created:

* Under the directory pointed to by the :envvar:`TMP` environment variable if
  this directory exists.

* Under :file:`c:\\temp`, if the :envvar:`TMP` environment variable is not
  set (or not pointing to a directory) and if this directory exists.

* Under the current working directory otherwise.

This allows you to determine exactly where the temporary
file will be created. This is particularly useful in networked
environments where you may not have write access to some
directories.

Disabling Command Line Argument Expansion
-----------------------------------------

.. index:: Command Line Argument Expansion

By default, an executable compiled for the Windows platform will do
the following postprocessing on the arguments passed on the command
line:

* If the argument contains the characters ``*`` and/or ``?``,
  file expansion will be attempted. For example, if the current directory
  contains :file:`a.txt` and :file:`b.txt`, then when calling::

      $ my_ada_program *.txt

  The following arguments will effectively be passed to the main program
  (for example when using ``Ada.Command_Line.Argument``)::

      Ada.Command_Line.Argument (1) -> "a.txt"
      Ada.Command_Line.Argument (2) -> "b.txt"

* You can disable filename expansion for a given argument by using single
  quotes. Thus, calling::

      $ my_ada_program '*.txt'

  will result in::

      Ada.Command_Line.Argument (1) -> "*.txt"

Note that if the program is launched from a shell such as Cygwin Bash,
quote removal might be performed by that shell.

In some contexts, it might be useful to disable this feature (for example if
the program performs its own argument expansion). In order to do this, a C
symbol needs to be defined and set to ``0``. You can do this by
adding the following code fragment in one of your Ada units:

.. code-block:: ada

   Do_Argv_Expansion : Integer := 0;
   pragma Export (C, Do_Argv_Expansion, "__gnat_do_argv_expansion");

The results of previous examples will be respectively::

   Ada.Command_Line.Argument (1) -> "*.txt"

and::

   Ada.Command_Line.Argument (1) -> "'*.txt'"

.. _Choosing_the_Scheduling_Policy_With_Windows:

Choosing the Scheduling Policy with Windows
-------------------------------------------

Under Windows, the standard 31 priorities of the Ada model are mapped onto
Window's seven standard priority levels by default: Idle, Lowest, Below Normal,
Normal, Above Normal,

When using the ``FIFO_Within_Priorities`` task dispatching policy, GNAT
assigns the ``REALTIME_PRIORITY_CLASS`` priority class to the application
and maps the Ada priority range to the sixteen priorities made available under
``REALTIME_PRIORITY_CLASS``.

For details on the values of the different priority mappings, see declarations
in :file:`system.ads`. For more information about Windows priorities, please
refer to Microsoft documentation.

Windows Socket Timeouts
-----------------------

Microsoft Windows desktops older than ``8.0`` and Microsoft Windows Servers
older than ``2019`` set a socket timeout 500 milliseconds longer than the value
set by setsockopt with ``SO_RCVTIMEO`` and ``SO_SNDTIMEO`` options. The GNAT
runtime makes a correction for the difference in the corresponding Windows
versions. For Windows Server starting with version ``2019``, you must
provide a manifest file for the GNAT runtime to be able to recognize that
the Windows version does not need the timeout correction. The manifest file
should be located in the same directory as the executable file and its file
name must match the executable name suffixed by ``.manifest``. For example,
if the executable name is :file:`sock_wto.exe`, the manifest file name
must be :file:`sock_wto.exe.manifest`. The manifest file must contain at
least the following data::

   <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
   <application>
      
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
      
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
      
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
   </application>
   </compatibility>
   </assembly>

Without the manifest file, the socket timeout will be overcorrected on
these Windows Server versions and the actual time will be 500
milliseconds shorter than what was set with
``GNAT.Sockets.Set_Socket_Option``.  Note that on Microsoft Windows
versions where correction is necessary, there is no way to set a
socket timeout shorter than 500 ms. If a socket timeout shorter than
500 ms is needed on these Windows versions, you should add a call to
``Check_Selector`` before any socket read or write
operations.


.. _Mixed-Language_Programming_on_Windows:

Mixed-Language Programming on Windows
-------------------------------------

Developing pure Ada applications on Windows is no different than on
other GNAT-supported platforms. However, when developing or porting an
application that contains a mix of Ada and C/C++, the choice of your
Windows C/C++ development environment conditions your overall
interoperability strategy.

If you use ``gcc`` or Microsoft C to compile the non-Ada part of
your application, there are no Windows-specific restrictions that
affect the overall interoperability with your Ada code. If you do want
to use the Microsoft tools for your C++ code, you have two choices:

* You can encapsulate your C++ code in a DLL to be linked with your Ada
  application. In this case, use the Microsoft or other environment to
  build the DLL and use GNAT to build your executable
  (:ref:`Using_DLLs_with_GNAT`).

* You can encapsulate your Ada code in a DLL to be linked with the
  other part of your application. In this case, use GNAT to build the DLL
  (:ref:`Building_DLLs_with_GNAT_Project_files`) and use the Microsoft
  or other environment to build your executable.

In addition to the description about C ``main`` in
:ref:`Mixed_Language_Programming` section, if the C ``main`` uses a
stand-alone library, it is required on x86-windows to
setup the SEH context. For this, the C ``main`` must looks like this:


  .. code-block:: c

      /* main.c */
      extern void adainit (void);
      extern void adafinal (void);
      extern void __gnat_initialize(void*);
      extern void call_to_ada (void);

      int main (int argc, char *argv[])
      {
        int SEH [2];

        /* Initialize the SEH context */
        __gnat_initialize (&SEH);

        adainit();

        /* Then call Ada services in the stand-alone library */

        call_to_ada();

        adafinal();
      }

Note that you need not do this on x86_64-windows where the Windows
native SEH support is used.


.. _Windows_Calling_Conventions:

Windows Calling Conventions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Stdcall
.. index:: APIENTRY

This section pertain only to Win32. On Win64, there is a single native
calling convention. All convention specifiers are ignored on this
platform.

When a subprogram ``F`` (caller) calls a subprogram ``G``
(callee), there are several ways to push ``G``\ 's parameters on the
stack and there are several possible scenarios to clean up the stack
upon ``G``\ 's return. A calling convention is an agreed upon software
protocol whereby the responsibilities between the caller (``F``) and
the callee (``G``) are clearly defined. Several calling conventions
are available for Windows:

* ``C`` (Microsoft defined)

* ``Stdcall`` (Microsoft defined)

* ``Win32`` (GNAT specific)

* ``DLL`` (GNAT specific)


.. _C_Calling_Convention:

``C`` Calling Convention
""""""""""""""""""""""""

This is the default calling convention used when interfacing to C/C++
routines compiled with either ``gcc`` or Microsoft Visual C++.

In the ``C`` calling convention, subprogram parameters are pushed on the
stack by the caller from right to left. The caller itself is in charge of
cleaning up the stack after the call. In addition, the name of a routine
with ``C`` calling convention is mangled by adding a leading underscore.

The name to use on the Ada side when importing (or exporting) a routine
with ``C`` calling convention is the name of the routine. For
example you should import the C function:

   ::

       int get_val (long);

from Ada as follows:

  .. code-block:: ada

     function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
     pragma Import (C, Get_Val, External_Name => "get_val");

Note that in this particular case, you could have omitted the
``External_Name`` parameter since, when missing, this parameter is set
to the name of the Ada entity in lower case. When the ``Link_Name``
parameter is missing, as in the above example, this parameter is set
the ``External_Name`` with a leading underscore.

When importing a variable defined in C, you should always use the ``C``
calling convention unless the object containing the variable is part of a
DLL (in which case you should use the ``Stdcall`` calling
convention, :ref:`Stdcall_Calling_Convention`).


.. _Stdcall_Calling_Convention:

``Stdcall`` Calling Convention
""""""""""""""""""""""""""""""

This convention, which was the calling convention used for Pascal
programs, is used by Microsoft for all the routines in the Win32 API for
efficiency reasons. You must use it to import any routine for which this
convention was specified.

In the ``Stdcall`` calling convention, subprogram parameters are also pushed
on the stack by the caller from right to left. However, the callee, not the
caller, is in charge of cleaning up the stack on routine exit. In addition,
the name of a routine with ``Stdcall`` calling convention is mangled by
adding a leading underscore (as for the ``C`` calling convention) and a
trailing :samp:`@{nn}`, where ``nn`` is the overall size (in
bytes) of the parameters passed to the routine.

The name to use on the Ada side when importing a C routine with a
``Stdcall`` calling convention is the name of the C routine. The leading
underscore and trailing :samp:`@{nn}` are added automatically by
the compiler. For example, you could import the Win32 function:

  ::

      APIENTRY int get_val (long);

from Ada as follows:

  .. code-block:: ada

     function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
     pragma Import (Stdcall, Get_Val);
     --  On the x86 a long is 4 bytes, so the Link_Name is "_get_val@4"

Like the case for the ``C`` calling convention, when the
``External_Name`` parameter is missing, it is the name of the Ada
entity in lower case. If instead of writing the above import pragma
you write:

  .. code-block:: ada

     function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
     pragma Import (Stdcall, Get_Val, External_Name => "retrieve_val");

the imported routine is ``_retrieve_val@4``. However, if instead
of specifying the ``External_Name`` parameter, you specify the
``Link_Name`` as in the following example:

  .. code-block:: ada

     function Get_Val (V : Interfaces.C.long) return Interfaces.C.int;
     pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val");

the imported routine is ``retrieve_val``. There is no
decoration at all; no leading underscore and no Stdcall suffix
:samp:`@{nn}`.

This is especially important as in some special cases a DLL's entry
point name lacks a trailing :samp:`@{nn}` while the exported
name generated for a call has it.

You can also import variables defined in a DLL by using an
import pragma for a variable. As an example, if a DLL contains a
variable defined as:

  .. code-block:: c

     int my_var;

then, to access this variable from Ada you should write:

  .. code-block:: ada

      My_Var : Interfaces.C.int;
      pragma Import (Stdcall, My_Var);

Note that to ease building cross-platform bindings, this convention
will be handled as a ``C`` calling convention on non-Windows platforms.


.. _Win32_Calling_Convention:

``Win32`` Calling Convention
""""""""""""""""""""""""""""

This convention, which is GNAT-specific, is fully equivalent to the
``Stdcall`` calling convention described above.


.. _DLL_Calling_Convention:

``DLL`` Calling Convention
""""""""""""""""""""""""""

This convention, which is GNAT-specific, is fully equivalent to the
``Stdcall`` calling convention described above.


.. _Introduction_to_Dynamic_Link_Libraries_DLLs:

Introduction to Dynamic Link Libraries (DLLs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: DLL

A Dynamically Linked Library (DLL) is a library that can be shared by
several applications running under Windows. A DLL can contain any number of
routines and variables.

One advantage of DLLs is that you can change and enhance them without
forcing all the applications that depend on them to be relinked or
recompiled. However, you should be aware than all calls to DLL routines are
slower since, as you will understand below, such calls are indirect.

To illustrate the remainder of this section, suppose that an application
wants to use the services of a DLL :file:`API.dll`. To use the services
provided by :file:`API.dll`, you must statically link against the DLL or
an import library which contains a jump table with an entry for each
routine and variable exported by the DLL. In the Microsoft world, this
import library is called :file:`API.lib`. When using GNAT, this import
library is called either :file:`libAPI.dll.a`, :file:`libapi.dll.a`,
:file:`libAPI.a` or :file:`libapi.a` (names are case insensitive).

After you have linked your application with the DLL or the import library
and you run your application, here is what happens:

* Your application is loaded into memory.

* The DLL :file:`API.dll` is mapped into the address space of your
  application. This means that:

  - The DLL uses the stack of the calling thread.

  - The DLL uses the virtual address space of the calling process.

  - The DLL allocates memory from the virtual address space of the calling
    process.

  - Handles (pointers) can be safely exchanged between routines in the DLL
    routines and routines in the application using the DLL.

* The entries in the jump table (from the import library :file:`libAPI.dll.a`
  or :file:`API.lib` or automatically created when linking against a DLL)
  which is part of your application are initialized with the addresses
  of the routines and variables in :file:`API.dll`.

* If present in :file:`API.dll`, routines ``DllMain`` or
  ``DllMainCRTStartup`` are invoked. These routines typically contain
  the initialization code needed for the well-being of the routines and
  variables exported by the DLL.

There is an additional point which is worth mentioning. In the Windows
world, there are two kind of DLLs: relocatable and non-relocatable
DLLs. Non-relocatable DLLs can only be loaded at a specific address
in the target application address space. If the addresses of two
non-relocatable DLLs overlap and these happen to be used by the same
application, a conflict occurs and the application will run
incorrectly. Hence, when possible, you should always use and
build relocatable DLLs. Both relocatable and non-relocatable DLLs are
supported by GNAT. Note that the :switch:`-s` linker switch (see GNU Linker
User's Guide) removes the debugging symbols from the DLL, but the DLL can
still be relocated.

As a side note, an interesting difference between Microsoft DLLs and
Unix shared libraries is the fact that on most Unix systems all public
routines are exported by default in a Unix shared library, while under
Windows it is possible (but not required) to list exported routines in
a definition file (see :ref:`The Definition File <The_Definition_File>`).


.. _Using_DLLs_with_GNAT:

Using DLLs with GNAT
^^^^^^^^^^^^^^^^^^^^

To use the services of a DLL, say :file:`API.dll`, in your Ada application
you must have:

* The Ada spec for the routines and/or variables you want to access in
  :file:`API.dll`. If not available, you must build this Ada spec from the
  C/C++ header files provided with the DLL.

* The import library (:file:`libAPI.dll.a` or :file:`API.lib`). As previously
  mentioned, an import library is a statically linked library containing the
  import table, which is filled at load time to point to the actual
  :file:`API.dll` routines. Sometimes you don't have an import library for the
  DLL you want to use. The following sections will explain how to build
  one. Note that this is optional.

* The actual DLL, :file:`API.dll`.

Once you have all the above, to compile an Ada application that uses the
services of :file:`API.dll` and whose main subprogram is ``My_Ada_App``,
you simply issue the command

  ::

      $ gnatmake my_ada_app -largs -lAPI

The argument :switch:`-largs -lAPI` at the end of the ``gnatmake`` command
tells the GNAT linker to look for an import library. The linker will
look for a library name in this specific order:

* :file:`libAPI.dll.a`
* :file:`API.dll.a`
* :file:`libAPI.a`
* :file:`API.lib`
* :file:`libAPI.dll`
* :file:`API.dll`

The first three are the GNU-style import libraries. The third is the
Microsoft-style import libraries. The last two are the actual DLL names.

Note that if the Ada package spec for :file:`API.dll` contains the
following pragma

  .. code-block:: ada

      pragma Linker_Options ("-lAPI");

you do not have to add :switch:`-largs -lAPI` at the end of the
``gnatmake`` command.

If any one of the items above is missing, you will have to create it
yourself. The following sections explain how to do so using as an
example a fictitious DLL called :file:`API.dll`.


.. _Creating_an_Ada_Spec_for_the_DLL_Services:

Creating an Ada Spec for the DLL Services
"""""""""""""""""""""""""""""""""""""""""

A DLL typically comes with a C/C++ header file which provides the
definitions of the routines and variables exported by the DLL. The Ada
equivalent of this header file is a package spec that contains definitions
for the imported entities. If the DLL you intend to use does not come with
an Ada spec, you have to generate such a spec yourself. For example, if
the header file of :file:`API.dll` is a file :file:`api.h` containing the
following two definitions:

  .. code-block:: c

      int some_var;
      int get (char *);

then the equivalent Ada spec could be:

  .. code-block:: ada

      with Interfaces.C.Strings;
      package API is
         use Interfaces;

         Some_Var : C.int;
         function Get (Str : C.Strings.Chars_Ptr) return C.int;

      private
         pragma Import (C, Get);
         pragma Import (DLL, Some_Var);
      end API;


.. _Creating_an_Import_Library:

Creating an Import Library
""""""""""""""""""""""""""

.. index:: Import library

If a Microsoft-style import library :file:`API.lib` or a GNAT-style
import library :file:`libAPI.dll.a` or :file:`libAPI.a` is available
with :file:`API.dll` you can skip this section. You can also skip this
section if :file:`API.dll` or :file:`libAPI.dll` is built with GNU tools
as in this case it is possible to link directly against the
DLL. Otherwise read on.


.. index:: Definition file

.. _The_Definition_File:

.. rubric:: The Definition File

As previously mentioned, and unlike Unix systems, the list of symbols
that are exported from a DLL must be provided explicitly in Windows.
The main goal of a definition file is precisely that: list the symbols
exported by a DLL. A definition file (usually a file with a ``.def``
suffix) has the following structure:

  ::

      [LIBRARY ``name``]
      [DESCRIPTION ``string``]
      EXPORTS
         ``symbol1``
         ``symbol2``
         ...

*LIBRARY name*
  This section, which is optional, gives the name of the DLL.


*DESCRIPTION string*
  This section, which is optional, gives a description string that will be
  embedded in the import library.


*EXPORTS*
  This section gives the list of exported symbols (procedures, functions or
  variables). For example, in the case of :file:`API.dll` the ``EXPORTS``
  section of :file:`API.def` looks like:

  ::

      EXPORTS
         some_var
         get

Note that you must specify the correct suffix (:samp:`@{nn}`)
(see :ref:`Windows_Calling_Conventions`) for a Stdcall
calling convention function in the exported symbols list.

There can actually be other sections in a definition file, but these
sections are not relevant to the discussion at hand.


.. _Create_Def_File_Automatically:

.. rubric:: Creating a Definition File Automatically

You can automatically create the definition file :file:`API.def`
(see :ref:`The Definition File <The_Definition_File>`) from a DLL.
To do that, use the ``dlltool`` program as follows:

  ::

      $ dlltool API.dll -z API.def --export-all-symbols

  Note that if some routines in the DLL have the ``Stdcall`` convention
  (:ref:`Windows_Calling_Conventions`) with stripped :samp:`@{nn}`
  suffix then you'll have to edit :file:`api.def` to add it and specify
  :switch:`-k` to ``gnatdll`` when creating the import library.

  Here are some hints to find the right :samp:`@{nn}` suffix.

  - If you have the Microsoft import library (.lib), you may be able
    to find the right symbols by using the Microsoft ``dumpbin`` tool
    (see the corresponding Microsoft documentation for further
    details).

    ::

        $ dumpbin /exports api.lib

  - If you get a message about a missing symbol at link time, the compiler
    tells you what symbol is expected. You then can go back to the
    definition file and add the right suffix.


.. _GNAT-Style_Import_Library:

.. rubric:: GNAT-Style Import Library

To create a static import library from :file:`API.dll` with the GNAT tools,
you should create the :file:`.def` file and use the ``gnatdll`` tool
(see :ref:`Using_gnatdll`) as follows:

  ::

      $ gnatdll -e API.def -d API.dll

  ``gnatdll`` takes as input a definition file :file:`API.def` and the
  name of the DLL containing the services listed in the definition file
  :file:`API.dll`. The name of the static import library generated is
  computed from the name of the definition file as follows: if the
  definition file name is :file:`xyz.def`, the import library name will
  be :file:`libxyz.a`. Note that in the previous example, the switch
  :switch:`-e` could have been removed because the name of the definition
  file (before the ``.def`` suffix) is the same as the name of the
  DLL (:ref:`Using_gnatdll` for more information about ``gnatdll``).


.. _MSVS-Style_Import_Library:

.. rubric:: Microsoft-Style Import Library

A Microsoft import library is needed only if you plan to make an
Ada DLL available to applications developed with Microsoft
tools (:ref:`Mixed-Language_Programming_on_Windows`).

To create a Microsoft-style import library for :file:`API.dll` you
should create the :file:`.def` file, then build the actual import library using
Microsoft's ``lib`` utility:

  ::

      $ lib -machine:IX86 -def:API.def -out:API.lib

  If you use the above command, the definition file :file:`API.def` must
  contain a line giving the name of the DLL:

  ::

      LIBRARY      "API"

  See the Microsoft documentation for further details about the usage of
  ``lib``.


.. _Building_DLLs_with_GNAT_Project_files:

Building DLLs with GNAT Project files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: DLLs, building

There is nothing specific to Windows in the build process.
See the *Library Projects* section in the *GNAT Project Manager*
chapter of the *GPRbuild User's Guide*.

Due to a system limitation, you cannot create threads under Windows
when inside the ``DllMain`` routine which is used for auto-initialization
of shared libraries, so you can't have library level tasks in SALs.


.. _Building_DLLs_with_GNAT:

Building DLLs with GNAT
^^^^^^^^^^^^^^^^^^^^^^^

.. index:: DLLs, building

This section explains how to build DLLs using the GNAT built-in DLL
support. With the following procedure, it is straightforward to build
and use DLLs with GNAT.


* Building object files.
  The first step is to build all objects files that are to be included
  into the DLL. This is done using the standard ``gnatmake`` tool.

* Building the DLL.
  To build the DLL, you must use the ``gcc`` :switch:`-shared` and
  :switch:`-shared-libgcc` switches. It's quite simple to use this method:

  ::

      $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ...

  It's important to note that in this case all symbols found in the
  object files are automatically exported. You can restrict
  the set of symbols to export by passing to ``gcc`` a definition
  file (see :ref:`The Definition File <The_Definition_File>`).
  For example:

  ::

      $ gcc -shared -shared-libgcc -o api.dll api.def obj1.o obj2.o ...

  If you use a definition file, you must export the elaboration procedures
  for every package that requires one. Elaboration procedures are named
  using the package name followed by "_E".

* Preparing DLL to be used.
  For the DLL to be used by client programs, the bodies must be hidden
  from it and the :file:`.ali` set with read-only attribute. This is very
  important because otherwise GNAT will recompile all packages and will not
  actually use the code in the DLL. For example:

  ::

      $ mkdir apilib
      $ copy *.ads *.ali api.dll apilib
      $ attrib +R apilib\\*.ali

At this point, you can use the DLL by directly linking
against it. Note that you must use the GNAT shared runtime when using
GNAT shared libraries. You do this with the :switch:`-shared` binder
switch.

  ::

     $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI


.. _Building_DLLs_with_gnatdll:

Building DLLs with gnatdll
^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: DLLs, building

Note that it is preferred to use GNAT Project files
(:ref:`Building_DLLs_with_GNAT_Project_files`) or the built-in GNAT
DLL support (:ref:`Building_DLLs_with_GNAT`) to build DLLs.

This section explains how to build DLLs containing Ada code using
``gnatdll``. These DLLs will be referred to as Ada DLLs in the
remainder of this section.

The steps required to build an Ada DLL that is to be used by Ada as well as
non-Ada applications are as follows:

* You need to mark each Ada entity exported by the DLL with a ``C`` or
  ``Stdcall`` calling convention to avoid any Ada name mangling for the
  entities exported by the DLL
  (see :ref:`Exporting Ada Entities <Exporting_Ada_Entities>`). You can
  skip this step if you plan to use the Ada DLL only from Ada applications.

* Your Ada code must export an initialization routine which calls the routine
  ``adainit`` (generated by ``gnatbind``) to perform the elaboration of
  the Ada code in the DLL (:ref:`Ada_DLLs_and_Elaboration`). The initialization
  routine exported by the Ada DLL must be invoked by the clients of the DLL
  to initialize the DLL.

* When useful, the DLL should also export a finalization routine which calls
  routine ``adafinal`` (also generated by ``gnatbind``) to perform the
  finalization of the Ada code in the DLL (:ref:`Ada_DLLs_and_Finalization`).
  The finalization routine exported by the Ada DLL must be invoked by the
  clients of the DLL when the DLL services are no further needed.

* You must provide a spec for the services exported by the Ada DLL in each
  of the programming languages to which you plan to make the DLL available.

* You must provide a definition file listing the exported entities
  (:ref:`The Definition File <The_Definition_File>`).

* Finally, you must use ``gnatdll`` to produce the DLL and the import
  library (:ref:`Using_gnatdll`).

Note that a relocatable DLL stripped using the ``strip``
binutils tool is no longer relocatable. To build a DLL without
debug information, pass :switch:`-largs -s` to ``gnatdll``. This
restriction does not apply to a DLL built using a Library Project.
See the *Library Projects* section in the *GNAT Project Manager*
chapter of the *GPRbuild User's Guide*.


.. Limitations_When_Using_Ada_DLLs_from Ada:

Limitations When Using Ada DLLs from Ada
""""""""""""""""""""""""""""""""""""""""

When using Ada DLLs from Ada applications there is a limitation you
should be aware of. On Windows, the GNAT run-time is not in a DLL of
its own, so each Ada DLL includes a part of the GNAT run-time. Specifically,
each Ada DLL includes the services of the GNAT run-time that are necessary
for the Ada code inside the DLL. As a result, when an Ada program uses an
Ada DLL there are two independent GNAT run-times: one in the Ada DLL and
one in the main program.

It is therefore not possible to exchange GNAT run-time objects between the
Ada DLL and the main Ada program. Example of GNAT run-time objects are file
handles (e.g., ``Text_IO.File_Type``), tasks types, protected objects
types, etc.

It is completely safe to exchange plain elementary, array or record types,
Windows object handles, etc.


.. _Exporting_Ada_Entities:

Exporting Ada Entities
""""""""""""""""""""""

.. index:: Export table

Building a DLL is a way to encapsulate a set of services usable from any
application. As a result, the Ada entities exported by a DLL should be
exported with the ``C`` or ``Stdcall`` calling conventions to avoid
any Ada name mangling. As an example here is an Ada package
``API``, spec and body, exporting two procedures, a function, and a
variable:


  .. code-block:: ada

     with Interfaces.C; use Interfaces;
     package API is
        Count : C.int := 0;
        function Factorial (Val : C.int) return C.int;

        procedure Initialize_API;
        procedure Finalize_API;
        --  Initialization & Finalization routines. More in the next section.
     private
        pragma Export (C, Initialize_API);
        pragma Export (C, Finalize_API);
        pragma Export (C, Count);
        pragma Export (C, Factorial);
     end API;

  .. code-block:: ada

     package body API is
        function Factorial (Val : C.int) return C.int is
           Fact : C.int := 1;
        begin
           Count := Count + 1;
           for K in 1 .. Val loop
              Fact := Fact * K;
           end loop;
           return Fact;
        end Factorial;

        procedure Initialize_API is
           procedure Adainit;
           pragma Import (C, Adainit);
        begin
           Adainit;
        end Initialize_API;

        procedure Finalize_API is
           procedure Adafinal;
           pragma Import (C, Adafinal);
        begin
           Adafinal;
        end Finalize_API;
     end API;

If the Ada DLL you are building will only be used by Ada applications,
you do not have to export Ada entities with a ``C`` or ``Stdcall``
convention. As an example, the previous package could be written as
follows:

  .. code-block:: ada

     package API is
        Count : Integer := 0;
        function Factorial (Val : Integer) return Integer;

        procedure Initialize_API;
        procedure Finalize_API;
        --  Initialization and Finalization routines.
     end API;

  .. code-block:: ada

     package body API is
        function Factorial (Val : Integer) return Integer is
           Fact : Integer := 1;
        begin
           Count := Count + 1;
           for K in 1 .. Val loop
              Fact := Fact * K;
           end loop;
           return Fact;
        end Factorial;

        ...
        --  The remainder of this package body is unchanged.
     end API;

Note that if you do not export the Ada entities with a ``C`` or
``Stdcall`` convention, you will have to provide the mangled Ada names
in the definition file of the Ada DLL
(:ref:`Creating_the_Definition_File`).


.. _Ada_DLLs_and_Elaboration:

Ada DLLs and Elaboration
""""""""""""""""""""""""

.. index:: DLLs and elaboration

The DLL that you are building contains your Ada code as well as all the
routines in the Ada library that are needed by it. The first thing a
user of your DLL must do is elaborate the Ada code
(:ref:`Elaboration_Order_Handling_in_GNAT`).

To allow this, you must export an initialization routine
(``Initialize_API`` in the previous example), which must be invoked
before using any of the DLL services. This elaboration routine must call
the Ada elaboration routine ``adainit`` generated by the GNAT binder
(:ref:`Binding_with_Non-Ada_Main_Programs`). See the body of
``Initialize_Api`` for an example. Note that the GNAT binder is
automatically invoked during the DLL build process by the ``gnatdll``
tool (:ref:`Using_gnatdll`).

When a DLL is loaded, Windows systematically invokes a routine called
``DllMain``. It should therefore be possible to call ``adainit``
directly from ``DllMain`` without having to provide an explicit
initialization routine. Unfortunately, you can't call
``adainit`` from the ``DllMain`` if your program has library level
tasks because access to the ``DllMain`` entry point is serialized by
the system (that is, only a single thread can execute 'through' it at a
time), which means that the GNAT run-time will deadlock waiting for a
newly created task to complete its initialization.


.. _Ada_DLLs_and_Finalization:

Ada DLLs and Finalization
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: DLLs and finalization

When the services of an Ada DLL are no longer needed, the client code should
invoke the DLL finalization routine, if available. The DLL finalization
routine is in charge of releasing all resources acquired by the DLL. In the
case of the Ada code contained in the DLL, this is achieved by calling
routine ``adafinal`` generated by the GNAT binder
(:ref:`Binding_with_Non-Ada_Main_Programs`).
See the body of ``Finalize_Api`` for an
example. As already pointed out the GNAT binder is automatically invoked
during the DLL build process by the ``gnatdll`` tool
(:ref:`Using_gnatdll`).


.. _Creating_a_Spec_for_Ada_DLLs:

Creating a Spec for Ada DLLs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To use the services exported by the Ada DLL from another programming
language (e.g., C), you have to translate the specs of the exported Ada
entities in that language. For instance in the case of ``API.dll``,
the corresponding C header file could look like:

  .. code-block:: c

     extern int *_imp__count;
     #define count (*_imp__count)
     int factorial (int);

It is important to understand that when building an Ada DLL to be used by
other Ada applications, you need two different specs for the packages
contained in the DLL: one for building the DLL and the other for using
the DLL. This is because the ``DLL`` calling convention is needed to
use a variable defined in a DLL, but when building the DLL, the variable
must have either the ``Ada`` or ``C`` calling convention. As an
example consider a DLL consisting of the following package ``API``:

  .. code-block:: ada

     package API is
        Count : Integer := 0;
        ...
        --  Remainder of the package omitted.
     end API;

After producing a DLL containing package ``API``, the spec that
must be used to import ``API.Count`` from Ada code outside of the
DLL is:

  .. code-block:: ada

     package API is
        Count : Integer;
        pragma Import (DLL, Count);
     end API;


.. _Creating_the_Definition_File:

Creating the Definition File
""""""""""""""""""""""""""""

The definition file is the last file you need to build the DLL. It lists
the exported symbols. As an example, the definition file for a DLL
containing only package ``API`` above (where all the entities are exported
with a ``C`` calling convention) is:

  ::

    EXPORTS
        count
        factorial
        finalize_api
        initialize_api

If the ``C`` calling convention is missing from package ``API``,
the definition file contains the mangled Ada names of the above
entities, which in this case are:

  ::

    EXPORTS
        api__count
        api__factorial
        api__finalize_api
        api__initialize_api


.. _Using_gnatdll:

Using ``gnatdll``
"""""""""""""""""

.. index:: gnatdll

``gnatdll`` is a tool to automate the DLL build process once all the Ada
and non-Ada sources that make up your DLL have been compiled.
``gnatdll`` is actually in charge of two distinct tasks: building both the
static import library for the DLL and the actual DLL. You invoke the
``gnatdll`` command as

  ::

      $ gnatdll [ switches ] list-of-files [ -largs opts ]

where ``list-of-files`` is a list of ALI and object files. The object
file list must be the exact list of objects corresponding to the non-Ada
sources whose services are to be included in the DLL. The ALI file list
must be the exact list of ALI files for the corresponding Ada sources
whose services are to be included in the DLL. If ``list-of-files`` is
missing, only the static import library is generated.

You may specify any of the following switches to ``gnatdll``:


  .. index:: -a (gnatdll)

:switch:`-a[{address}]`
  Build a non-relocatable DLL at ``address``. If you don't specify
  ``address``, ``gnatdll`` uses the default address of ``0x11000000``. By
  default, when this switch is missing, ``gnatdll`` builds a
  relocatable DLL. We advise you to build relocatable DLL.


  .. index:: -bargs (gnatdll)

:switch:`-bargs {opts}`
  Binder switches. Pass ``opts`` to the binder.


  .. index:: -d (gnatdll)

:switch:`-d {dllfile}`
  ``dllfile`` is the name of the DLL. You must specify this switch for
  ``gnatdll`` to do anything. ``gnatdll`` names the generated import library
  algorithmically from ``dllfile`` as shown in the following
  example: if ``dllfile`` is :file:`xyz.dll`, the import library name is
  :file:`libxyz.dll.a`. ``gnatdll`` obtains the name of the definition file (if not specified
  by switch :switch:`-e`) algorithmically from ``dllfile``
  as shown in the following example:
  if ``dllfile`` is :file:`xyz.dll`, the definition
  file used is :file:`xyz.def`.


  .. index:: -e (gnatdll)

:switch:`-e {deffile}`
  ``deffile`` is the name of the definition file.


  .. index:: -g (gnatdll)

:switch:`-g`
  Generate debugging information. This information is stored in the object
  file and copied from there to the final DLL file by the linker,
  where it can be read by the debugger. You must use the
  :switch:`-g` switch if you plan on using the debugger or the symbolic
  stack traceback.


  .. index:: -h (gnatdll)

:switch:`-h`
  Help mode. Displays ``gnatdll`` switch usage information.


  .. index:: -I (gnatdll)

:switch:`-I{dir}`
  Direct ``gnatdll`` to search the ``dir`` directory for source and
  object files needed to build the DLL.
  (:ref:`Search_Paths_and_the_Run-Time_Library_RTL`).


  .. index:: -k (gnatdll)

:switch:`-k`
  Removes the :samp:`@{nn}` suffix from the import library's exported
  names, but keeps them for the link names. You must specify this
  switch if you want to use a ``Stdcall`` function in a DLL for which
  the :samp:`@{nn}` suffix has been removed. This is the case for most
  of the Windows NT DLL for example. This switch has no effect if you
  specify the :switch:`-n` switch.


  .. index:: -l (gnatdll)

:switch:`-l {file}`
  The list of ALI and object files used to build the DLL are listed in
  ``file``, instead of being given in the command line. Each line in
  ``file`` contains the name of an ALI or object file.


  .. index:: -m (gnatdll)

:switch:`-m`
  Generate map file


  .. index:: -n (gnatdll)

:switch:`-n`
  No Import. Do not create the import library.


  .. index:: -q (gnatdll)

:switch:`-q`
  Quiet mode. Do not display unnecessary messages.


  .. index:: -v (gnatdll)

:switch:`-v`
  Verbose mode. Display extra information.


  .. index:: -largs (gnatdll)

:switch:`-largs {opts}`
  Linker switches. Pass ``opts`` to the linker.


.. rubric:: ``gnatdll`` Example

As an example, the command to build a relocatable DLL from :file:`api.adb`
once :file:`api.adb` has been compiled and :file:`api.def` created is

  ::

     $ gnatdll -d api.dll api.ali

The above command creates two files: :file:`libapi.dll.a` (the import
library) and :file:`api.dll` (the actual DLL). If you want to create
only the DLL, just type:

  ::

     $ gnatdll -d api.dll -n api.ali

Alternatively, if you want to create just the import library, type:

  ::

     $ gnatdll -d api.dll


.. rubric:: ``gnatdll`` behind the Scenes

This section details the steps involved in creating a DLL. ``gnatdll``
does these steps for you. Unless you are interested in understanding what
goes on behind the scenes, you should skip this section.

We use the previous example of a DLL containing the Ada package ``API``,
to illustrate the steps necessary to build a DLL. The starting point is a
set of objects that make up the DLL and the corresponding ALI
files. In the case of this example, this means :file:`api.o` and
:file:`api.ali`. To build a relocatable DLL, ``gnatdll`` does
the following:

* builds the base file (:file:`api.base`). A base file gives
  the information necessary to generate relocation information for the
  DLL.

  ::

      $ gnatbind -n api
      $ gnatlink api -o api.jnk -mdll -Wl,--base-file,api.base

  In addition to the base file, the ``gnatlink`` command generates an
  output file :file:`api.jnk`, which can be discarded. The :switch:`-mdll` switch
  asks ``gnatlink`` to generate the routines ``DllMain`` and
  ``DllMainCRTStartup`` that are called by the Windows loader when the DLL
  is loaded into memory.

* uses ``dlltool`` (see :ref:`Using dlltool <Using_dlltool>`) to build the
  export table (:file:`api.exp`). The export table contains the relocation
  information in a form which can be used during the final link to ensure
  that the Windows loader is able to place the DLL anywhere in memory.

  ::

      $ dlltool --dllname api.dll --def api.def --base-file api.base \\
                --output-exp api.exp

* builds the base file using the new export table. Note that
  ``gnatbind`` must be called once again since the binder generated file
  has been deleted during the previous call to ``gnatlink``.

  ::

      $ gnatbind -n api
      $ gnatlink api -o api.jnk api.exp -mdll
            -Wl,--base-file,api.base


* builds the new export table using the new base file and
  generates the DLL import library :file:`libAPI.dll.a`.


  ::

      $ dlltool --dllname api.dll --def api.def --base-file api.base \\
                --output-exp api.exp --output-lib libAPI.a

* Finally, builds the relocatable DLL using the final export table.

  ::

      $ gnatbind -n api
      $ gnatlink api api.exp -o api.dll -mdll


.. _Using_dlltool:

.. rubric:: Using ``dlltool``

``dlltool`` is the low-level tool used by ``gnatdll`` to build
DLLs and static import libraries. This section summarizes the most
common ``dlltool`` switches. You run ``dlltool`` as follows:

  ::

    $ dlltool [`switches`]

``dlltool`` switches include:


.. index:: --base-file (dlltool)

:switch:`--base-file {basefile}`
  Read the base file ``basefile`` generated by the linker. You use this switch
  to create a relocatable DLL.


.. index:: --def (dlltool)

:switch:`--def {deffile}`
  Read the definition file.


.. index:: --dllname (dlltool)

:switch:`--dllname {name}`
  Gives the name of the DLL. You use this switch to embed the name of the
  DLL in the static import library generated by ``dlltool`` with switch
  :switch:`--output-lib`.


.. index:: -k (dlltool)

:switch:`-k`
  Kill :samp:`@{nn}` from exported names
  (:ref:`Windows_Calling_Conventions`
  for a discussion about ``Stdcall``-style symbols).


.. index:: --help (dlltool)

:switch:`--help`
  Prints the ``dlltool`` switches with a concise description.


.. index:: --output-exp (dlltool)

:switch:`--output-exp {exportfile}`
  Generate an export file ``exportfile``. The export file contains the
  export table (list of symbols in the DLL) and is used to create the DLL.


.. index:: --output-lib (dlltool)

:switch:`--output-lib {libfile}`
  Generate a static import library ``libfile``.


.. index:: -v (dlltool)

:switch:`-v`
  Verbose mode.


.. index:: --as (dlltool)

:switch:`--as {assembler-name}`
  Use ``assembler-name`` as the assembler. The default is ``as``.


.. _GNAT_and_Windows_Resources:

GNAT and Windows Resources
^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Resources, windows

Resources are an easy way to add Windows-specific objects to your
application. The objects that you can add as resources include:

* menus

* accelerators

* dialog boxes

* string tables

* bitmaps

* cursors

* icons

* fonts

* version information

You can use a version information resource to embed information into
an executable or a DLL. This information can be viewed using the file
properties from the Windows Explorer. Here's an example of a version
information resource:

  ::

     1 VERSIONINFO
     FILEVERSION     1,0,0,0
     PRODUCTVERSION  1,0,0,0
     BEGIN
       BLOCK "StringFileInfo"
       BEGIN
         BLOCK "080904E4"
         BEGIN
           VALUE "CompanyName", "My Company Name"
           VALUE "FileDescription", "My application"
           VALUE "FileVersion", "1.0"
           VALUE "InternalName", "my_app"
           VALUE "LegalCopyright", "My Name"
           VALUE "OriginalFilename", "my_app.exe"
           VALUE "ProductName", "My App"
           VALUE "ProductVersion", "1.0"
         END
       END

       BLOCK "VarFileInfo"
       BEGIN
         VALUE "Translation", 0x809, 1252
       END
     END

The value ``0809`` (langID) is for the U.K English language and
``04E4`` (charsetID), which is equal to ``1252`` decimal, for
multilingual.

This section explains how to build, compile and use resources. Note that this
section does not cover all resource objects; for a complete description see
the corresponding Microsoft documentation.


.. _Building_Resources:

Building Resources
""""""""""""""""""

.. index:: Resources, building

A resource file is an ASCII file. By convention, resource files have an
:file:`.rc` extension.
The easiest way to build a resource file is to use Microsoft tools
such as ``imagedit.exe`` to build bitmaps, icons and cursors and
``dlgedit.exe`` to build dialogs.
You can always build an :file:`.rc` file yourself by writing a
resource script.

It's not our objective to explain how to write a resource file. A
complete description of the resource script language can be found in
the Microsoft documentation.


.. _Compiling_Resources:

Compiling Resources
"""""""""""""""""""

.. index:: rc
.. index:: windres
.. index:: Resources, compiling

This section describes how you can build a GNAT-compatible (COFF) object file
containing the resources. You do this using the Resource Compiler
``windres`` as follows:

  ::

     $ windres -i myres.rc -o myres.o

By default ``windres`` runs ``gcc`` to preprocess the :file:`.rc`
file. You can specify an alternate preprocessor (usually named
:file:`cpp.exe`) using the ``windres`` :switch:`--preprocessor`
parameter. You can obtain a list of all possible switches by entering
the command ``windres`` :switch:`--help`.

You can also use the Microsoft resource compiler ``rc.exe``
to produce a :file:`.res` file (binary resource file). See the
corresponding Microsoft documentation for further details. In this case,
you need to use ``windres`` to translate the :file:`.res` file to a
GNAT-compatible object file as follows:

  ::

     $ windres -i myres.res -o myres.o


.. _Using_Resources:

Using Resources
"""""""""""""""

.. index:: Resources, using

To include the resource file in your program just add the
GNAT-compatible object file for the resource(s) to the linker
arguments. With ``gnatmake`` you do this using the :switch:`-largs`
switch:

  ::

    $ gnatmake myprog -largs myres.o


.. _Using_GNAT_DLL_from_MSVS:

Using GNAT DLLs from Microsoft Visual Studio Applications
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Microsoft Visual Studio, use with GNAT DLLs

This section describes a common case of mixed GNAT/Microsoft Visual
Studio application development, where the main program is developed
using MSVS and is linked with a DLL developed using GNAT. You should
develop such a mixed application following the general guidelines
outlined above; below is the cookbook-style sequence of steps to
follow:

1. First develop and build the GNAT shared library using a library project
   (let's assume the project is :file:`mylib.gpr`, producing the library :file:`libmylib.dll`):

  ::

     $ gprbuild -p mylib.gpr

2. Produce a :file:`.def` file for the symbols you need to interface
   with, either by hand or automatically with possibly some manual
   adjustments (see :ref:`Creating Definition File Automatically
   <Create_Def_File_Automatically>`):

  ::

     $ dlltool libmylib.dll -z libmylib.def --export-all-symbols

3. Make sure that MSVS command-line tools are accessible on the path.

4. Create the Microsoft-style import library (see :ref:`MSVS-Style Import Library <MSVS-Style_Import_Library>`):

  ::

     $ lib -machine:IX86 -def:libmylib.def -out:libmylib.lib

If you are using a 64-bit toolchain, the above becomes...

  ::

     $ lib -machine:X64 -def:libmylib.def -out:libmylib.lib

5. Build the C ``main``:

  ::

     $ cl /O2 /MD main.c libmylib.lib

6. Before running the executable, make sure you have set the PATH to
   include the DLL or copy the DLL into into the directory containing
   the :file:`.exe`.


.. _Debugging_a_DLL:

Debugging a DLL
^^^^^^^^^^^^^^^

.. index:: DLL debugging

Debugging a DLL is similar to debugging a standard program, but
you have to deal with two different executable parts: the DLL and the
program that uses it. There are the following four possibilities:

* The program and DLL are built with GCC/GNAT.
* The program is built with foreign tools and the DLL is built with
  GCC/GNAT.
* The program is built with GCC/GNAT and the DLL is built with
  foreign tools.

In this section we address only cases one and two above.  Note that
there is no point in trying to debug a DLL with GNU/GDB if there is no
GDB-compatible debugging information in it. To do so, you must use a
debugger compatible with the tools suite used to build the DLL.

.. _Program_and_DLL_Both_Built_with_GCC/GNAT:

Program and DLL Both Built with GCC/GNAT
""""""""""""""""""""""""""""""""""""""""

This is the simplest case. Both the DLL and the program have ``GDB``
compatible debugging information. You can then break anywhere in
the process. Let's suppose the main procedure is named
``ada_main`` and in the DLL there's an entry point named
``ada_dll``.

The DLL (:ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) and
program must have been built with the debugging information (see the GNAT
:switch:`-g` switch). Here are the step-by-step instructions for debugging it:

* Launch ``GDB`` on the main program.

  ::

     $ gdb -nw ada_main

* Start the program and stop at the beginning of the main procedure

  ::

      (gdb) start

  This step is required to be able to set a breakpoint inside
  the DLL. Until the program is run, the DLL is not loaded. This has
  the consequence that the DLL debugging information is also not
  loaded, so it is not possible to set a breakpoint in the DLL.

* Set a breakpoint inside the DLL

  ::

      (gdb) break ada_dll
      (gdb) cont

At this stage, a breakpoint is set inside the DLL. From there on
you can use standard ``GDB`` commands to debug the whole program
(:ref:`Running_and_Debugging_Ada_Programs`).


.. _Program_Built_with_Foreign_Tools_and_DLL_Built_with_GCC/GNAT:

Program Built with Foreign Tools and DLL Built with GCC/GNAT
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

In this case, things are slightly more complex because you can't
start the main program and then break at the beginning to load the DLL and the
associated DLL debugging information. It's not possible to break at the
beginning of the program because there's no ``GDB`` debugging information,
and therefore there's no direct way of getting initial control. This
section addresses this issue by describing some methods that you can use
to break somewhere in the DLL to debug it.

First, suppose that the main procedure is named ``main`` (this is the
case, for example, for some C code built with Microsoft Visual C) and that
there's a DLL named ``test.dll`` containing an Ada entry point named
``ada_dll``.

The DLL (see :ref:`Introduction_to_Dynamic_Link_Libraries_DLLs`) must have
been built with debugging information (see the GNAT :switch:`-g` switch).


.. rubric:: Debugging the DLL Directly

* Determine the executable's starting address

  ::

      $ objdump --file-header main.exe

  The starting address is reported on the last line. For example:

  ::

      main.exe:     file format pei-i386
      architecture: i386, flags 0x0000010a:
      EXEC_P, HAS_DEBUG, D_PAGED
      start address 0x00401010

* Launch the debugger on the executable.

  ::

      $ gdb main.exe

* Set a breakpoint at the starting address and launch the program.

  ::

      $ (gdb) break *0x00401010
      $ (gdb) run

  The program will stop at the specified address.

* Set a breakpoint on a DLL subroutine.

  ::

    (gdb) break ada_dll.adb:45

  Or if you want to break using a symbol on the DLL, you need first to
  select the Ada language (language used by the DLL).

  ::

      (gdb) set language ada
      (gdb) break ada_dll

* Continue the program.

  ::

      (gdb) cont

  This runs the program until it reaches the breakpoint that you've
  set. From that point, you can use standard ``GDB`` commands to debug
  a program as described in
  (:ref:`Running_and_Debugging_Ada_Programs`).

You can also debug the DLL by attaching ``GDB`` to a running process.


.. rubric:: Attaching to a Running Process

.. index:: DLL debugging, attach to process

With ``GDB``, you can always debug a running process by attaching to
it. It's possible to debug a DLL this way. The limitation of this
approach is that the DLL must run long enough to perform the attach
operation. To ensure this, you may want, for example, to insert a
time-wasting loop in the code of the DLL to allow this to happen.

* Launch the main program :file:`main.exe`.

  ::

      $ main

* Use the Windows *Task Manager* to find the process ID. Let's say
  that the process PID for :file:`main.exe` is 208.

* Launch gdb.

  ::

      $ gdb

* Attach to the running process to be debugged.

  ::

      (gdb) attach 208

* Load the process debugging information.

  ::

      (gdb) symbol-file main.exe

* Break somewhere in the DLL.

  ::

      (gdb) break ada_dll

* Continue process execution.

  ::

      (gdb) cont

This last step will resume the process execution and stop at
the breakpoint we have set. From there you can use standard
``GDB`` commands to debug a program, as described in
:ref:`Running_and_Debugging_Ada_Programs`.


.. _Setting_Stack_Size_from_gnatlink:

Setting Stack Size from ``gnatlink``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can specify the program stack size at link time. On most versions
of Windows, starting with XP, this is mostly useful to set the size of
the main stack (environment task). The other task stacks are set with
pragma Storage_Size or with the *gnatbind -d* command. The specified size will
become the reserved memory size of the underlying thread.

Since very old versions of Windows (2000, NT4, etc.) don't allow setting the
reserve size of individual tasks, for those versions the link-time stack size
applies to all tasks, and pragma Storage_Size has no effect.
In particular, Stack Overflow checks are made against this
link-time specified size.

You can set this with ``gnatlink`` using either of the following:


* :switch:`-Xlinker` linker switch

  ::

      $ gnatlink hello -Xlinker --stack=0x10000,0x1000


  This sets the stack reserve size to 0x10000 bytes and the stack commit
  size to 0x1000 bytes.

* :switch:`-Wl` linker switch

  ::

    $ gnatlink hello -Wl,--stack=0x1000000

  This sets the stack reserve size to 0x1000000 bytes. Note that with
  :switch:`-Wl` switch, you can't also set the stack commit size
  because the comma is a separator for this switch.


.. _Setting_Heap_Size_from_gnatlink:

Setting Heap Size from ``gnatlink``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Under Windows systems, it is possible to specify the program heap size from
``gnatlink`` using either of the following:

* :switch:`-Xlinker` linker switch

  ::

      $ gnatlink hello -Xlinker --heap=0x10000,0x1000

  This sets the heap reserve size to 0x10000 bytes and the heap commit
  size to 0x1000 bytes.

* :switch:`-Wl` linker switch

  ::

      $ gnatlink hello -Wl,--heap=0x1000000


  This sets the heap reserve size to 0x1000000 bytes. Note that with
  :switch:`-Wl` switch, you can't also set the heap commit size
  because the comma is a separator for this switch.


.. _Win32_Specific_Addons:

Windows Specific Add-Ons
-------------------------

This section describes the Windows specific add-ons.

.. _Win32Ada:

Win32Ada
^^^^^^^^

``Win32Ada`` is a binding for the Microsoft Win32 API, which you can
easily install using the provided installer. To use it,
you need to use a project file and add a single with_clause
to give you full access to the ``Win32Ada`` binding sources and ensure
that the proper libraries are passed to the linker.

  .. code-block:: gpr

      with "win32ada";
      project P is
         for Sources use ...;
      end P;

To build the application, you just need to call ``gprbuild`` for the
application's project, here :file:`p.gpr`:

  .. code-block:: sh

      gprbuild p.gpr

.. _wPOSIX:

wPOSIX
^^^^^^

``wPOSIX`` is a minimal POSIX binding whose goal is to help with building
cross-platforms applications. This binding is not complete though, as
the Win32 API does not provide the necessary support for all POSIX APIs.

To use the ``wPOSIX`` binding, you need to use a project file and add
a single *with* clause to give you full access to the ``wPOSIX`` binding
sources and ensure that the proper libraries are passed to the linker.

  .. code-block:: gpr

      with "wposix";
      project P is
         for Sources use ...;
      end P;

To build the application, you just need to call ``gprbuild`` for the
application's project, here :file:`p.gpr`:

  .. code-block:: sh

      gprbuild p.gpr


.. _Mac_OS_Topics:

Mac OS Topics
=============

.. index:: OS X

This section describes topics that are specific to Apple's OS X
platform.

Codesigning the Debugger
------------------------

The Darwin Kernel, used by Apple's OS X, requires the debugger to have
special permissions before it's allowed to control other
processes. These permissions are granted by codesigning the GDB
executable. Without these permissions, the debugger will report error
messages such as::

   Starting program: /x/y/foo
   Unable to find Mach task port for process-id 28885: (os/kern) failure (0x5).
   (please check gdb is codesigned - see taskgated(8))

Codesigning requires a certificate.  The following procedure explains
how to create one:

* Start the Keychain Access application (in
  /Applications/Utilities/Keychain Access.app)

* Select the Keychain Access -> Certificate Assistant ->
  Create a Certificate... menu

* Then:

  * Choose a name for the new certificate (this procedure will use
    "gdb-cert" as an example)

  * Set "Identity Type" to "Self Signed Root"

  * Set "Certificate Type" to "Code Signing"

  * Activate the "Let me override defaults" option


* Click several times on "Continue" until the "Specify a Location
  For The Certificate" screen appears, then set "Keychain" to "System"

* Click on "Continue" until the certificate is created

* Finally, in the view, double-click on the new certificate,
  and set "When using this certificate" to "Always Trust"

* Exit the Keychain Access application and restart the computer
  (this is unfortunately required)


Once you've created a certificate as above, you can codesign the debugger
by running the following command in a Terminal:

  ::

     $ codesign -f -s  "gdb-cert"  <gnat_install_prefix>/bin/gdb

with ``gdb-cert`` replaced by the actual certificate name chosen
above, and ``gnat_install_prefix`` replaced by the location where you
installed GNAT.  Also, be sure that users of ``GDB`` are in the Unix
group ``_developer``.

---

### Gcc Ada Doc Gnat Ugn The Gnat Compilation Model (`gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst`)

.. role:: switch(samp)

.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing

.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit


.. _The_GNAT_Compilation_Model:

**************************
The GNAT Compilation Model
**************************

.. index:: ! GNAT compilation model

.. index:: Compilation model

This chapter describes the compilation model used by GNAT. Although
similar to that used by other languages such as C and C++, this model
is substantially different from the traditional Ada compilation models,
which are based on a centralized program library. The chapter covers
the following material:

* Topics related to source file makeup and naming

  * :ref:`Source_Representation`
  * :ref:`Foreign_Language_Representation`
  * :ref:`File_Naming_Topics_and_Utilities`

* :ref:`Configuration_Pragmas`
* :ref:`Generating_Object_Files`
* :ref:`Source_Dependencies`
* :ref:`The_Ada_Library_Information_Files`
* :ref:`Binding_an_Ada_Program`
* :ref:`GNAT_and_Libraries`
* :ref:`Conditional_Compilation`
* :ref:`Mixed_Language_Programming`
* :ref:`GNAT_and_Other_Compilation_Models`
* :ref:`Using_GNAT_Files_with_External_Tools`


.. _Source_Representation:

Source Representation
=====================

.. index:: Latin-1

.. index:: VT, HT, CR, LF, FF

Ada source programs are represented in standard text files, using
Latin-1 coding. Latin-1 is an 8-bit code that includes the familiar
7-bit ASCII set plus additional characters used for
representing foreign languages (see :ref:`Foreign_Language_Representation`
for support of non-USA character sets). The format effector characters
are represented using their standard ASCII encodings, as follows:

    =========== ======================= ===========
     Character          Effect           Code
    ----------- ----------------------- -----------
    :kbd:`VT`    Vertical tab            ``16#0B#``
    :kbd:`HT`    Horizontal tab          ``16#09#``
    :kbd:`CR`    Carriage return         ``16#0D#``
    :kbd:`LF`    Line feed               ``16#0A#``
    :kbd:`FF`    Form feed               ``16#0C#``
    =========== ======================= ===========

Source files are in standard text file format. In addition, GNAT
recognizes a wide variety of stream formats, in which the end of
physical lines is marked by any of the following sequences:
``LF``, ``CR``, ``CR-LF``, or ``LF-CR``. This is useful
in accommodating files imported from other operating systems.

.. index:: pair: End of source file; Source file, end

.. index:: SUB (control character)

The end of a source file is normally represented by the physical end of
file. However, the control character ``16#1A#`` (:kbd:`SUB`) is also
recognized as signalling the end of the source file. Again, this is
provided for compatibility with other, legacy, operating systems where this
code is used to represent the end of file.

.. index:: spec (definition), compilation (definition)

Each file contains a single Ada compilation unit, including any pragmas
associated with the unit. For example, this means you must place a
package declaration (a package *spec*) and the corresponding body in
separate files. An Ada *compilation* (which is a sequence of
compilation units) is represented using a sequence of files. Similarly,
you place each subunit or child unit in a separate file.

.. _Foreign_Language_Representation:

Foreign Language Representation
===============================

GNAT supports the standard character sets defined in Ada as well as
several other non-standard character sets for use in localized versions
of the compiler (:ref:`Character_Set_Control`).

.. _Latin-1:

Latin-1
-------

.. index:: Latin-1

The basic character set is Latin-1. This character set is defined by ISO
standard 8859, part 1. The lower half (character codes ``16#00#``
... ``16#7F#)`` is identical to standard ASCII coding but the upper
half is used to represent additional characters. These include extended letters
used by European languages, such as French accents, the vowels with umlauts
used in German, and the extra letter A-ring used in Swedish.

.. index:: Ada.Characters.Latin_1

For a complete list of Latin-1 codes and their encodings, see the source
file of library unit ``Ada.Characters.Latin_1`` in file
:file:`a-chlat1.ads`.
You may use any of these extended characters freely in character or
string literals. In addition, the extended characters that represent
letters can be used in identifiers.

.. _Other_8-Bit_Codes:

Other 8-Bit Codes
-----------------

GNAT also supports several other 8-bit coding schemes:


.. index:: Latin-2
.. index:: ISO 8859-2

*ISO 8859-2 (Latin-2)*
  Latin-2 letters allowed in identifiers, with uppercase and lowercase
  equivalence.

.. index:: Latin-3
.. index:: ISO 8859-3

*ISO 8859-3 (Latin-3)*
  Latin-3 letters allowed in identifiers, with uppercase and lowercase
  equivalence.


.. index:: Latin-4
.. index:: ISO 8859-4

*ISO 8859-4 (Latin-4)*
  Latin-4 letters allowed in identifiers, with uppercase and lowercase
  equivalence.


.. index:: ISO 8859-5
.. index:: Cyrillic

*ISO 8859-5 (Cyrillic)*
  ISO 8859-5 letters (Cyrillic) allowed in identifiers, with uppercase and
  lowercase equivalence.

.. index:: ISO 8859-15
.. index:: Latin-9

*ISO 8859-15 (Latin-9)*
  ISO 8859-15 (Latin-9) letters allowed in identifiers, with uppercase and
  lowercase equivalence.

.. index:: code page 437 (IBM PC)

*IBM PC (code page 437)*
  This code page is the normal default for PCs in the US. It corresponds
  to the original IBM PC character set. This set has some, but not all, of
  the extended Latin-1 letters, but these letters do not have the same
  encoding as Latin-1. In this mode, these letters are allowed in
  identifiers with uppercase and lowercase equivalence.

.. index:: code page 850 (IBM PC)

*IBM PC (code page 850)*
  This code page is a modification of 437 extended to include all the
  Latin-1 letters, but still not with the usual Latin-1 encoding. In this
  mode, all these letters are allowed in identifiers with uppercase and
  lowercase equivalence.


*Full Upper 8-bit*
  Any character in the range 80-FF is allowed in identifiers and all are
  considered distinct. In other words, there are no uppercase and lowercase
  equivalences in this range. This is useful in conjunction with
  certain encoding schemes used for some foreign character sets (e.g.,
  the typical method of representing Chinese characters on the PC).


*No Upper-Half*
  No upper-half characters in the range 80-FF are allowed in identifiers.
  This gives Ada 83 compatibility for identifier names.

For precise data on the encodings permitted, and the uppercase and lowercase
equivalences that are recognized, see the file :file:`csets.adb` in
the GNAT compiler sources. You will need to obtain a full source release
of GNAT to obtain this file.

.. _Wide_Character_Encodings:

Wide_Character Encodings
------------------------

GNAT allows wide character codes to appear in character and string
literals, and also optionally in identifiers, by means of the following
possible encoding schemes:

*Hex Coding*
  In this encoding, a wide character is represented by the following five
  character sequence::

    ESC a b c d

  where ``a``, ``b``, ``c``, ``d`` are the four hexadecimal
  characters (using uppercase letters) of the wide character code. For
  example, ESC A345 is used to represent the wide character with code
  ``16#A345#``.
  This scheme is compatible with use of the full Wide_Character set.

.. index:: Upper-Half Coding

*Upper-Half Coding*
  The wide character with encoding ``16#abcd#`` where the upper bit is on
  (in other words, 'a' is in the range 8-F) is represented as two bytes,
  ``16#ab#`` and ``16#cd#``. The second byte cannot be a format control
  character, but is not required to be in the upper half. This method can
  be also used for shift-JIS or EUC, where the internal coding matches the
  external coding.

.. index:: Shift JIS Coding

*Shift JIS Coding*
  A wide character is represented by a two-character sequence,
  ``16#ab#`` and
  ``16#cd#``, with the restrictions described for upper-half encoding as
  described above. The internal character code is the corresponding JIS
  character according to the standard algorithm for Shift-JIS
  conversion. You can only use characters defined in the JIS code set table
  with this encoding method.

.. index:: EUC Coding

*EUC Coding*
  A wide character is represented by a two-character sequence
  ``16#ab#`` and ``16#cd#``, with both characters being in the upper
  half. The internal character code is the corresponding JIS character
  according to the EUC encoding algorithm. You can only use characters
  defined in the JIS code set table with this encoding method.


*UTF-8 Coding*
  A wide character is represented using
  UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
  10646-1/Am.2. Depending on the character value, the representation
  is a one, two, or three byte sequence::

    16#0000#-16#007f#: 2#0xxxxxxx#
    16#0080#-16#07ff#: 2#110xxxxx# 2#10xxxxxx#
    16#0800#-16#ffff#: 2#1110xxxx# 2#10xxxxxx# 2#10xxxxxx#

  where the ``xxx`` bits correspond to the left-padded bits of the
  16-bit character value. Note that all lower half ASCII characters
  are represented as ASCII bytes and all upper half characters and
  other wide characters are represented as sequences of upper-half
  (The full UTF-8 scheme allows for encoding 31-bit characters as
  6-byte sequences the use of these sequences is documented in the
  following section on wide wide characters.)


*Brackets Coding*
  In this encoding, a wide character is represented by the following eight
  character sequence::

    [ " a b c d " ]

  where ``a``, ``b``, ``c``, ``d`` are the four hexadecimal characters
  (using uppercase letters) of the wide character code. For example,
  ['A345'] is used to represent the wide character with code
  ``16#A345#``. You can also (though you are not required to) use the
  Brackets coding for upper half characters. For example, you can
  represent the code ``16#A3#`` as ``['A3']``.

  This scheme is compatible with use of the full ``Wide_Character`` set,
  and is also the method used for wide character encoding in some standard
  ACATS (Ada Conformity Assessment Test Suite) test suite distributions.

.. note::

  Some of these coding schemes do not permit the full use of the
  Ada character set. For example, neither Shift JIS nor EUC allow the
  use of the upper half of the Latin-1 set.

.. _Wide_Wide_Character_Encodings:

Wide_Wide_Character Encodings
-----------------------------

GNAT allows wide wide character codes to appear in character and string
literals, and also optionally in identifiers, by means of the following
possible encoding schemes:

*UTF-8 Coding*
  A wide character is represented using
  UCS Transformation Format 8 (UTF-8) as defined in Annex R of ISO
  10646-1/Am.2. Depending on the character value, the representation
  of character codes with values greater than 16#FFFF# is a
  is a four, five, or six byte sequence::

    16#01_0000#-16#10_FFFF#:     11110xxx 10xxxxxx 10xxxxxx
                                 10xxxxxx
    16#0020_0000#-16#03FF_FFFF#: 111110xx 10xxxxxx 10xxxxxx
                                 10xxxxxx 10xxxxxx
    16#0400_0000#-16#7FFF_FFFF#: 1111110x 10xxxxxx 10xxxxxx
                                 10xxxxxx 10xxxxxx 10xxxxxx


  where the ``xxx`` bits correspond to the left-padded bits of the
  32-bit character value.

*Brackets Coding*
  In this encoding, a wide wide character is represented by the following ten or
  twelve byte character sequence::

    [ " a b c d e f " ]
    [ " a b c d e f g h " ]

  where ``a-h`` are the six or eight hexadecimal
  characters (using uppercase letters) of the wide wide character code. For
  example, ["1F4567"] is used to represent the wide wide character with code
  ``16#001F_4567#``.

  This scheme is compatible with use of the full ``Wide_Wide_Character`` set,
  and is also the method used for wide wide character encoding in some standard
  ACATS (Ada Conformity Assessment Test Suite) test suite distributions.


.. _File_Naming_Topics_and_Utilities:

File Naming Topics and Utilities
================================

GNAT has a default file naming scheme, but and also provides you
with a high degree of control over how the names and extensions of your
source files correspond to the Ada compilation units that they
contain.


.. _File_Naming_Rules:

File Naming Rules
-----------------

GNAT determines the default file name by the name of the unit that the
file contains. The name is formed by taking the full expanded name of
the unit, replacing the separating dots with hyphens, and using
lowercase for all letters.

An exception occurs if the file name generated by the above rules starts
with one of the characters
``a``, ``g``, ``i``, or ``s`` and the second character is a
hyphen. In this case, the character tilde is used in place
of the hyphen. This special rule avoids clashes with
the standard names for child units of the packages ``System``, ``Ada``,
``Interfaces``, and ``GNAT``, which use the prefixes
``s-``, ``a-``, ``i-``, and ``g-``,
respectively.

The file extension is :file:`.ads` for a spec and
:file:`.adb` for a body. The following table shows some
examples of these rules.

   ============================ ===============================
   Source File                   Ada Compilation Unit
   ---------------------------- -------------------------------
   :file:`main.ads`              Main (spec)
   :file:`main.adb`              Main (body)
   :file:`arith_functions.ads`   Arith_Functions (package spec)
   :file:`arith_functions.adb`   Arith_Functions (package body)
   :file:`func-spec.ads`         Func.Spec (child package spec)
   :file:`func-spec.adb`         Func.Spec (child package body)
   :file:`main-sub.adb`          Sub (subunit of Main)
   :file:`a~bad.adb`             A.Bad (child package body)
   ============================ ===============================

Following these rules can result in excessively long
file names if corresponding
unit names are long (for example, if child units or subunits are
heavily nested). An option is available to shorten such long file names
(called file name 'krunching'). You may find this particularly useful when
programs being developed with GNAT are to be used on operating systems
with limited file name lengths. :ref:`Using_gnatkr`.

Of course, no file shortening algorithm can guarantee uniqueness over
all possible unit names; if file name krunching is used, it is your
responsibility to ensure no name clashes occur. Alternatively, you
can specify the exact file names that you want used, as described
in the next section. Finally, if your Ada programs are migrating from a
compiler with a different naming convention, you can use the ``gnatchop``
utility to produce source files that follow the GNAT naming conventions.
(For details see :ref:`Renaming_Files_with_gnatchop`.)

Note: in the case of Windows or Mac OS operating systems, case is not
significant. So, for example, on Windows if the canonical name is
:file:`main-sub.adb`, you can use the file name :file:`Main-Sub.adb` instead.
However, case is significant for other operating systems, so, for example,
if you want to use other than canonically cased file names on a Unix system,
you need to follow the procedures described in the next section.

.. _Using_Other_File_Names:

Using Other File Names
----------------------

.. index:: File names

The previous section described the default rules used by
GNAT to determine the file name in which a given unit resides. It is
usually convenient to follow these default rules, and if you follow them,
the compiler knows without being explicitly told where to find all
the files it needs.

.. index:: Source_File_Name pragma

However, in some cases, particularly when a program is imported from
another Ada compiler environment, it may be more convenient for you
to specify which file names contain which units. GNAT allows
arbitrary file names to be used by means of the ``Source_File_Name`` pragma.
The form of this pragma is as shown in the following examples:

.. code-block:: ada

      pragma Source_File_Name (My_Utilities.Stacks,
        Spec_File_Name => "myutilst_a.ada");
      pragma Source_File_name (My_Utilities.Stacks,
        Body_File_Name => "myutilst.ada");

As shown in this example, the first argument for the pragma is the unit
name (in this example a child unit). The second argument has the form
of a named association. The identifier
indicates whether the file name is for a spec or a body;
the file name itself is given by a string literal.

The source file name pragma is a configuration pragma, which means that
normally you will place it in the :file:`gnat.adc`
file used to hold configuration
pragmas that apply to a complete compilation environment.
For more details on how the :file:`gnat.adc` file is created and used
see :ref:`Handling_of_Configuration_Pragmas`.

.. index:: gnat.adc

GNAT allows you to specify completely arbitrary file names using the
source file name pragma. However, if the file name specified has an
extension other than :file:`.ads` or :file:`.adb` you must use a
special syntax when compiling the file. The name on the command line
in this case must be preceded by the special sequence ``-x`` followed
by a space and the name of the language, here ``ada``, as in:

.. code-block:: sh

     $ gcc -c -x ada peculiar_file_name.sim

``gnatmake`` handles non-standard file names in the usual manner (the
non-standard file name for the main program is simply used as the
argument to ``gnatmake``). Note that if the extension is also non-standard,
you must include it in the ``gnatmake`` command; it may not
be omitted.

.. _Alternative_File_Naming_Schemes:

Alternative File Naming Schemes
-------------------------------

.. index:: File naming schemes, alternative

.. index:: File names

The previous section described the use of the ``Source_File_Name``
pragma to allow arbitrary names to be assigned to individual source files.
However, this approach requires one pragma for each file and, especially in
large systems, can result in very long :file:`gnat.adc` files, which can create
a maintenance problem.

.. index:: Source_File_Name pragma

GNAT also provides a facility for specifying systematic file naming schemes
other than the standard default naming scheme previously described. An
alternative scheme for naming is specified by the use of
``Source_File_Name`` pragmas having the following format:

.. code-block:: ada

     pragma Source_File_Name (
        Spec_File_Name  => FILE_NAME_PATTERN
      [ , Casing          => CASING_SPEC]
      [ , Dot_Replacement => STRING_LITERAL ] );

     pragma Source_File_Name (
        Body_File_Name  => FILE_NAME_PATTERN
      [ , Casing          => CASING_SPEC ]
      [ , Dot_Replacement => STRING_LITERAL ] ) ;

     pragma Source_File_Name (
        Subunit_File_Name  => FILE_NAME_PATTERN
      [ , Casing          => CASING_SPEC ]
      [ , Dot_Replacement => STRING_LITERAL ] ) ;

     FILE_NAME_PATTERN ::= STRING_LITERAL
     CASING_SPEC ::= Lowercase | Uppercase | Mixedcase

The ``FILE_NAME_PATTERN`` string shows how the file name is constructed.
It contains a single asterisk character, and the unit name is substituted
systematically for this asterisk. The optional parameter
``Casing`` indicates
whether the unit name is to be all upper-case letters, all lower-case letters,
or mixed-case. If no
``Casing`` parameter is used, the default is all
lower-case.

You use the optional ``Dot_Replacement`` string to replace any periods
that occur in subunit or child unit names. If you don't specify a
``Dot_Replacement`` argument, separating dots appear unchanged in the
resulting file name.  The above syntax indicates that the ``Casing``
argument must appear before the ``Dot_Replacement`` argument, but you
can write these arguments in any order.

As indicated, you can specify different naming schemes for
bodies, specs, and subunits. Quite often, the rule for subunits is the
same as the rule for bodies, in which case, you need not provide
a separate ``Subunit_File_Name`` rule; in this case the
``Body_File_name`` rule is used for subunits as well.

You can also use the separate rule for subunits to implement the rather
unusual case of a compilation environment (e.g., a single directory) which
contains a subunit and a child unit with the same unit name. Although
both units cannot appear in the same partition, the Ada Reference Manual
allows (but does not require) the possibility of the two units coexisting
in the same environment.

File name translation consists of the following steps:

* If there is a specific ``Source_File_Name`` pragma for the given unit,
  this is always used and any general pattern rules are ignored.

* If there is a pattern type ``Source_File_Name`` pragma that applies to
  the unit, the resulting file name is used if the file exists. If
  more than one pattern matches, the latest one is tried first and the
  first attempt that results in a reference to a file that exists is used.

* If no pattern type ``Source_File_Name`` pragma that applies to the unit
  for which the corresponding file exists, the standard GNAT default
  naming rules are used.

As an example of the use of this mechanism, consider a commonly used scheme
in which file names are all lower case, with separating periods copied
unchanged to the resulting file name, specs end with :file:`.1.ada`, and
bodies end with :file:`.2.ada`. GNAT will follow this scheme if the following
two pragmas appear:

.. code-block:: ada

     pragma Source_File_Name
       (Spec_File_Name => ".1.ada");
     pragma Source_File_Name
       (Body_File_Name => ".2.ada");

The default GNAT scheme is equivalent to providing the following
default pragmas:

.. code-block:: ada

     pragma Source_File_Name
       (Spec_File_Name => ".ads", Dot_Replacement => "-");
     pragma Source_File_Name
       (Body_File_Name => ".adb", Dot_Replacement => "-");

Our final example implements a scheme typically used with one of the
legacy Ada 83 compilers, where the separator character for subunits was '__'
(two underscores), specs were identified by adding :file:`_.ADA`, bodies
by adding :file:`.ADA`, and subunits by
adding :file:`.SEP`. All file names were
upper case. Child units were not present, of course, since this was an
Ada 83 compiler, but it seems reasonable to extend this scheme to use
the same double underscore separator for child units.

.. code-block:: ada

     pragma Source_File_Name
       (Spec_File_Name => "_.ADA",
        Dot_Replacement => "__",
        Casing = Uppercase);
     pragma Source_File_Name
       (Body_File_Name => ".ADA",
        Dot_Replacement => "__",
        Casing = Uppercase);
     pragma Source_File_Name
       (Subunit_File_Name => ".SEP",
        Dot_Replacement => "__",
        Casing = Uppercase);


.. index:: ! gnatname

.. _Handling_Arbitrary_File_Naming_Conventions_with_gnatname:

Handling Arbitrary File Naming Conventions with ``gnatname``
------------------------------------------------------------

.. index:: File Naming Conventions

.. _Arbitrary_File_Naming_Conventions:

Arbitrary File Naming Conventions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The GNAT compiler must know the source file name of a compilation unit
in order to compile it.  When using the standard GNAT default file
naming conventions (``.ads`` for specs, ``.adb`` for bodies), it
does not need additional information.

When the source file names do not follow the standard GNAT default
file naming conventions, you must give the GNAT compiler additional
information through a configuration pragmas file
(:ref:`Configuration_Pragmas`) or a project file.  When the
non-standard file naming conventions are well-defined, a small number
of pragmas ``Source_File_Name`` specifying a naming pattern
(:ref:`Alternative_File_Naming_Schemes`) may be sufficient. However,
if the file naming conventions are irregular or arbitrary, you must
define a number of pragma ``Source_File_Name`` for individual
compilation units.  To help maintain the correspondence between
compilation unit names and source file names within the compiler, GNAT
provides a tool ``gnatname`` to generate the required pragmas for a
set of files.

.. _Running_gnatname:

Running ``gnatname``
^^^^^^^^^^^^^^^^^^^^

The usual form of the ``gnatname`` command is:

.. code-block:: sh

      $ gnatname [ switches ]  naming_pattern  [ naming_patterns ]
          [--and [ switches ]  naming_pattern  [ naming_patterns ]]


All of the arguments are optional. If invoked without any arguments,
``gnatname`` will display its usage.

When used with at least one naming pattern, ``gnatname`` attempts to
find all the compilation units in files that follow at least one of the
naming patterns. To find these compilation units,
``gnatname`` uses the GNAT compiler in syntax-check-only mode on all
regular files.

One or several *Naming Patterns* may be given as arguments to ``gnatname``.
Each Naming Pattern is enclosed between double quotes (or single
quotes on Windows).
A Naming Pattern is a regular expression similar to the wildcard patterns
used in file names by the Unix shells or the DOS prompt.

You may call ``gnatname`` with several sections of
directories/patterns.  Sections are separated by the switch
:switch:`--and`. In each section, you must include at least one
pattern. If you don't specify a directory a section, the current
directory (or the project directory if :switch:`-P` is used) is
used.  The options other that the directory switches and the
patterns apply globally even if they are in different sections.

Examples of Naming Patterns are::

     "*.[12].ada"
     "*.ad[sb]*"
     "body_*"    "spec_*"

For a more complete description of the syntax of Naming Patterns,
see the second kind of regular expressions described in :file:`g-regexp.ads`
(the 'Glob' regular expressions).

When invoked without the switch :switch:`-P`, ``gnatname`` will create a
configuration pragmas file :file:`gnat.adc` in the current working directory,
with pragmas ``Source_File_Name`` for each file that contains a valid Ada
unit.

.. _Switches_for_gnatname:

Switches for ``gnatname``
^^^^^^^^^^^^^^^^^^^^^^^^^

Switches for ``gnatname`` must precede any specified Naming Pattern.

You may specify any of the following switches to ``gnatname``:

.. index:: --version (gnatname)

:switch:`--version`
  Display Copyright and version, then exit disregarding, all other options.

.. index:: --help (gnatname)

:switch:`--help`
  If :switch:`--version` was not used, display usage, then exit, disregarding
  all other options.

:switch:`--subdirs={dir}`
  Actual object, library or exec directories are subdirectories <dir> of the
  specified ones.

:switch:`--no-backup`
  Do not create a backup copy of an existing project file.

:switch:`--and`
  Start another section of directories/patterns.

.. index:: -c (gnatname)

:switch:`-c{filename}`
  Create a configuration pragmas file :file:`filename` (instead of the default
  :file:`gnat.adc`).
  There may be zero, one, or more space between :switch:`-c` and
  :file:`filename`.
  :file:`filename` may include directory information. :file:`filename` must be
  writable. You can specify only one switch :switch:`-c`.
  When a switch :switch:`-c` is
  specified, you may not specify switch :switch:`-P` (see below).

.. index:: -d (gnatname)

:switch:`-d{dir}`
  Look for source files in directory :file:`dir`. You may put zero, one or more
  spaces between :switch:`-d` and :file:`dir`.
  :file:`dir` may end with ``/**``, i.e., you may write it the form
  ``root_dir/**``. In this case, the directory ``root_dir`` and all of its
  subdirectories, recursively, have to be searched for sources.
  When you specify a :switch:`-d` switch,
  the current working directory will is not searched for source
  files unless you explicitly specify it with a :switch:`-d`
  or :switch:`-D` switch.
  You may specify several switches :switch:`-d`.
  If :file:`dir` is a relative path, it is relative to the directory of
  the configuration pragmas file specified with switch
  :switch:`-c`,
  or to the directory of the project file specified with switch
  :switch:`-P` or,
  if you don't specify either switch :switch:`-c`
  or switch :switch:`-P`, it's relative to the
  current working directory. The directory
  you specified with switch :switch:`-d` must exist and be readable.

.. index:: -D (gnatname)

:switch:`-D{filename}`
  Look for source files in all directories listed in text file :file:`filename`.
  You may place zero, one or more spaces between :switch:`-D`
  and :file:`filename`.
  :file:`filename` must be an existing, readable text file.
  Each nonempty line in :file:`filename` must be a directory.
  Specifying switch :switch:`-D` is equivalent to specifying as many
  switches :switch:`-d` as there are nonempty lines in
  :file:`file`.

:switch:`-eL`
  Follow symbolic links when processing project files.

  .. index:: -f (gnatname)

:switch:`-f{pattern}`
  Foreign patterns. Using this switch, you can add sources of languages
  other than Ada to the list of sources of a project file, but
  it's only useful if you also specify a :switch:`-P` switch.
  For example,

  .. code-block:: sh

     gnatname -Pprj -f"*.c" "*.ada"

  looks for Ada units in all files with the :file:`.ada` extension,
  and adds the C files with extension :file:`.c` to the list of file
  for project :file:`prj.gpr` .

  .. index:: -h (gnatname)

:switch:`-h`
  Output usage (help) information. The output is written to :file:`stdout`.

  .. index:: -P (gnatname)

:switch:`-P{proj}`

  Create or update project file :file:`proj`. You may place zero, one
  or more space between :switch:`-P` and :file:`proj`. :file:`proj`
  may include directory information. :file:`proj` must be writable.
  There may be only one switch :switch:`-P`.  When you specify switch
  :switch:`-P`, you may not also include switch :switch:`-c`.  On all
  platforms except VMS when ``gnatname`` is invoked for an existing
  project file :file:`<proj>.gpr``, ``gnatname`` creates a backup copy
  of the project file in the project directory with file name
  :file:`<proj>.gpr.saved_x` where ``x`` is the first non negative
  number that creates a unique filename.

  .. index:: -v (gnatname)

:switch:`-v`
  Verbose mode. Output detailed explanation of what it's doing to :file:`stdout`.
  This includes name of the file written, the name of the directories searched,
  and, for each file in those directories whose name matches at least one of
  the Naming Patterns, an indication of whether the file contains a unit,
  and, if so, the name of the unit.

.. index:: -v -v (gnatname)

:switch:`-v -v`
  Very verbose mode. In addition to the output produced in verbose mode
  (a single :switch:`-v` switch),
  for each file in the searched directories whose name matches none of
  the Naming Patterns, ``gnatname`` indicates that there is no match.

  .. index:: -x (gnatname)

:switch:`-x{pattern}`
  Excluded patterns. Using this switch, you can exclude some files
  that otherwise would match the name patterns. For example,

  .. code-block:: sh

      gnatname -x "*_nt.ada" "*.ada"

  looks for Ada units in all files with the :file:`.ada` extension,
  except those whose names end with :file:`_nt.ada`.


.. _Examples_of_gnatname_Usage:

Examples of ``gnatname`` Usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: sh

     $ gnatname -c /home/me/names.adc -d sources "[a-z]*.ada*"

In this example, the directory :file:`/home/me` must already exist
and be writable. In addition, the directory
:file:`/home/me/sources` (specified by
:switch:`-d sources`) must exist and be readable.

Note the optional spaces after :switch:`-c` and :switch:`-d`.

.. code-block:: sh

     $ gnatname -P/home/me/proj -x "*_nt_body.ada"
     -dsources -dsources/plus -Dcommon_dirs.txt "body_*" "spec_*"

Note that you may use several :switch:`-d` switches, even in
conjunction with one or several :switch:`-D` switches. This example
illustrates multiple Naming Patterns and one excluded pattern.


.. _File_Name_Krunching_with_gnatkr:

File Name Krunching with ``gnatkr``
-----------------------------------

.. index:: ! gnatkr

Here we discuss the method used by the compiler to shorten
the default file names chosen for Ada units so that they do not
exceed the maximum length permitted. We also describe the
``gnatkr`` utility, which you can use to determine the result of
applying this shortening.

.. _About_gnatkr:

About ``gnatkr``
^^^^^^^^^^^^^^^^

GNAT requires that the file name must be derived from the unit
name. The default rule is as follows:

* Take the unit name and replace all dots by hyphens.

* If such a replacement occurs in the
  second character position of a name, and the first character is
  :samp:`a`, :samp:`g`, :samp:`s`, or :samp:`i`,
  then replace the dot by the character
  :samp:`~` (tilde)
  instead of a hyphen.

  This exception avoids clashes
  with the standard names for children of System, Ada, Interfaces,
  and GNAT, which use the prefixes
  :samp:`s-`, :samp:`a-`, :samp:`i-`, and :samp:`g-`,
  respectively.

The :switch:`-gnatk{nn}`
switch of the compiler activates a 'krunching'
circuit that limits file names to ``nn`` characters (where ``nn`` is a decimal
integer).

You can use the ``gnatkr`` utility to determine the krunched name for
a given file when krunched to a specified maximum length.

.. _Using_gnatkr:

Using ``gnatkr``
^^^^^^^^^^^^^^^^

You invoke the ``gnatkr`` command as follows:

.. code-block:: sh

      $ gnatkr name [ length ]

``name`` is the uncrunched file name, derived from the name of the unit
in the default manner described in the previous section (i.e., in particular
all dots are replaced by hyphens). You may or may not include an
extension (defined as a suffix of the form period followed by arbitrary
characters other than period) in the filename. If you do, ``gnatkr`` will
preserve it in the output. For example, when krunching :file:`hellofile.ads`
to eight characters, the result will be :file:`hellofil.ads`.

Note: for compatibility with previous versions of ``gnatkr``, you can
use dots in the name instead of hyphens, but ``gnatkr`` always
interprets the last dot as the start of an extension. So if you pass ``gnatkr``
an argument such as :file:`Hello.World.adb`, it treats it
exactly as if the first period had been a hyphen, so, for
example, krunching to eight characters gives the result
:file:`hellworl.adb`.

Note that the result is always all lower case.  Other characters are
folded as required.

``length`` represents the length of the krunched name. The default
if you don't specify it, is 8 characters. A length of zero means
unlimited, in other words don't chop except for system files where the
implied crunching length is always eight characters.

The output is the krunched name. The output has an extension only if the
original argument was a file name with an extension.

.. _Krunching_Method:

Krunching Method
^^^^^^^^^^^^^^^^

The initial file name is determined by the name of the unit that the file
contains. The name is formed by taking the full expanded name of the
unit and replacing the separating dots with hyphens and
using lowercase
for all letters, except that a hyphen in the second character position is
replaced by a tilde if the first character is
:samp:`a`, :samp:`i`, :samp:`g`, or :samp:`s`.
The extension is ``.ads`` for a
spec and ``.adb`` for a body.
Krunching does not affect the extension, but the file name is shortened to
the specified length by following these rules:

* The name is divided into segments separated by hyphens, tildes, or
  underscores and all hyphens, tildes, and underscores are
  eliminated. If this leaves the name short enough, we are done.

* If the name is too long, the longest segment is located (left-most
  if there are two of equal length) and shortened by dropping
  its last character. This is repeated until the name is short enough.

  As an example, consider the krunching of :file:`our-strings-wide_fixed.adb`
  to fit the name into 8 characters, as required by some operating systems::

      our-strings-wide_fixed 22
      our strings wide fixed 19
      our string  wide fixed 18
      our strin   wide fixed 17
      our stri    wide fixed 16
      our stri    wide fixe  15
      our str     wide fixe  14
      our str     wid  fixe  13
      our str     wid  fix   12
      ou  str     wid  fix   11
      ou  st      wid  fix   10
      ou  st      wi   fix   9
      ou  st      wi   fi    8
      Final file name: oustwifi.adb

* The file names for all predefined units are always krunched to eight
  characters. The krunching of these predefined units uses the following
  special prefix replacements:

  ===================== ==============
  Prefix                 Replacement
  --------------------- --------------
  :file:`ada-`           :file:`a-`
  :file:`gnat-`          :file:`g-`
  :file:`interfac es-`   :file:`i-`
  :file:`system-`        :file:`s-`
  ===================== ==============

  These system files have a hyphen in the second character
  position. That's is why normal user files replace such a character
  with a tilde.

  As an example of this special rule, consider
  :file:`ada-strings-wide_fixed.adb`, which gets krunched as follows::

      ada-strings-wide_fixed 22
      a-  strings wide fixed 18
      a-  string  wide fixed 17
      a-  strin   wide fixed 16
      a-  stri    wide fixed 15
      a-  stri    wide fixe  14
      a-  str     wide fixe  13
      a-  str     wid  fixe  12
      a-  str     wid  fix   11
      a-  st      wid  fix   10
      a-  st      wi   fix   9
      a-  st      wi   fi    8
      Final file name: a-stwifi.adb

Of course, no file shortening algorithm can guarantee uniqueness over all
possible unit names. If file name krunching is used, it'is your
responsibility to ensure that no name clashes occur. The utility
program ``gnatkr`` is supplied so that you can conveniently determine the
krunched name of a file.

.. _Examples_of_gnatkr_Usage:

Examples of ``gnatkr`` Usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    $ gnatkr very_long_unit_name.ads      --> velounna.ads
    $ gnatkr grandparent-parent-child.ads --> grparchi.ads
    $ gnatkr Grandparent.Parent.Child.ads --> grparchi.ads
    $ gnatkr grandparent-parent-child     --> grparchi
    $ gnatkr very_long_unit_name.ads/count=6 --> vlunna.ads
    $ gnatkr very_long_unit_name.ads/count=0 --> very_long_unit_name.ads


.. _Renaming_Files_with_gnatchop:

Renaming Files with ``gnatchop``
--------------------------------

.. index:: ! gnatchop

This section discusses how to handle files with multiple units by using
the ``gnatchop`` utility. You will also find this utility useful in renaming
files to meet the standard GNAT default file naming conventions.

.. _Handling_Files_with_Multiple_Units:

Handling Files with Multiple Units
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

GNAT's fundamental compilation model requires that a file submitted to the
compiler contain only one unit and there be a strict correspondence
between the file name and the unit name.

If you want to have your files contain multiple units,
perhaps to maintain compatibility with some other Ada compilation system,
you can use ``gnatname`` to generate or update your project files, which
can be processed by GNAT.

See :ref:`Handling_Arbitrary_File_Naming_Conventions_with_gnatname`
for more details on how to use `gnatname`.

Alternatively, if you want to permanently restructure a set of
'foreign' files so that they match the GNAT rules, and do the
remaining development using the GNAT structure, you can simply use
``gnatchop`` once, generate the new set of files containing only one
unit per file, and work with them from that point on.

Note that if your file containing multiple units starts with a byte order
mark (BOM) specifying UTF-8 encoding, each file generated by gnatchop
will start with a copy of this BOM, meaning that they can be compiled
automatically in UTF-8 mode without you needing to specify an explicit encoding.

.. _Operating_gnatchop_in_Compilation_Mode:

Operating gnatchop in Compilation Mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The basic function of ``gnatchop`` is to take a file with multiple units
and split it into separate files. The boundary between units is reasonably
clear, except for the issue of comments and pragmas. In default mode, the
rule is that any pragmas between units belong to the previous unit, except
that configuration pragmas always belong to the following unit. Any comments
belong to the following unit. These rules
almost always result in the right choice of
the split point without you needing to mark it explicitly and you'll likely
find this default to be what you want. In this default mode, you may not
submit a file containing only configuration pragmas, or one that ends in
configuration pragmas, to ``gnatchop``.

However, using a special switch to activate 'compilation mode',
``gnatchop``
can perform another function, which is to provide exactly the semantics
required by the RM for the handling of configuration pragmas in a compilation.
In the absence of configuration pragmas at the main file level, this
switch has no effect, but it causes such configuration pragmas to be handled
in a very different manner.

First, in compilation mode, if you give ``gnatchop`` a file that consists of
only configuration pragmas, it appends this file to the
:file:`gnat.adc` file in the current directory. This behavior provides
the required behavior described in the RM for the actions to be taken
on submitting such a file to the compiler, namely that these pragmas
should apply to all subsequent compilations in the same compilation
environment. Using GNAT, the current directory, possibly containing a
:file:`gnat.adc` file is the representation
of a compilation environment. For more information on the
:file:`gnat.adc` file, see :ref:`Handling_of_Configuration_Pragmas`.

Second, in compilation mode, if you give ``gnatchop`` a file that
starts with configuration pragmas and contains one or more units, then
configuration pragmas are prepended to each of the chopped
files. This behavior provides the required behavior described in the
RM for the actions to be taken on compiling such a file, namely that
the pragmas apply to all units in the compilation, but not to
subsequently compiled units.

Finally, if configuration pragmas appear between units, they are appended
to the previous unit. This results in the previous unit being illegal,
since the compiler does not accept configuration pragmas that follow
a unit. This provides the required RM behavior that forbids configuration
pragmas other than those preceding the first compilation unit of a
compilation.

For most purposes, you will use ``gnatchop``  in default mode. You only
use the compilation mode described above if you need precisely
accurate behavior with respect to compilations and you have files
that contain multiple units and configuration pragmas. In this
circumstance, the use of ``gnatchop`` with the compilation mode
switch provides the required behavior. This is the mode
in which GNAT processes the ACVC tests.


.. _Command_Line_for_gnatchop:

Command Line for ``gnatchop``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You call ``gnatchop`` as follows:

.. code-block:: sh

     $ gnatchop switches file_name [file_name ...]
           [directory]

The only required argument is the file name of the file to be chopped.
There are no restrictions on the form of this file name. The file itself
contains one or more Ada units, in normal GNAT format, concatenated
together. As shown, more than one file may be presented to be chopped.

When run in default mode, ``gnatchop`` generates one output file in
the current directory for each unit in each of the files.

``directory``, if specified, gives the name of the directory to which
the output files will be written. If you don't specify it, all files are
written to the current directory.

For example, given a
file called :file:`hellofiles` containing

.. code-block:: ada

     procedure Hello;

     with Ada.Text_IO; use Ada.Text_IO;
     procedure Hello is
     begin
        Put_Line ("Hello");
     end Hello;

the command

.. code-block:: sh

     $ gnatchop hellofiles

generates two files in the current directory, one called
:file:`hello.ads` containing the single line that is the procedure spec,
and the other called :file:`hello.adb` containing the remaining text. The
original file is not affected. You can compile these generated files in
the normal manner.

When you invoke ``gnatchop`` on a file that is empty or contains only
empty lines and/or comments, ``gnatchop`` will complete normally, but
won't produce any new file.

For example, given a
file called :file:`toto.txt` containing

.. code-block:: ada

     --  Just a comment

the command

.. code-block:: sh

     $ gnatchop toto.txt

will not produce any new file and will result in the following warnings::

     toto.txt:1:01: warning: empty file, contains no compilation units
     no compilation units found
     no source files written


.. _Switches_for_gnatchop:

Switches for ``gnatchop``
^^^^^^^^^^^^^^^^^^^^^^^^^

``gnatchop`` recognizes the following switches:


.. index:: --version (gnatchop)

:switch:`--version`
  Display copyright and version, then exit, disregarding all other options.

.. index:: --help (gnatchop)

:switch:`--help`
  If :switch:`--version` is not present, display usage, then exit, disregarding
  all other options.

.. index:: -c (gnatchop)

:switch:`-c`
  Causes ``gnatchop`` to operate in compilation mode, in which
  configuration pragmas are handled according to strict RM rules. See the
  previous section for a full description of this mode.

:switch:`-gnat{xxx}`
  This passes the given :switch:`-gnat{xxx}` switch to ``gcc`` which is
  used to parse the given file. Not all *xxx* options make sense,
  but, for example, the use of :switch:`-gnati2` allows ``gnatchop`` to
  process a source file that uses Latin-2 coding for identifiers.

:switch:`-h`
  Causes ``gnatchop`` to generate a brief help summary to the standard
  output file showing usage information.

.. index:: -k (gnatchop)

:switch:`-k{mm}`

  Limit generated file names to the specified number ``mm`` of
  characters.  This is useful if the resulting set of files is
  required to be interoperable with systems which limit the length of
  file names.  You may not place any space between the :switch:`-k`
  and the numeric value. You can omit the numeric value, in which case
  ``gnatchop`` will use a default of :switch:`-k8`, suitable for use
  with DOS-like file systems. If you don't specify a :switch:`-k` switch,
  there is no limit on the length of file names.

.. index:: -p (gnatchop)

:switch:`-p`
  Causes the file modification time stamp of the input file to be
  preserved and used for the time stamp of the output file(s). You may find this
  useful for preserving coherency of time stamps in an environment where
  ``gnatchop`` is used as part of a standard build process.

.. index:: -q (gnatchop)

:switch:`-q`
  Causes output of informational messages indicating the set of generated
  files to be suppressed. Warnings and error messages are unaffected.

.. index:: -r (gnatchop)
.. index:: Source_Reference pragmas

:switch:`-r`
  Generate ``Source_Reference`` pragmas. Use this switch if the output
  files are regarded as temporary and development is to be done from
  of the original unchopped file. This switch causes
  ``Source_Reference`` pragmas to be inserted into each of the
  generated files to refer back to the original file name and line number.
  The result is that all error messages refer back to the original
  unchopped file.
  In addition, the debugging information placed into the object file (when
  the :switch:`-g` switch of ``gcc`` or ``gnatmake`` is
  specified)
  also refers back to this original file so that tools like profilers and
  debuggers will give information in terms of the original unchopped file.

  If the original file to be chopped itself contains
  a ``Source_Reference``
  pragma referencing a third file, ``gnatchop`` respects these
  pragmas and the generated ``Source_Reference`` pragmas
  in the chopped file refer to the original file, with appropriate
  line numbers. This is particularly useful when ``gnatchop``
  is used in conjunction with ``gnatprep`` to compile files that
  contain preprocessing statements and multiple units.

.. index:: -v (gnatchop)

:switch:`-v`
  Causes ``gnatchop`` to operate in verbose mode. It outputs the
  version number and copyright notice as well as exact copies of the
  commands spawned to obtain the information needed to control chopping.

.. index:: -w (gnatchop)

:switch:`-w`
  Overwrite existing file names. Normally, ``gnatchop`` treats it as a
  fatal error if there's already a file with the same name as a
  file it would otherwise output. This can happen either if you've previously
  chopped that file or if the files to be
  chopped contain duplicated units. This switch bypasses this
  check and causes all but the last instance of such duplicated
  units to be skipped.

.. index:: --GCC= (gnatchop)

:switch:`--GCC={xxxx}`
  Specify the path of the GNAT parser to be used. When this switch is used,
  ``gnatchop`` makes no attempt to add a prefix to the GNAT parser executable,
  so it must include the full pathname.


.. _Examples_of_gnatchop_Usage:

Examples of ``gnatchop`` Usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: sh

      $ gnatchop -w hello_s.ada prerelease/files

Chops the source file :file:`hello_s.ada`. The output files are
placed in the directory :file:`prerelease/files`,
overwriting any
files with matching names in that directory (no files in the current
directory are modified).

.. code-block:: sh

      $ gnatchop archive

Chops the source file :file:`archive`
into the current directory. One
useful application of ``gnatchop`` is in sending sets of sources
around, for example in email messages. The required sources are simply
concatenated (for example, using a Unix ``cat``
command) and
``gnatchop`` is used at the other end to reconstitute the original
files.

.. code-block:: sh

      $ gnatchop file1 file2 file3 direc

Chops all units in files :file:`file1`, :file:`file2`, :file:`file3`,
placing the resulting files in the directory :file:`direc`. Note that
if any units occur more than once anywhere within this set of files,
``gnatchop`` generates an error message, and doesn't write any
files. To override this check, use the :switch:`-w` switch, in which
case the last occurrence in the last file will be the one that is
output and ``gnatchop`` will skip earlier duplicate occurrences for
the same unit.

.. _Configuration_Pragmas:

Configuration Pragmas
=====================

.. index:: Configuration pragmas

.. index:: Pragmas, configuration

Configuration pragmas supported by GNAT consist of those pragmas described as
such in the Ada Reference Manual and the
implementation-dependent pragmas that are configuration pragmas.
See the ``Implementation_Defined_Pragmas`` chapter in the
:title:`GNAT_Reference_Manual` for details on these
additional GNAT-specific configuration pragmas.
Most notably, the pragma ``Source_File_Name``, which allows
specifying non-default names for source files, is a configuration
pragma. The following is a complete list of configuration pragmas
recognized by GNAT::

     Ada_83
     Ada_95
     Ada_05
     Ada_2005
     Ada_12
     Ada_2012
     Ada_2022
     Aggregate_Individually_Assign
     Allow_Integer_Address
     Annotate
     Assertion_Policy
     Assume_No_Invalid_Values
     C_Pass_By_Copy
     Check_Float_Overflow
     Check_Name
     Check_Policy
     Component_Alignment
     Convention_Identifier
     Debug_Policy
     Default_Scalar_Storage_Order
     Default_Storage_Pool
     Detect_Blocking
     Disable_Atomic_Synchronization
     Discard_Names
     Elaboration_Checks
     Eliminate
     Enable_Atomic_Synchronization
     Extend_System
     Extensions_Allowed
     External_Name_Casing
     Fast_Math
     Favor_Top_Level
     Ignore_Pragma
     Implicit_Packing
     Initialize_Scalars
     Interrupt_State
     Interrupts_System_By_Default
     License
     Locking_Policy
     No_Component_Reordering
     No_Heap_Finalization
     No_Strict_Aliasing
     Normalize_Scalars
     Optimize_Alignment
     Overflow_Mode
     Overriding_Renamings
     Partition_Elaboration_Policy
     Persistent_BSS
     Prefix_Exception_Messages
     Priority_Specific_Dispatching
     Profile
     Profile_Warnings
     Queuing_Policy
     Rename_Pragma
     Restrictions
     Restriction_Warnings
     Reviewable
     Short_Circuit_And_Or
     Source_File_Name
     Source_File_Name_Project
     SPARK_Mode
     Style_Checks
     Suppress
     Suppress_Exception_Locations
     Task_Dispatching_Policy
     Unevaluated_Use_Of_Old
     Unsuppress
     Use_VADS_Size
     User_Aspect_Definition
     Validity_Checks
     Warning_As_Error
     Warnings
     Wide_Character_Encoding


.. _Handling_of_Configuration_Pragmas:

Handling of Configuration Pragmas
---------------------------------

You can place configuration pragmas either appear at the start of a compilation
unit or in a configuration pragma file that applies to
all compilations performed in a given compilation environment.

Configuration pragmas placed before a library level package specification
are not propagated to the corresponding package body (see RM 10.1.5(8));
they must be added explicitly to the package body.

GNAT includes the ``gnatchop`` utility to provide an automatic
way to handle configuration pragmas that follows the semantics for
compilations (that is, files with multiple units) described in the RM.
See :ref:`Operating_gnatchop_in_Compilation_Mode` for details.
However, for most purposes, you will find it more convenient to edit the
:file:`gnat.adc` file that contains configuration pragmas directly,
as described in the following section.

In the case of ``Restrictions`` pragmas appearing as configuration
pragmas in individual compilation units, the exact handling depends on
the type of restriction.

Restrictions that require partition-wide consistency (like
``No_Tasking``) are
recognized wherever they appear
and can be freely inherited, e.g. from a |withed| unit to the |withing|
unit. This makes sense since the binder will always insist on seeing
consistent us, so any unit not conforming to any restrictions
anywhere in the partition will be rejected and it's better for you to find
that out at compile time rather than bind time.

For restrictions that do not require partition-wide consistency, e.g.
``SPARK`` or ``No_Implementation_Attributes``, the restriction
normally applies only to the unit in which the pragma appears, and not
to any other units.

The exception is ``No_Elaboration_Code``, which always applies to the
entire object file from a compilation, i.e. to the body, spec, and all
subunits.  You can apply this restriction in a configuration pragma
file or you can ace it in the body and/or the spec (in either case it
applies to all the relevant units). You can place it on a subunit only if
you have previously placed it in the body of spec.


.. _The_Configuration_Pragmas_Files:

The Configuration Pragmas Files
-------------------------------

.. index:: gnat.adc

In GNAT, a compilation environment is defined by the current directory
at the time that a compile command is given. This current directory is
searched for a file whose name is :file:`gnat.adc`. If this file is
present, it is expected to contain one or more configuration pragmas
that will be applied to the current compilation.  However, if you
specify the switch :switch:`-gnatA`, GNAT ignores
:file:`gnat.adc`. When used, GNAT adds :file:`gnat.adc` to the
dependencies so that if :file:`gnat.adc` is modified later, the source
will be recompiled on a future invocation of ``gnatmake``.

You can add
configuration pragmas into the :file:`gnat.adc` file
either by running ``gnatchop`` on a source file consisting only of
configuration pragmas or, more conveniently, by directly editing the
:file:`gnat.adc` file, which is a standard format source file.

Besides :file:`gnat.adc`, you may apply additional files containing
configuration pragmas to the current compilation using the
:switch:`-gnatec={path}` switch, where ``path`` must designate an
existing file that contains only configuration pragmas. These
configuration pragmas are in addition to those found in
:file:`gnat.adc` (provided :file:`gnat.adc` is present and you do not
use switch :switch:`-gnatA`).
You can specify multiple :switch:`-gnatec=`  switches.

GNAT will add files containing configuration pragmas specified with switches
:switch:`-gnatec=` to the dependencies, unless they are
temporary files. A file is considered temporary if its name ends in
:file:`.tmp` or :file:`.TMP`. Certain tools follow this naming
convention because they pass information to ``gcc`` via
temporary files that are immediately deleted; it doesn't make sense to
depend on a file that no longer exists. Such tools include
``gprbuild``, ``gnatmake``, and ``gnatcheck``.

By default, configuration pragma files are stored by their absolute
paths in ALI files. You can use the :switch:`-gnateb` switch to
request they be stored instead by just their basename.

If you are using project file, they provide a separate mechanism using
project attributes.

.. --Comment
   See :ref:`Specifying_Configuration_Pragmas` for more details.


.. _Generating_Object_Files:

Generating Object Files
=======================

An Ada program consists of a set of source files and the first step in
compiling the program is generating the corresponding object files.
You generate these by compiling a subset of these source files.
The files you need to compile are the following:

* If a package spec has no body, compile the package spec to produce the
  object file for the package.

* If a package has both a spec and a body, compile the body to produce
  the object file for the package. You need not compile the source
  file for the package spec in this case because there's only one
  object file, which contains the code for both the spec and body of
  the package.

* For a subprogram, compile the subprogram body to produce the object
  file for the subprogram. You need not compile the spec, if such a file is
  present.

.. index:: Subunits

* In the case of subunits, only compile the parent unit. GNAT
  generates a single object file for the entire subunit tree, which
  includes all the subunits.

* Compile child units independently of their parent units (though, of
  course, the spec of all the ancestor unit must be present in order
  to compile a child unit).

  .. index:: Generics

* Compile generic units in the same manner as any other units. The
  object files in this case are small dummy files that contain, at
  most, the flag used for elaboration checking. This is because GNAT
  always handles generic instantiation by means of macro
  expansion. However, you still must compile generic units
  for dependency checking and elaboration purposes.

The preceding rules describe the set of files that must be compiled to
generate all the object files for a program. See the following section on dependencies for more details on computing that set of files.
Each object file has the same
name as the corresponding source file, except that the extension is
:file:`.o`, as usual.

You may wish to compile other files for the purpose of checking their
syntactic and semantic correctness. For example, in the case where a
package has a separate spec and body, you would not normally compile the
spec. However, it is convenient in practice to compile the spec to make
sure it is error-free before compiling clients of this spec because such
compilations will fail if there is an error in the spec.

GNAT provides an option for compiling such files purely for the
purposes of checking correctness; such compilations are not required as
part of the process of building a program. To compile a file in this
checking mode, use the :switch:`-gnatc` switch.

.. _Source_Dependencies:

Source Dependencies
===================

Each object file obviously depends on at least the source file which
is compiled to produce it. Here we are using "depends" in the sense of
a typical ``make`` utility; in other words, an object file depends on
a source file if changes to the source file require the object file to
be recompiled.  In addition to this basic dependency, a given object
may depend on additional source files as follows:

* If a file being compiled |withs| a unit ``X``, the object file
  depends on the file containing the spec of unit ``X``. This includes
  files that are |withed| implicitly either because they are parents
  of |withed| child units or are run-time units required by the
  language constructs used in a particular unit.

* If a file being compiled instantiates a library level generic unit, the
  object file depends on both the spec and body files for this generic
  unit.

* If a file being compiled instantiates a generic unit defined within a
  package, the object file depends on the body file for the package as
  well as the spec file.

.. index:: Inline
.. index:: -gnatn switch

* If a file being compiled contains a call to a subprogram for which
  pragma ``Inline`` applies and you have activated inlining with the
  :switch:`-gnatn` switch, the object file depends on the file containing the
  body of this subprogram as well as on the file containing the spec. Note
  that for inlining to actually occur as a result of the use of this switch,
  you must compile in optimizing mode.

  .. index:: -gnatN switch

  The use of :switch:`-gnatN` activates  inlining optimization
  that is performed by the front end of the compiler. This inlining does
  not require that the code generation be optimized. Like :switch:`-gnatn`,
  the use of this switch generates additional dependencies.

  When using a ``gcc`` or LLVM based back end, the use of
  :switch:`-gnatN` is deprecated and the use of :switch:`-gnatn` is preferred.
  Historically front end inlining was more extensive than back end
  inlining, but that is no longer the case.

* If an object file :file:`O` depends on the proper body of a subunit through
  inlining or instantiation, it depends on the parent unit of the subunit.
  This means that any modification of the parent unit or one of its subunits
  affects the compilation of :file:`O`.

* The object file for a parent unit depends on all its subunit body files.

* The previous two rules means that, for purposes of computing
  dependencies and recompilation, a body and all its subunits are
  treated as an indivisible whole.

  These rules are applied transitively: if unit ``A`` |withs|
  unit ``B``, whose elaboration calls an inlined procedure in package
  ``C``, the object file for unit ``A`` depends on the body of
  ``C``, in file :file:`c.adb`.

  The set of dependent files described by these rules includes all the
  files on which the unit is semantically dependent, as dictated by the
  Ada language standard. However, it is a superset of what the
  standard describes, because it includes generic, inline, and subunit
  dependencies.

  An object file must be recreated by recompiling the corresponding
  source file if any of the source files on which it depends are
  modified. For example, if the ``make`` utility is used to control
  compilation, the rule for an Ada object file must mention all the
  source files on which the object file depends, according to the
  above definition.  Invoking ``gnatmake`` will cause it to determine
  the necessary recompilations.

.. _The_Ada_Library_Information_Files:

The Ada Library Information Files
=================================

.. index:: Ada Library Information files

.. index:: ALI files

Each compilation actually generates two output files. The first of these
is the actual object file that has a :file:`.o` extension. The second is a
text file containing full dependency information. It has the same
name as the source file, but an :file:`.ali` extension.
This file is known as the Ada Library Information (:file:`ALI`) file.
The following information is contained in that file:

* Version information (indicates which version of GNAT was used to compile
  the unit(s) in question)

* Main program information (including priority and time slice settings,
  as well as the wide character encoding used during compilation).

* List of arguments used in the compilation command

* Attributes of the unit, including the configuration pragmas used, an
  indication of whether the compilation was successful, and the exception
  model used.

* A list of relevant restrictions applying to the unit (used for consistency
  checking).

* Categorization information (e.g., use of pragma ``Pure``).

* Information on all |withed| units, including presence of
  ``Elaborate`` or ``Elaborate_All`` pragmas.

* Information from any ``Linker_Options`` pragmas used in the unit

* Information on the use of ``Body_Version`` or ``Version``
  attributes in the unit.

* Dependency information. This is a list of files, together with
  time stamp and checksum information. These are files on which
  the unit depends in the sense that the modification of any of
  these units requires the recompilation of the unit in question.

* Cross-reference data. Contains information on all entities referenced
  in the unit. Used by some tools to provide cross-reference information.

For a full detailed description of the format of the :file:`ALI` file,
see the source of the spec of unit ``Lib.Writ``, contained in file
:file:`lib-writ.ads` in the GNAT compiler sources.


.. _Binding_an_Ada_Program:

Binding an Ada Program
======================

When using languages such as C and C++, once the source files have been
compiled the only remaining step in building an executable program
is linking the object modules together. This means that you can
link an inconsistent version of a program, in which two units have
included different versions of the same header.

The rules of Ada do not permit such an inconsistent program to be built.
For example, if two clients have different versions of the same package,
it is illegal to build a program containing these two clients.
These rules are enforced by the GNAT binder, which also determines an
elaboration order consistent with the Ada rules.

The GNAT binder is run after all the object files for a program have
been created. It is given the name of the main program unit and from
this determines the set of units required by the program by reading the
corresponding ALI files. It generates error messages if the program is
inconsistent or if no valid order of elaboration exists.

If no errors are detected, the binder produces a main program in Ada
that contains calls to the elaboration procedures of those
compilation unit that require them, followed by
a call to the main program. This Ada program is compiled to generate the
object file for the main program. The name of
the Ada file is :file:`b~xxx.adb` (with the corresponding spec
:file:`b~xxx.ads`) where ``xxx`` is the name of the
main program unit.

Finally, the linker is used to build the resulting executable program,
using the object from the main program from the bind step as well as the
object files for the Ada units of the program.


.. _GNAT_and_Libraries:

GNAT and Libraries
==================

.. index:: Library building and referencing

This section describes how to build and use libraries with GNAT and
how to recompile the GNAT run-time library. You should be familiar with the
Project Manager facility (see the *GNAT_Project_Manager* chapter of the
:title:`GPRbuild User's Guide`) before reading this chapter.

.. _Introduction_to_Libraries_in_GNAT:

Introduction to Libraries in GNAT
---------------------------------

A library is, conceptually, a collection of objects which does not have its
own main thread of execution but instead provides certain services to the
applications that use it. A library can be either statically linked with the
application, in which case its code is directly included in the application,
or, on platforms that support it, be dynamically linked, in which case
its code is shared by all applications making use of this library.

GNAT supports both types of libraries.
In the static case, you can provide the compiled code in different ways. The
simplest approach is to directly provide the set of objects resulting from
compilation of the library source files. Alternatively, you can group the
objects into an archive using whatever commands are provided by the operating
system.

In the GNAT environment, a library has these components:

*  Source files,

*  :file:`ALI` files (see :ref:`The_Ada_Library_Information_Files`), and

*  Object files, an archive, or a shared library.

A GNAT library may expose all its source files, which is useful for
documentation purposes. Alternatively, it may expose only the units needed by
an external user to make use of the library, in other words, the specs
reflecting the library services along with all the units needed to compile
those specs, which can include generic bodies or any body implementing an
inlined routine. In the case of *stand-alone libraries* those exposed
units are called *interface units* (:ref:`Stand-alone_Ada_Libraries`).

All compilation units comprising an application, including those in a library,
need to be elaborated in an order partially defined by Ada's semantics. GNAT
computes the elaboration order from the :file:`ALI` files and this is why they
constitute a mandatory part of GNAT libraries.
*Stand-alone libraries* are the exception to this rule because a specific
library elaboration routine is produced independently of the application(s)
using the library.

.. _General_Ada_Libraries:

General Ada Libraries
---------------------


.. _Building_a_library:

Building a library
^^^^^^^^^^^^^^^^^^

The easiest way to build a library is to use the Project Manager,
which supports a special type of project called a *Library Project*
(see the *Library Projects* section in the *GNAT Project Manager*
chapter of the :title:`GPRbuild User's Guide`).

A project is considered a library project when two project-level
attributes are defined in it: ``Library_Name`` and ``Library_Dir``. In
order to control different aspects of library configuration, you can
specify additional optional project-level attributes:

* ``Library_Kind``
    This attribute controls whether the library is to be static or dynamic

* ``Library_Version``
    This attribute specifies the library version. Its value is used
    during dynamic linking of shared libraries to determine if the currently
    installed versions of the binaries are compatible.

* ``Library_Options``

* ``Library_GCC``
    These attributes specify additional low-level options to be used during
    library generation and the commands used to generate the
    library.

The GNAT Project Manager takes complete care of the library maintenance task,
including recompilation of the source files for which objects do not exist
or are not up to date, assembly of the library archive, and installation of
the library (i.e., copying associated source, object and :file:`ALI` files
to the specified location).

Here's a simple library project file:

.. code-block:: gpr

       project My_Lib is
         for Source_Dirs use ("src1", "src2");
         for Object_Dir use "obj";
         for Library_Name use "mylib";
         for Library_Dir use "lib";
         for Library_Kind use "dynamic";
       end My_lib;

and the compilation command to build and install the library:

.. code-block:: sh

     $ gnatmake -Pmy_lib

It's complex to manually perform all the steps required to
produce a library, so we recommend you use the GNAT Project Manager
for this task. In case this is not desired, we discuss the necessary
steps below.

There are various possibilities for compiling the units that make up
the library: for example with a :file:`Makefile`
(:ref:`Using_the_GNU_make_Utility`) or with a conventional script. For
simple libraries, you can also create a dummy main program
that depends upon all the packages that comprise the interface of the
library. You can then pass this dummy main program to ``gnatmake``,
which will ensure all necessary objects are built.

After the above has been accomplished, you should follow the standard procedure
of the underlying operating system to produce the static or shared library.

Here's an example of such a dummy program:

.. code-block:: ada

       with My_Lib.Service1;
       with My_Lib.Service2;
       with My_Lib.Service3;
       procedure My_Lib_Dummy is
       begin
          null;
       end;

Here are the generic commands that will build an archive or a shared library.

.. code-block:: sh

     # compiling the library
     $ gnatmake -c my_lib_dummy.adb

     # we don't need the dummy object itself
     $ rm my_lib_dummy.o my_lib_dummy.ali

     # create an archive with the remaining objects
     $ ar rc libmy_lib.a *.o
     # some systems may require "ranlib" to be run as well

     # or create a shared library
     $ gcc -shared -o libmy_lib.so *.o
     # some systems may require the code to have been compiled with -fPIC

     # remove the object files that are now in the library
     $ rm *.o

     # Make the ALI files read-only so that gnatmake will not try to
     # regenerate the objects that are in the library
     $ chmod -w *.ali

Please note that the library must have a name of the form :file:`lib{xxx}.a`
or :file:`lib{xxx}.so` (or :file:`lib{xxx}.dll` on Windows) in order to
be accessed by the :switch:`-l{xxx}` switch at link time.

.. _Installing_a_library:

Installing a library
^^^^^^^^^^^^^^^^^^^^

.. index:: ADA_PROJECT_PATH
.. index:: GPR_PROJECT_PATH

If you use project files, library installation is part of the library build
process (see the *Installing a Library with Project Files* section of the
*GNAT Project Manager* chapter of the :title:`GPRbuild User's Guide`).

When you're not able to use project files for some reason, you can
also install the library so that the sources needed to use the library
are on the Ada source path and the ALI files & libraries be on the Ada
Object path (see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`),
but we don't recommend doing this.  Alternatively, the system
administrator can place general-purpose libraries in the default
compiler paths, by specifying the libraries' location in the
configuration files :file:`ada_source_path` and
:file:`ada_object_path`. These configuration files must be located in
the GNAT installation tree at the same place as the ``gcc`` spec
file. The location of the ``gcc`` spec file can be determined as follows:

.. code-block:: sh

     $ gcc -v


The configuration files mentioned above have a simple format: each line
must contain one unique directory name.
Those names are added to the corresponding path
in their order of appearance in the file. The names can be either absolute
or relative; in the latter case, they are relative to where theses files
are located.

The files :file:`ada_source_path` and :file:`ada_object_path` might not be
present in a
GNAT installation, in which case, GNAT looks for its run-time library in
the directories :file:`adainclude` (for the sources) and :file:`adalib` (for the
objects and :file:`ALI` files). When the files exist, the compiler does not
look in :file:`adainclude` and :file:`adalib`, and thus the
:file:`ada_source_path` file
must contain the location for the GNAT run-time sources (which can simply
be :file:`adainclude`). In the same way, the :file:`ada_object_path` file must
contain the location for the GNAT run-time objects (which can simply
be :file:`adalib`).

You can also specify a new default path to the run-time library at
compilation time with the :switch:`--RTS=rts-path` switch. You can
thus choose the run-time library you want your program to be
compiled with. This switch is recognized by ``gcc``, ``gnatmake``,
``gnatbind``, ``gnatls``, and all project aware tools.

You can install a library before or after the standard GNAT library by
selecting the ordering the lines in the configuration files. In
general, a library must be installed before the GNAT library if it
redefines any part of it.

.. _Using_a_library:

Using a library
^^^^^^^^^^^^^^^

Once again, the project facility greatly simplifies the use of
libraries. In this context, using a library is just a matter of adding a
|with| clause in your project. For example, to make use of the
library ``My_Lib`` shown in examples in earlier sections, you can
write:

.. code-block:: gpr

       with "my_lib";
       project My_Proj is
         ...
       end My_Proj;

Even if you have a third-party, non-Ada library, you can still use GNAT's
Project Manager facility to provide a wrapper for it. For example, the
following project, when |withed| by your main project, will link with the
third-party library :file:`liba.a`:

.. code-block:: gpr

       project Liba is
          for Externally_Built use "true";
          for Source_Files use ();
          for Library_Dir use "lib";
          for Library_Name use "a";
          for Library_Kind use "static";
       end Liba;

This is an alternative to the use of ``pragma Linker_Options``. It is
especially interesting in the context of systems with several interdependent
static libraries where finding a proper linker order is not easy and best be
left to the tools having visibility over project dependence information.

In order to use an Ada library manually, you need to make sure that this
library is on both your source and object path
(see :ref:`Search_Paths_and_the_Run-Time_Library_RTL`
and :ref:`Search_Paths_for_gnatbind`). Furthermore, when the objects are grouped
in an archive or a shared library, you need to specify the desired
library at link time.

For example, you can use the library :file:`mylib` installed in
:file:`/dir/my_lib_src` and :file:`/dir/my_lib_obj` with the following commands:

.. code-block:: sh

     $ gnatmake -aI/dir/my_lib_src -aO/dir/my_lib_obj my_appl \\
       -largs -lmy_lib

This can be expressed more simply:

.. code-block:: sh

    $ gnatmake my_appl

when the following conditions are met:

* :file:`/dir/my_lib_src` has been added by the user to the environment
  variable :envvar:`ADA_INCLUDE_PATH`, or by the administrator to the file
  :file:`ada_source_path`

* :file:`/dir/my_lib_obj` has been added by the user to the environment
  variable :envvar:`ADA_OBJECTS_PATH`, or by the administrator to the file
  :file:`ada_object_path`

* a pragma ``Linker_Options`` has been added to one of the sources.
  For example:

  .. code-block:: ada

       pragma Linker_Options ("-lmy_lib");

Note that you may also load a library dynamically at
run time given its filename, as illustrated in the GNAT :file:`plugins` example
in the directory :file:`share/examples/gnat/plugins` within the GNAT
install area.

.. _Stand-alone_Ada_Libraries:

Stand-alone Ada Libraries
-------------------------

.. index:: ! Stand-alone libraries

.. _Introduction_to_Stand-alone_Libraries:

Introduction to Stand-alone Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A Stand-alone Library (abbreviated 'SAL') is a library that contains
the necessary code to elaborate the Ada units that are included in the
library. In contrast with an ordinary library, which consists of all
sources, objects and :file:`ALI` files of the library, a SAL may
specify a restricted subset of compilation units to serve as a library
interface. In this case, the fully self-sufficient set of files will
normally consist of an objects archive, the sources of interface
units' specs, and the :file:`ALI` files of interface units.  If an
interface spec contains a generic unit or an inlined subprogram, you
must also provide the body's source; if the units that must be
provided in the source form depend on other units, you must also
provide the source and :file:`ALI` files of those units.

The main purpose of a SAL is to minimize the recompilation overhead of client
applications when a new version of the library is installed. Specifically,
if the interface sources have not changed, client applications don't need to
be recompiled. If, furthermore, a SAL is provided in the shared form and its
version, controlled by ``Library_Version`` attribute, is not changed,
the clients also do not need to be relinked.

SALs also allow the library providers to minimize the amount of library source
text exposed to the clients.  Such 'information hiding' might be useful or
necessary for various reasons.

Stand-alone libraries are also well suited to be used in an executable whose
main routine is not written in Ada.

.. _Building_a_Stand-alone_Library:

Building a Stand-alone Library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

GNAT's Project facility provides a simple way of building and installing
stand-alone libraries; see the *Stand-alone Library Projects* section
in the *GNAT Project Manager* chapter of the :title:`GPRbuild User's Guide`.
To be a Stand-alone Library Project, in addition to the two attributes
that make a project a Library Project (``Library_Name`` and
``Library_Dir``; see the *Library Projects* section in the
*GNAT Project Manager* chapter of the *GPRbuild User's Guide*),
you must define the attribute ``Library_Interface``.  For example:

.. code-block:: gpr

       for Library_Dir use "lib_dir";
       for Library_Name use "dummy";
       for Library_Interface use ("int1", "int1.child");

Attribute ``Library_Interface`` has a non-empty string list value,
each string in the list designating a unit contained in an immediate source
of the project file.

When a Stand-alone Library is built, the binder is first invoked to build
a package whose name depends on the library name
(:file:`b~dummy.ads/b` in the example above).
This binder-generated package includes initialization and
finalization procedures whose
names depend on the library name (``dummyinit`` and ``dummyfinal``
in the example
above). The object corresponding to this package is included in the library.

You must ensure timely (e.g., prior to any use of interfaces in the SAL)
calling of these procedures if a static SAL is built, or if a shared SAL
is built
with the project-level attribute ``Library_Auto_Init`` set to
``"false"``.

For a Stand-Alone Library, only the :file:`ALI` files of the Interface Units
(those that are listed in attribute ``Library_Interface``) are copied to
the Library Directory. As a consequence, only the Interface Units may be
imported from Ada units outside of the library. If other units are imported,
the binding phase will fail.

You can also build an encapsulated library where not only
the code to elaborate and finalize the library is embedded but also
ensure that the library is linked only against static
libraries. That means that an encapsulated library only depends on system
libraries: all other code, including the GNAT runtime, is embedded. To
build an encapsulated library you must set attribute
``Library_Standalone`` to ``encapsulated``:

.. code-block:: gpr

       for Library_Dir use "lib_dir";
       for Library_Name use "dummy";
       for Library_Kind use "dynamic";
       for Library_Interface use ("int1", "int1.child");
       for Library_Standalone use "encapsulated";

The default value for this attribute is ``standard`` in which case
a stand-alone library is built.

You may specify the attribute ``Library_Src_Dir`` for a Stand-Alone
Library. ``Library_Src_Dir`` has a single string value. Its value must
be the path (absolute or relative to the project directory) of an
existing directory. This directory cannot be the object directory or
one of the source directories, but it can be the same as the library
directory. The sources of the Interface Units of the library that are
needed by an Ada client of the library are copied to the designated
directory, called the Interface Copy directory, when the library is
built.  These sources include the specs of the Interface Units, but
they may also include bodies and subunits when pragmas ``Inline`` or
``Inline_Always`` are used or when there is a generic unit in the
spec. Before the sources are copied to the Interface Copy directory,
the building process makes an attempt to delete all files in the
Interface Copy directory.

Building stand-alone libraries by hand is somewhat tedious, but for those
occasions when it is necessary here are the steps that you need to perform:

* Compile all library sources.

* Invoke the binder with the switch :switch:`-n` (No Ada main program),
  with all the :file:`ALI` files of the interfaces, and
  with the switch :switch:`-L` to give specific names to the ``init``
  and ``final`` procedures.  For example:

  .. code-block:: sh

      $ gnatbind -n int1.ali int2.ali -Lsal1

* Compile the binder generated file:

  .. code-block:: sh

      $ gcc -c b~int2.adb

* Link the dynamic library with all the necessary object files,
  passing to the linker the names of the ``init`` (and possibly
  ``final``) procedures for automatic initialization (and finalization).
  You should place the built library in a different directory than
  the object files.

* Copy the ``ALI`` files of the interface to the library directory,
  add in this copy an indication that it is an interface to a SAL
  (i.e., add a word ``SL`` on the line in the :file:`ALI` file that starts
  with letter 'P') and make the modified copy of the :file:`ALI` file
  read-only.

Using SALs is not different from using other libraries
(see :ref:`Using_a_library`).

.. _Creating_a_Stand-alone_Library_to_be_used_in_a_non-Ada_context:

Creating a Stand-alone Library to be used in a non-Ada context
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It's easy for you to adapt the SAL build procedure discussed above for
use of a SAL in a non-Ada context.

The only extra step required is to ensure that library interface subprograms
are compatible with the main program, by means of ``pragma Export``
or ``pragma Convention``.

Here's an example of simple library interface for use with C main program:

.. code-block:: ada

       package My_Package is

          procedure Do_Something;
          pragma Export (C, Do_Something, "do_something");

          procedure Do_Something_Else;
          pragma Export (C, Do_Something_Else, "do_something_else");

       end My_Package;

On the C side, you must provide a 'foreign' view of the
library interface; remember that it should contain elaboration routines in
addition to interface subprograms.

The example below shows the content of :file:`mylib_interface.h` (note
that there is no rule for the naming of this file, any name can be used)

.. code-block:: c

       /* the library elaboration procedure */
       extern void mylibinit (void);

       /* the library finalization procedure */
       extern void mylibfinal (void);

       /* the interface exported by the library */
       extern void do_something (void);
       extern void do_something_else (void);

Libraries built as explained above can be used from any program, provided
the elaboration procedures (named ``mylibinit`` in the previous
example) are called before any library services are used. Any number of
libraries can be called from a single executable as long as the elaboration
procedure of each library is called.

Below is an example of a C program that uses the ``mylib`` library.

.. code-block:: c

       #include "mylib_interface.h"

       int
       main (void)
       {
          /* First, elaborate the library before using it */
          mylibinit ();

          /* Main program, using the library exported entities */
          do_something ();
          do_something_else ();

          /* Library finalization at the end of the program */
          mylibfinal ();
          return 0;
       }

Note that invoking any library finalization procedure generated by
``gnatbind`` shuts down the Ada run-time environment.
Consequently, the
finalization of all Ada libraries must be performed at the end of the program.
No call to these libraries or to the Ada run-time library should be made
after the finalization phase.

Information on limitations of binding Ada code in non-Ada contexts can be
found under :ref:`Binding_with_Non-Ada_Main_Programs`.

Note also that you must take special care with multi-tasking
applications. In that case, the initialization and finalization
routines are not protected against concurrent access. If you need such
requirement, you must ensure it at the application level
using a specific operating system services like a mutex or a
critical-section.

.. _Restrictions_in_Stand-alone_Libraries:

Restrictions in Stand-alone Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You should use the pragmas listed below with caution inside libraries,
since they can create incompatibilities with other Ada libraries:

* pragma ``Locking_Policy``
* pragma ``Partition_Elaboration_Policy``
* pragma ``Queuing_Policy``
* pragma ``Task_Dispatching_Policy``
* pragma ``Unreserve_All_Interrupts``

When using a library that contains such pragmas, the user of the
library must ensure that all libraries use the same pragmas with the
same values. Otherwise, ``Program_Error`` will be raised during the
elaboration of the conflicting libraries. You should document the
usage of these pragmas and its consequences for the user.

Similarly, the traceback in the exception occurrence mechanism should be
enabled or disabled in a consistent manner across all libraries.
Otherwise, ``Program_Error`` will be raised during the elaboration of the
conflicting libraries.

If you use the ``Version`` or ``Body_Version``
attributes inside a library, you need to
perform a ``gnatbind`` step that specifies all :file:`ALI` files in all
libraries so that version identifiers can be properly computed.
In practice these attributes are rarely used, so this is unlikely
to be a consideration.

.. _Rebuilding_the_GNAT_Run-Time_Library:

Rebuilding the GNAT Run-Time Library
------------------------------------

.. index:: GNAT Run-Time Library, rebuilding
.. index:: Building the GNAT Run-Time Library
.. index:: Rebuilding the GNAT Run-Time Library
.. index:: Run-Time Library, rebuilding

You may need to recompile the GNAT library in various debugging or
experimentation contexts. The GNAT distribution provides a project
file called :file:`libada.gpr` to do that; it can be found in the
directory containing the GNAT library. The location of this directory
depends on the way the GNAT environment has been installed and can be
determined by means of the command:

.. code-block:: sh

      $ gnatls -v

The last entry in the source search path usually contains the
GNAT library (the :file:`adainclude` directory).

This project file contains its own documentation and, in particular, the
set of instructions needed to rebuild a new library and to use it.

Note that rebuilding the GNAT Run-Time is only recommended for temporary
experiments or debugging and is not supported for other purposes.

.. index:: ! Conditional compilation

.. _Conditional_Compilation:

Conditional Compilation
=======================

This section presents some guidelines for modeling conditional compilation in Ada and describes the
gnatprep preprocessor utility.

.. index:: ! Conditional compilation

.. _Modeling_Conditional_Compilation_in_Ada:

Modeling Conditional Compilation in Ada
---------------------------------------

You may want to arrange for a single source program
to serve multiple purposes, where it is compiled in different
ways to achieve these different goals. Some examples of the
need for this feature are

* Adapting a program to a different hardware environment
* Adapting a program to a different target architecture
* Turning debugging features on and off
* Arranging for a program to compile with different compilers

In C, or C++, the typical approach is to use the preprocessor
defined as part of the language. The Ada language does not
contain such a feature. This is not an oversight, but rather a very
deliberate design decision, based on the experience that overuse of
the preprocessing features in C and C++ can result in programs that
are extremely difficult to maintain. For example, if we have ten
switches that can be on or off, this means that there are a thousand
separate programs, any one of which might not even be syntactically
correct, and, even if syntactically correct,
might not work correctly. Testing all combinations can quickly become
impossible.

Nevertheless, the need to tailor programs certainly exists and in
this section we will discuss how this can
be achieved using Ada in general and GNAT in particular.

.. _Use_of_Boolean_Constants:

Use of Boolean Constants
^^^^^^^^^^^^^^^^^^^^^^^^

In the case where the difference is simply which code
sequence is executed, the cleanest solution is to use Boolean
constants to control which code is executed.

.. code-block:: ada

      FP_Initialize_Required : constant Boolean := True;
      ...
      if FP_Initialize_Required then
      ...
      end if;

Not only will the code inside the ``if`` statement not be executed if
the constant Boolean is ``False``, but it will also be completely
deleted from the program.
However, the code is only deleted after the ``if`` statement block
has been checked for syntactic and semantic correctness.
(In contrast, with preprocessors the code is deleted before the
compiler ever gets to see it, so it is not checked until the switch
is turned on.)

.. index:: Preprocessors (contrasted with conditional compilation)

Typically the Boolean constants will be in a separate package,
something like:

.. code-block:: ada

       package Config is
          FP_Initialize_Required : constant Boolean := True;
          Reset_Available        : constant Boolean := False;
          ...
       end Config;

You would write the ``Config`` package multiple forms for various targets,
with an appropriate script selecting the version of ``Config`` needed.
Then, any other unit requiring conditional compilation can do a |with|
of ``Config`` to make the constants visible.

.. _Debugging_-_A_Special_Case:

Debugging - A Special Case
^^^^^^^^^^^^^^^^^^^^^^^^^^

A common use of conditional code is to execute statements (for example
dynamic checks, or output of intermediate results) under control of a
debug switch, so that the debugging behavior can be turned on and off.
You can do this by using a Boolean constant to control whether the debug code
is active:

.. code-block:: ada

       if Debugging then
          Put_Line ("got to the first stage!");
       end if;

or

.. code-block:: ada

       if Debugging and then Temperature > 999.0 then
          raise Temperature_Crazy;
       end if;

.. index:: pragma Assert

Since this is a common case, GNAT provides special features to deal
with this in a convenient manner. For the case of tests, Ada 2005 has
added a pragma ``Assert`` that you can use for such tests. This pragma
is modeled on the ``Assert`` pragma that has always been available in
GNAT, so you can use this feature with GNAT even if you are not using
Ada 2005 features.  The use of pragma ``Assert`` is described in the
:title:`GNAT_Reference_Manual`, but as an example, the last test could
be written:

.. code-block:: ada

       pragma Assert (Temperature <= 999.0, "Temperature Crazy");

or simply

.. code-block:: ada

       pragma Assert (Temperature <= 999.0);

In both cases, if assertions are active and the temperature is
excessive, the exception ``Assert_Failure`` is raised with the
exception message using the specified string in the first case or a
string indicating the location of the pragma in the second case.

.. index:: pragma Assertion_Policy

You can turn assertions on and off by using the ``Assertion_Policy``
pragma.

.. index:: -gnata switch

This is an Ada 2005 pragma that is implemented in all modes by
GNAT. Alternatively, you can use the :switch:`-gnata` switch
to enable assertions from the command line, which also applies to
all versions of Ada.

.. index:: pragma Debug

For the example above with the ``Put_Line``, the GNAT-specific pragma
``Debug`` can be used:

.. code-block:: ada

       pragma Debug (Put_Line ("got to the first stage!"));

If debug pragmas are enabled, the argument, which must be of the form
of a procedure call, is executed (in this case, ``Put_Line`` is
called).  You can specify only one call, but you can of course include
a special debugging procedure containing any code you like in the
program and call it in a pragma ``Debug`` argument as needed.

One advantage of pragma ``Debug`` over the ``if Debugging then``
construct is that pragma ``Debug`` can appear in declarative contexts,
such as at the very beginning of a procedure, before local declarations have
been elaborated.

.. index:: pragma Debug_Policy

You can enable debug pragmas using either the :switch:`-gnata` switch that also
controls assertions, or with a separate Debug_Policy pragma.

The latter pragma is new in the Ada 2005 versions of GNAT (but it can be used
in Ada 95 and Ada 83 programs as well) and is analogous to
pragma ``Assertion_Policy`` to control assertions.

``Assertion_Policy`` and ``Debug_Policy`` are configuration pragmas,
and thus can appear in :file:`gnat.adc` if you are not using a
project file or in the file designated to contain configuration pragmas
in a project file.
They then apply to all subsequent compilations. In practice the use of
the :switch:`-gnata` switch is often the most convenient method of controlling
the status of these pragmas.

Note that a pragma is not a statement, so in contexts where a statement
sequence is required, you can't just write a pragma on its own. You have
to add a ``null`` statement.

.. code-block:: ada

       if ... then
          ... -- some statements
       else
          pragma Assert (Num_Cases < 10);
          null;
       end if;

.. _Conditionalizing_Declarations:

Conditionalizing Declarations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In some cases it may be necessary to conditionalize declarations to meet
different requirements. For example we might want a bit string whose length
is set to meet some hardware message requirement.

This may be possible using declare blocks controlled
by conditional constants:

.. code-block:: ada

       if Small_Machine then
          declare
             X : Bit_String (1 .. 10);
          begin
             ...
          end;
       else
          declare
             X : Large_Bit_String (1 .. 1000);
          begin
             ...
          end;
       end if;

Note that in this approach, both declarations are analyzed by the
compiler so this can only be used where both declarations are legal,
even though one of them will not be used.

Another approach is to define integer constants, e.g., ``Bits_Per_Word``,
or Boolean constants, e.g., ``Little_Endian``, and then write declarations
that are parameterized by these constants. For example

.. code-block:: ada

       for Rec use
         Field1 at 0 range Boolean'Pos (Little_Endian) * 10 .. Bits_Per_Word;
       end record;

If ``Bits_Per_Word`` is set to 32, this generates either

.. code-block:: ada

       for Rec use
         Field1 at 0 range 0 .. 32;
       end record;

for the big endian case, or

.. code-block:: ada

       for Rec use record
           Field1 at 0 range 10 .. 32;
       end record;

for the little endian case. Since a powerful subset of Ada expression
notation is usable for creating static constants, clever use of this
feature can often solve quite difficult problems in conditionalizing
compilation (note incidentally that in Ada 95, the little endian
constant was introduced as ``System.Default_Bit_Order``, so you don't
need to define this one yourself).

.. _Use_of_Alternative_Implementations:

Use of Alternative Implementations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In some cases, none of the approaches described above are adequate. This
can occur, for example, if the set of declarations required is radically
different for two different configurations.

In this situation, the official Ada way of dealing with conditionalizing
such code is to write separate units for the different cases. As long as
this doesn't result in excessive duplication of code, you can do this
without creating maintenance problems. The approach is to share common
code as far as possible and then isolate the code and declarations
that are different. Subunits are often a convenient method for breaking
out a piece of a unit that you need to be conditionalized, with separate files
for different versions of the subunit for different targets, where the
build script selects the right one to give to the compiler.

.. index:: Subunits (and conditional compilation)

As an example, consider a situation where a new feature in Ada 2005
allows something to be done in a really nice way. But your code must be able
to compile with an Ada 95 compiler. Conceptually you want to say:

.. code-block:: ada

       if Ada_2005 then
          ... neat Ada 2005 code
       else
          ... not quite as neat Ada 95 code
       end if;

where ``Ada_2005`` is a Boolean constant.

But this won't work when ``Ada_2005`` is set to ``False``,
since the ``then`` clause will be illegal for an Ada 95 compiler.
(Recall that although such unreachable code would eventually be deleted
by the compiler, it still needs to be legal.  If it uses features
introduced in Ada 2005, it's still illegal in Ada 95.)

So instead, we write

.. code-block:: ada

       procedure Insert is separate;

Then we have two files for the subunit ``Insert``, with the two sets of
code.
If the package containing this is called ``File_Queries``, then we might
have two files

* :file:`file_queries-insert-2005.adb`
* :file:`file_queries-insert-95.adb`

and the build script renames the appropriate file to :file:`file_queries-insert.adb` and then carries out the compilation.

This can also be done with project files' naming schemes. For example:

.. code-block:: gpr

       for body ("File_Queries.Insert") use "file_queries-insert-2005.ada";

Note also that with project files, you should use a different extension
than :file:`ads` / :file:`adb` for alternative versions. Otherwise, a naming
conflict may arise through another commonly used feature: declaring as part
of the project a set of directories containing all the sources obeying the
default naming scheme.

The use of alternative units is certainly feasible in all situations,
and for example the Ada part of the GNAT run-time is conditionalized
based on the target architecture using this approach. As a specific example,
consider the implementation of the AST feature in VMS. There is one
spec: :file:`s-asthan.ads` which is the same for all architectures, and three
bodies:

* :file:`s-asthan.adb`
    used for all non-VMS operating systems

* :file:`s-asthan-vms-alpha.adb`
    used for VMS on the Alpha

* :file:`s-asthan-vms-ia64.adb`
    used for VMS on the ia64

The dummy version :file:`s-asthan.adb` simply raises exceptions noting that
this operating system feature is not available and the two remaining
versions interface with the corresponding versions of VMS to provide
VMS-compatible AST handling. The GNAT build script knows the architecture
and operating system, and automatically selects the right version,
renaming it if necessary to :file:`s-asthan.adb` before the run-time build.

Another style for arranging alternative implementations is through
Ada's access-to-subprogram facility.  In case some functionality is to
be conditionally included, you can declare an access-to-procedure
variable ``Ref`` that is initialized to designate a 'do nothing'
procedure, and then invoke ``Ref.all`` when appropriate.  Then, in,
some library package, set ``Ref`` to ``Proc'Access`` for some
procedure ``Proc`` that performs the relevant processing.  The
initialization only occurs if the library package is included in the
program.  The same idea can also be implemented using tagged types and
dispatching calls.

.. _Preprocessing:

Preprocessing
^^^^^^^^^^^^^

.. index:: Preprocessing

Although it is quite possible to conditionalize code without the use of
C-style preprocessing, as described in the cases above, it is
nevertheless convenient in some cases to use the C approach. Moreover,
older Ada compilers have often provided some preprocessing capability,
so legacy code may depend on this approach, even though it is not
standard.

To accommodate such use, GNAT provides a preprocessor (modeled to a large
extent on the various preprocessors that have been used
with legacy code on other compilers, to enable easier transition).

.. index:: gnatprep

You can use the preprocessor used in two different modes. You can use it
separately from the compiler to generate a separate output source file,
which you then feed to the compiler as a separate step. This is the
``gnatprep`` utility, whose use is fully described in
:ref:`Preprocessing_with_gnatprep`.

The preprocessing language allows such constructs as

.. code-block:: c

       #if DEBUG or else (PRIORITY > 4) then
          sequence of declarations
       #else
          completely different sequence of declarations
       #end if;

The values of the symbols ``DEBUG`` and ``PRIORITY`` can be
defined either on the command line or in a separate file.

The other way of running the preprocessor is even closer to the C style and
often more convenient. In this approach, the preprocessing is integrated into
the compilation process. You pass the compiler the preprocessor input, which
includes ``#if`` lines etc, and the compiler carries out the
preprocessing internally and compiles the resulting output.
For more details on this approach, see :ref:`Integrated_Preprocessing`.

.. _Preprocessing_with_gnatprep:

Preprocessing with ``gnatprep``
-------------------------------

.. index:: ! gnatprep
.. index:: Preprocessing (gnatprep)

This section discusses how to you can use GNAT's ``gnatprep`` utility
for simple preprocessing.  Although designed for use with GNAT,
``gnatprep`` does not depend on any special GNAT features.  For
further discussion of conditional compilation in general, see
:ref:`Conditional_Compilation`.

.. _Preprocessing_Symbols:

Preprocessing Symbols
^^^^^^^^^^^^^^^^^^^^^

Preprocessing symbols are defined in *definition files* and referenced in the
sources to be preprocessed. A preprocessing symbol is an identifier, following
normal Ada (case-insensitive) rules for its syntax, with the restriction that
all characters need to be in the ASCII set (no accented letters).

.. _Using_gnatprep:

Using ``gnatprep``
^^^^^^^^^^^^^^^^^^

To call ``gnatprep`` use:

.. code-block:: sh

    $ gnatprep [ switches ] infile outfile [ deffile ]

where

* *switches*
    is an optional sequence of switches as described in the next section.

* *infile*
    is the full name of the input file, which is an Ada source
    file containing preprocessor directives.

* *outfile*
    is the full name of the output file, which is an Ada source
    in standard Ada form. When used with GNAT, this file name will
    normally have an ``ads`` or ``adb`` suffix.

* ``deffile``
    is the full name of a text file containing definitions of
    preprocessing symbols to be referenced by the preprocessor. You
    can omit this argument and instead use the :switch:`-D` switch.


.. _Switches_for_gnatprep:

Switches for ``gnatprep``
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: --version (gnatprep)

:switch:`--version`
  Display copyright and version, then exit, disregarding all other options.

.. index:: --help (gnatprep)

:switch:`--help`
  If :switch:`--version` was not used, display usage and then exit, disregarding
  all other options.

.. index:: -b (gnatprep)

:switch:`-b`
  Causes both preprocessor lines and the lines deleted by
  preprocessing to be replaced by blank lines in the output source file,
  preserving line numbers in the output file.

.. index:: -c (gnatprep)

:switch:`-c`
  Causes both preprocessor lines and the lines deleted
  by preprocessing to be retained in the output source as comments marked
  with the special string ``"--! "``. This option also results in line numbers
  being preserved in the output file.

.. index:: -C (gnatprep)

:switch:`-C`
  Causes comments to be scanned. Normally comments are ignored by
  ``gnatprep``.  If you specify this option, ``gnatprep`` scans
  comments and any $symbol substitutions performed as in program
  text. You will find this particularly useful when structured
  comments are used (e.g., for programs written in a pre-2014 version
  of the SPARK Ada subset). This switch is not available
  when doing integrated preprocessing (it would be useless in this
  context since comments are always ignored by the compiler).

.. index:: -D (gnatprep)

:switch:`-D{symbol}[={value}]`
  Defines a new preprocessing symbol with the specified value. If you
  don't specify a value, the symbol is defined to be ``True``. You can
  use this switch instead of providing a definition file.

.. index:: -e (gnatprep)

:switch:`-e`
  Causes both preprocessor lines and the lines deleted by
  preprocessing to be replaced by empty comment lines marked
  with ``"--!"`` (and no other text) in the output source file,
  preserving line numbers in the output file. This option can
  be useful as an alternative to :switch:`-b` and :switch:`-c`
  when compilation style switches like :switch:`-gnatyu` or
  :switch:`-gnatyM` are used (to avoid warnings about multiple
  blank lines or lines too long).

.. index:: -r (gnatprep)

:switch:`-r`
  Causes ``gnatprep`` to generate a ``Source_Reference`` pragma that
  references the original input file, so that error messages will use
  the file name of this original file. The use of this switch implies
  that preprocessor lines are not to be removed from the file, so
  the :switch:`-b` and :switch:`-c` are always enabled.

  If the file to be preprocessed contains multiple units, you
  must call ``gnatchop`` on the the output file from
  ``gnatprep``. If a ``Source_Reference`` pragma is present
  in the preprocessed file, it will be respected by
  ``gnatchop -r``
  so that the final chopped files will correctly refer to the original
  input source file passed to ``gnatprep``.

.. index:: -s (gnatprep)

:switch:`-s`
  Causes a sorted list of symbol names and values to be
  listed on the standard output file.

.. index:: -T (gnatprep)

:switch:`-T`
  Use LF as line terminators when writing files. By default the line terminator
  of the host (LF under unix, CR/LF under Windows) is used.

.. index:: -u (gnatprep)

:switch:`-u`
  Causes undefined symbols to be treated as having the value ``False``
  in the context of a preprocessor test. If you don't specify this
  switch, ``gnatprep`` will treat an undefined symbol in a ``#if`` or
  ``#elsif`` test as an error.

.. index:: -v (gnatprep)

:switch:`-v`
  Verbose mode: generates more output about what is done.

Note: if you don't specify either :switch:`-b` or :switch:`-c`,
then preprocessor lines and
deleted lines are completely removed from the output, unless you specify
:switch:`-r`, in which case ``gnatprep`` enables the :switch:`-b` switch.


.. _Form_of_Definitions_File:

Form of Definitions File
^^^^^^^^^^^^^^^^^^^^^^^^

The definitions file contains lines of the form::

      symbol := value

where ``symbol`` is a preprocessing symbol, and ``value`` is one of the following:

*  Empty, corresponding to a null substitution,
*  A string literal using normal Ada syntax, or
*  Any sequence of characters from the set {letters, digits, period, underline}.

You may also place comment lines in the definitions file, starting with
the usual ``--``
and comments may be added to the end of each definition line.


.. _Form_of_Input_Text_for_gnatprep:

Form of Input Text for ``gnatprep``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The input text contains preprocessor conditional inclusion lines
as well as general symbol substitution sequences.

Preprocessor conditional inclusion commands have the form:

.. code-block:: c

       #if <expression> [then]
          lines
       #elsif <expression> [then]
          lines
       #elsif <expression> [then]
          lines
       ...
       #else
          lines
       #end if;

In this example, <expression> is defined by the following grammar::

       <expression> ::=  <symbol>
       <expression> ::=  <symbol> = "<value>"
       <expression> ::=  <symbol> = <symbol>
       <expression> ::=  <symbol> = <integer>
       <expression> ::=  <symbol> > <integer>
       <expression> ::=  <symbol> >= <integer>
       <expression> ::=  <symbol> < <integer>
       <expression> ::=  <symbol> <= <integer>
       <expression> ::=  <symbol> 'Defined
       <expression> ::=  not <expression>
       <expression> ::=  <expression> and <expression>
       <expression> ::=  <expression> or <expression>
       <expression> ::=  <expression> and then <expression>
       <expression> ::=  <expression> or else <expression>
       <expression> ::=  ( <expression> )

For the first test, (<expression> ::= <symbol>), the symbol must have
either the value true or false. The right-hand of the
symbol definition must be one of the (case-insensitive) literals
``True`` or ``False``. If the value is true, the
corresponding lines are included and if the value is false, they are
excluded.

When comparing a symbol to an integer, the integer is any non negative
literal integer as defined in the Ada Reference Manual, such as 3, 16#FF# or
2#11#. The symbol value must also be a non negative integer. Integer values
in the range 0 .. 2**31-1 are supported.

The test (<expression> ::= <symbol>'Defined) is true only if
the symbol has been defined in the definition file or by a :switch:`-D`
switch on the command line. Otherwise, the test is false.

The equality tests are case insensitive, as are all the preprocessor lines.

If the symbol referenced is not defined in the symbol definitions
file, the result depends on whether or not you have specified the
:switch:`-u` switch. If you have, the symbol is treated as if it had
the value false and the test fails. If not,
it's an error to reference an undefined symbol. It's also an
error to reference a symbol that you have defined with a value other than
``True`` or ``False``.

The use of the ``not`` operator inverts the sense of this logical
test.  You can't combine the ``not`` operator with the ``or`` or
``and`` operators without parentheses. For example, you can't write
"if not X or Y then" allowed, but can write either "if (not X) or Y
then" or "if not (X or Y) then".

The ``then`` keyword is optional, as shown.

You must place the ``#`` in the first non-blank character on a line,
i.e., it must be preceded only by spaces or horizontal tabs, but
otherwise the format is free form. You may place spaces or tabs
between the ``#`` and the keyword. The keywords and the symbols are
case insensitive, as in normal Ada code. You can write comments on a
preprocessor line, but other than that, you can't place any other
tokens on a preprocessor line. You can have any number of ``elsif``
clauses, including none at all. The ``else`` is optional, as in Ada.

You obtain symbol substitution outside of preprocessor lines by using
the sequence::

      $symbol

anywhere within a source line, except in a comment or within a
string literal. The identifier
following the ``$`` must match one of the symbols defined in the symbol
definition file and the resulting output substitutes the value of the
symbol in place of ``$symbol`` in the output file.

Note that although you can't substitute strings within a string
literal, you can have a symbol whose defined value is a string
literal. So instead of setting XYZ to ``hello`` and writing:

.. code-block:: ada

     Header : String := "$XYZ";

you should set XYZ to ``"hello"`` and write:

.. code-block:: ada

     Header : String := $XYZ;

and then the substitution will occur as desired.


.. _Integrated_Preprocessing:

Integrated Preprocessing
------------------------

As noted above, a file to be preprocessed consists of Ada source code
in which preprocessing lines have been inserted. However, instead of
using ``gnatprep`` to explicitly preprocess a file as a separate step
before compilation, you can carry out the preprocessing implicitly as
part of compilation. Such *integrated preprocessing*, which is the
common style with C, is performed when you pass either or both of the
following switches to the compiler:

   *   :switch:`-gnatep`, which specifies the *preprocessor data file*.
       This file dictates how the source files will be preprocessed (e.g., which
       symbol definition files apply to which sources).

   *   :switch:`-gnateD`, which defines values for preprocessing symbols.

Integrated preprocessing applies only to Ada source files; it's
not available for configuration pragma files.

With integrated preprocessing, GNAT doesn't write the output from the
preprocessor, by default, to any external file. Instead it's passed
internally to the compiler. To preserve the result of preprocessing in
a file, either run ``gnatprep`` in standalone mode or supply the
:switch:`-gnateG` switch to the compiler.

When using project files:

   * you should use the builder switch :switch:`-x`  if any Ada source is
     compiled with :switch:`gnatep=` so that the compiler finds the
     *preprocessor data file*.

   * you should place the preprocessing data file and the symbol
     definition files in the source directories of the project.

Note that the ``gnatmake`` switch :switch:`-m` will almost
always trigger recompilation for sources that are preprocessed,
because ``gnatmake`` cannot compute the checksum of the source after
preprocessing.

The actual preprocessing function is described in detail in
:ref:`Preprocessing_with_gnatprep`. This section explains the switches
that relate to integrated preprocessing.

.. index:: -gnatep (gcc)

:switch:`-gnatep={preprocessor_data_file}`
  This switch specifies the file name (without directory
  information) of the preprocessor data file. Either place this file
  in one of the source directories, or, when using project
  files, reference the project file's directory via the
  ``project_name'Project_Dir`` project attribute; e.g:

     .. code-block:: gpr

         project Prj is
            package Compiler is
               for Switches ("Ada") use
                 ("-gnatep=" & Prj'Project_Dir & "prep.def");
            end Compiler;
         end Prj;

  A preprocessor data file is a text file that contains *preprocessor
  control lines*.  A preprocessor control line directs the preprocessing of
  either a particular source file, or, analogous to ``others`` in Ada,
  all sources not specified elsewhere in  the preprocessor data file.
  A preprocessor control line
  can optionally identify a *definition file* that assigns values to
  preprocessor symbols, as well as a list of switches that relate to
  preprocessing.
  You can also include empty lines and comments (using Ada syntax), with no
  semantic effect.

  Here's an example of a preprocessor data file:

    .. code-block:: ada

        "toto.adb"  "prep.def" -u
        --  Preprocess toto.adb, using definition file prep.def
        --  Undefined symbols are treated as False

        * -c -DVERSION=V101
        --  Preprocess all other sources without using a definition file
        --  Suppressed lined are commented
        --  Symbol VERSION has the value V101

        "tata.adb" "prep2.def" -s
        --  Preprocess tata.adb, using definition file prep2.def
        --  List all symbols with their values

  A preprocessor control line has the following syntax:

    ::

        <preprocessor_control_line> ::=
           <preprocessor_input> [ <definition_file_name> ] { <switch> }

        <preprocessor_input> ::= <source_file_name> | '*'

        <definition_file_name> ::= <string_literal>

        <source_file_name> := <string_literal>

        <switch> := (See below for list)

  Thus, you start each preprocessor control line either a literal
  string or the character '*':

  *  A literal string is the file name (without directory information) of the source
     file that will be input to the preprocessor.

  *  The character '*' is a wild-card indicator; the additional parameters on the line
     indicate the preprocessing for all the sources
     that are not specified explicitly on other lines (the order of the lines is not
     significant).

  You cannot have two lines with the same file name or two
  lines starting with the '*' character.

  After the file name or '*', you can place an optional literal string
  to specify the name of the definition file to be used for
  preprocessing (:ref:`Form_of_Definitions_File`). The definition
  files are found by the compiler in one of the source directories. In
  some cases, when compiling a source in a directory other than the
  current directory, if the definition file is in the current
  directory, you may need to add the current directory as a
  source directory through the :switch:`-I` switch; otherwise the
  compiler would not find the definition file.

  Finally, switches similar to those of ``gnatprep`` may optionally appear:

  :switch:`-b`
    Causes both preprocessor lines and the lines deleted by
    preprocessing to be replaced by blank lines, preserving the line number.
    This switch is always implied; however, if specified after :switch:`-c`
    or :switch:`-e` it cancels the effect of those switches.

  :switch:`-c`
    Causes both preprocessor lines and the lines deleted
    by preprocessing to be retained as comments marked
    with the special string '`--!`'.


  :switch:`-D{symbol}={new_value}`
    Define or redefine ``symbol`` to have ``new_value`` as its value.
    You can write ``symbol`` as either an Ada identifier or any Ada
    reserved word aside from ``if``, ``else``, ``elsif``, ``end``,
    ``and``, ``or`` and ``then``.  You can write ``new_value`` as a
    literal string, an Ada identifier or any Ada reserved word. A
    symbol declared with this switch replaces a symbol with the same
    name defined in a definition file.


  :switch:`-e`
    Causes both preprocessor lines and the lines deleted by
    preprocessing to be replaced by empty comment lines marked
    with '`--!`' (and no other text) in the output source file,


  :switch:`-s`
    Causes a sorted list of symbol names and values to be
    listed on the standard output file.


  :switch:`-u`
    Causes undefined symbols to be treated as having the value
    ``FALSE`` in the context of a preprocessor test. If you don't
    specify this switch, an undefined symbol in a ``#if`` or
    ``#elsif`` test is treated as an error.


.. index:: -gnateD (gcc)

:switch:`-gnateD{symbol}[={new_value}]`
  Define or redefine ``symbol`` to have ``new_value`` as its value. If
  you don't specify a value, the value of ``symbol`` is ``True``.  You
  write ``symbol`` as an identifier, following normal Ada
  (case-insensitive) rules for its syntax, and ``new_value`` as either
  an arbitrary string between double quotes or any sequence (including
  an empty sequence) of characters from the set (letters, digits,
  period, underline).  Ada reserved words may be used as symbols, with
  the exceptions of ``if``, ``else``, ``elsif``, ``end``, ``and``,
  ``or`` and ``then``.

  Examples:

    ::

        -gnateDToto=Tata
        -gnateDFoo
        -gnateDFoo=\"Foo-Bar\"

  A symbol declared with this switch on the command line replaces a
  symbol with the same name either in a definition file or specified with a
  switch :switch:`-D` in the preprocessor data file.

  This switch is similar to switch :switch:`-D` of ``gnatprep``.


.. index:: -gnateG (gcc)

:switch:`-gnateG[bce]`
  When integrated preprocessing is performed on source file :file:`filename.extension`,
  create or overwrite :file:`filename.extension.prep` to contain
  the result of the preprocessing.
  For example if the source file is :file:`foo.adb` then
  the output file is :file:`foo.adb.prep`.
  An optional character (b, c, or e) can be appended to indicate that filtered
  lines are to be replaced by blank lines, comments, or empty comments (see
  documentation above about :switch:`-b`, :switch:`-c`, and :switch:`-e`).
  If one of those switches is given in a preprocessor data file, then it
  will override any option included with :switch:`-gnateG`.


.. _Mixed_Language_Programming:

Mixed Language Programming
==========================

.. index:: Mixed Language Programming

This section describes how to develop a mixed-language program,
with a focus on combining Ada with C or C++.

.. _Interfacing_to_C:

Interfacing to C
----------------

Interfacing Ada with a foreign language such as C involves using
compiler directives to import and/or export entity definitions in each
language -- using ``extern`` statements in C, for example, and the
``Import``, ``Export``, and ``Convention`` pragmas in Ada.
A full treatment of these topics is provided in Appendix B, section 1
of the Ada Reference Manual.

There are two ways to build a program using GNAT that contains some Ada
sources and some foreign language sources, depending on whether or not
the main subprogram is written in Ada.  Here's an example with
the main subprogram in Ada:

.. code-block:: c

    /* file1.c */
    #include <stdio.h>

    void print_num (int num)
    {
      printf ("num is %d.\\n", num);
      return;
    }

.. code-block:: c

    /* file2.c */

    /* num_from_Ada is declared in my_main.adb */
    extern int num_from_Ada;

    int get_num (void)
    {
      return num_from_Ada;
    }

.. code-block:: ada

    --  my_main.adb
    procedure My_Main is

       --  Declare then export an Integer entity called num_from_Ada
       My_Num : Integer := 10;
       pragma Export (C, My_Num, "num_from_Ada");

       --  Declare an Ada function spec for Get_Num, then use
       --  C function get_num for the implementation.
       function Get_Num return Integer;
       pragma Import (C, Get_Num, "get_num");

       --  Declare an Ada procedure spec for Print_Num, then use
       --  C function print_num for the implementation.
       procedure Print_Num (Num : Integer);
       pragma Import (C, Print_Num, "print_num");

    begin
       Print_Num (Get_Num);
    end My_Main;

To build this example:

* First compile the foreign language files to
  generate object files:

  .. code-block:: sh

      $ gcc -c file1.c
      $ gcc -c file2.c

* Then compile the Ada units to produce a set of object files and ALI
  files:

  .. code-block:: sh

      $ gnatmake -c my_main.adb

* Run the Ada binder on the Ada main program:

  .. code-block:: sh

      $ gnatbind my_main.ali

* Link the Ada main program, the Ada objects, and the other language
  objects:

  .. code-block:: sh

      $ gnatlink my_main.ali file1.o file2.o

You can merge the last three steps into a single command:

.. code-block:: sh

   $ gnatmake my_main.adb -largs file1.o file2.o


.. index:: Binder output file

If the main program is in a language other than Ada, you may have more
than one entry point into the Ada subsystem. You must use a special
binder option to generate callable routines that initialize and
finalize the Ada units (:ref:`Binding_with_Non-Ada_Main_Programs`).
You must insert calls to the initialization and finalization routines
in the main program or some other appropriate point in the code. You
must place the call to initialize the Ada units so that it occurs
before the first Ada subprogram is called and must place the call to
finalize the Ada units so it occurs after the last Ada subprogram
returns. The binder places the initialization and finalization
subprograms into the :file:`b~xxx.adb` file, where they can be
accessed by your C sources.  To illustrate, we have the following
example:

.. code-block:: c

     /* main.c */
     extern void adainit (void);
     extern void adafinal (void);
     extern int add (int, int);
     extern int sub (int, int);

     int main (int argc, char *argv[])
     {
        int a = 21, b = 7;

        adainit();

        /* Should print "21 + 7 = 28" */
        printf ("%d + %d = %d\\n", a, b, add (a, b));

        /* Should print "21 - 7 = 14" */
        printf ("%d - %d = %d\\n", a, b, sub (a, b));

        adafinal();
     }

.. code-block:: ada

     --  unit1.ads
     package Unit1 is
        function Add (A, B : Integer) return Integer;
        pragma Export (C, Add, "add");
     end Unit1;

.. code-block:: ada

     --  unit1.adb
     package body Unit1 is
        function Add (A, B : Integer) return Integer is
        begin
           return A + B;
        end Add;
     end Unit1;

.. code-block:: ada

     --  unit2.ads
     package Unit2 is
        function Sub (A, B : Integer) return Integer;
        pragma Export (C, Sub, "sub");
     end Unit2;

.. code-block:: ada

     --  unit2.adb
     package body Unit2 is
        function Sub (A, B : Integer) return Integer is
        begin
           return A - B;
        end Sub;
     end Unit2;

The build procedure for this application is similar to the last
example's:

* First, compile the foreign language files to generate object files:

  .. code-block:: sh

      $ gcc -c main.c


* Next, compile the Ada units to produce a set of object files and ALI
  files:

  .. code-block:: sh

      $ gnatmake -c unit1.adb
      $ gnatmake -c unit2.adb

* Run the Ada binder on every generated ALI file.  Make sure to use the
  :switch:`-n` option to specify a foreign main program:

  .. code-block:: sh

      $ gnatbind -n unit1.ali unit2.ali

* Link the Ada main program, the Ada objects and the foreign language
  objects. You need only list the last ALI file here:

  .. code-block:: sh

      $ gnatlink unit2.ali main.o -o exec_file

  This procedure yields a binary executable called :file:`exec_file`.

Depending on the circumstances (for example when your non-Ada main object
does not provide symbol ``main``), you may also need to instruct the
GNAT linker not to include the standard startup objects by passing the
:switch:`-nostartfiles` switch to ``gnatlink``.

.. _Calling_Conventions:

Calling Conventions
-------------------

.. index:: Foreign Languages

.. index:: Calling Conventions

GNAT follows standard calling sequence conventions and will interface
to any other language that also follows these conventions. The following
Convention identifiers are recognized by GNAT:


.. index:: Interfacing to Ada

.. index:: Other Ada compilers

.. index:: Convention Ada

``Ada``
  This indicates that the standard Ada calling sequence is
  used and all Ada data items may be passed without any limitations in the
  case where GNAT is used to generate both the caller and callee. You can also
  mix GNAT generated code and code generated by another Ada
  compiler. In this case, you should restrict the data types to simple
  cases, including primitive types. Whether complex data types can be passed
  depends on the situation. It is probably safe to pass simple arrays, such
  as arrays of integers or floats. Records may or may not work, depending
  on whether both compilers lay them out identically. Complex structures
  involving variant records, access parameters, tasks, or protected types,
  are unlikely to be able to be passed.

  If output from two different compilers is mixed, you are responsible
  for dealing with elaboration issues. Probably the safest approach is
  to write the main program in the version of Ada other than GNAT, so
  it takes care of its own elaboration requirements, and
  call the GNAT-generated adainit procedure to ensure elaboration of
  the GNAT components. Consult the documentation of the other Ada
  compiler for further details on elaboration.

.. index:: Interfacing to Assembly

.. index:: Convention Assembler


``Assembler``
  Specifies assembler as the convention. In practice this has the
  same effect as convention Ada (but is not equivalent in the sense of being
  considered the same convention).

.. index:: Convention Asm

.. index:: Asm

``Asm``
  Equivalent to Assembler.

  .. index:: Interfacing to COBOL

  .. index:: Convention COBOL

.. index:: COBOL

``COBOL``
  Data is passed according to the conventions described
  in section B.4 of the Ada Reference Manual.

.. index:: C
.. index:: Interfacing to C

.. index:: Convention C


``C``
  Data is passed according to the conventions described
  in section B.3 of the Ada Reference Manual.

  A note on interfacing to a C 'varargs' function:

    .. index:: C varargs function
    .. index:: Interfacing to C varargs function
    .. index:: varargs function interfaces

    In C, ``varargs`` allows a function to take a variable number of
    arguments. There is no direct equivalent in this to Ada. One
    approach that you can use is to create a C wrapper for each
    different profile and then interface to this C wrapper. For
    example, to print an ``int`` value using ``printf``,
    create a C function ``printfi`` that takes two arguments, a
    pointer to a string and an int, and calls ``printf``.
    Then in the Ada program, use pragma ``Import`` to
    interface to ``printfi``.

    It may work on some platforms to directly interface to
    a ``varargs`` function by providing a specific Ada profile
    for a particular call. However, this does not work on
    all platforms since there is no guarantee that the
    calling sequence for a two-argument normal C function
    is the same as for calling a ``varargs`` C function with
    the same two arguments.

.. index:: Convention Default

.. index:: Default

``Default``
  Equivalent to C.

.. index:: Convention External

.. index:: External

``External``
  Equivalent to C.

.. index:: C++
.. index:: Interfacing to C++

.. index:: Convention C++


``C_Plus_Plus`` (or ``CPP``)
  This stands for C++. For most purposes, this is identical to C.
  See the separate description of the specialized GNAT pragmas relating to
  C++ interfacing for further details.

.. index:: Fortran
.. index:: Interfacing to Fortran
.. index:: Convention Fortran


``Fortran``
  Data is passed according to the conventions described
  in section B.5 of the Ada Reference Manual.


``Intrinsic``
  This applies to an intrinsic operation, as defined in the Ada
  Reference Manual. If a pragma Import (Intrinsic) applies to a subprogram,
  it means the body of the subprogram is provided by the compiler itself,
  usually by means of an efficient code sequence, and that you don't
  supply an explicit body for it. In an application program, the pragma may
  be applied to the following sets of names:


  * ``Rotate_Left``, ``Rotate_Right``, ``Shift_Left``, ``Shift_Right``, ``Shift_Right_Arithmetic``.
    The corresponding subprogram declaration must have
    two formal parameters. The
    first must be a signed integer type or a modular type with a binary
    modulus and the second parameter must be of type Natural.
    The return type must be the same as the type of the first argument. The size
    of this type can only be 8, 16, 32, or 64.


  * Binary arithmetic operators: '+', '-', '*', '/'.
    The corresponding operator declaration must have parameters and result type
    that have the same root numeric type (for example, all three are long_float
    types). This simplifies the definition of operations that use type checking
    to perform dimensional checks:


    .. code-block:: ada

        type Distance is new Long_Float;
        type Time     is new Long_Float;
        type Velocity is new Long_Float;
        function "/" (D : Distance; T : Time)
          return Velocity;
        pragma Import (Intrinsic, "/");

    You often program this common idiom with a generic definition and an
    explicit body. The pragma makes it simpler to introduce such declarations.
    It incurs no overhead in compilation time or code size because it is
    implemented as a single machine instruction.


  * General subprogram entities. This is used  to bind an Ada subprogram
    declaration to
    a compiler builtin by name with back ends where such interfaces are
    available. A typical example is the set of ``__builtin`` functions
    exposed by the ``gcc`` back end, as in the following example:


    .. code-block:: ada

         function builtin_sqrt (F : Float) return Float;
         pragma Import (Intrinsic, builtin_sqrt, "__builtin_sqrtf");

    Most of the ``gcc`` builtins are accessible this way, and as for other
    import conventions (e.g. C), it is the user's responsibility to ensure
    that the Ada subprogram profile matches the underlying builtin
    expectations.

.. index:: Stdcall
.. index:: Convention Stdcall

``Stdcall``
  This is relevant only to Windows implementations of GNAT
  and specifies that the ``Stdcall`` calling sequence is used,
  as defined by the NT API. To simplify building
  cross-platform bindings, this convention is handled as a ``C`` calling
  convention on non-Windows platforms.

.. index:: DLL
.. index:: Convention DLL


``DLL``
  This is equivalent to ``Stdcall``.

.. index:: Win32
.. index:: Convention Win32


``Win32``
  This is equivalent to ``Stdcall``.

.. index:: Stubbed
.. index:: Convention Stubbed


``Stubbed``
  This is a special convention that indicates that the compiler
  should provide a stub body that raises ``Program_Error``.

GNAT additionally provides a useful pragma ``Convention_Identifier``
that you can use to parameterize conventions and allow additional synonyms.
For example, if you have legacy code in which the convention
identifier Fortran77 was used for Fortran, you can use the configuration
pragma:

.. code-block:: ada

     pragma Convention_Identifier (Fortran77, Fortran);

And from now on, you can use  the identifier ``Fortran77`` as a convention
identifier (for example in an ``Import`` pragma) with the same
meaning as ``Fortran``.


.. _Building_Mixed_Ada_and_C++_Programs:

Building Mixed Ada and C++ Programs
-----------------------------------

If you are inexperienced with mixed-language development, you may find that
building an application containing both Ada and C++ code can be a
challenge.  This section gives a few hints that should make this task easier.

.. _Interfacing_to_C++:

Interfacing to C++
^^^^^^^^^^^^^^^^^^

GNAT supports interfacing with the G++ compiler (or any C++ compiler
generating code that is compatible with the G++ Application Binary
Interface ---see http://itanium-cxx-abi.github.io/cxx-abi/abi.html).

You can do interfacing at three levels: simple data, subprograms, and
classes. In the first two cases, GNAT offers a specific ``Convention C_Plus_Plus``
(or ``CPP``) that behaves exactly like ``Convention C``.
Usually, C++ mangles the names of subprograms. To generate proper mangled
names automatically, see :ref:`Generating_Ada_Bindings_for_C_and_C++_headers`).
You can also address this problem addressed manually in two ways:

* by modifying the C++ code in order to force a C convention using
  the ``extern "C"`` syntax.

* by figuring out the mangled name (using e.g. ``nm`` or by looking at the
  assembly code generated by the C++ compiler) and using it as the
  ``Link_Name`` argument of the pragma ``Import``.

You can achieve interfacing at the class level by using the GNAT specific
pragmas such as ``CPP_Constructor``.  See the :title:`GNAT_Reference_Manual` for additional information.

.. _Linking_a_Mixed_C++_and_Ada_Program:

Linking a Mixed C++ & Ada Program
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Usually the linker, of the C++ development system must be used to link
mixed applications because most C++ systems resolve elaboration
issues (such as calling constructors on global class instances)
transparently during the link phase. GNAT has been adapted to ease the
use of a foreign linker for the last phase. We consider three cases:


* Using GNAT and G++ (GNU C++ compiler) from the same GCC installation:
  You can call the C++ linker by using the C++ specific driver
  called ``g++``.

  If the C++ code uses inline functions that you plan to call from
  Ada, you need to compile your C++ code with the
  :switch:`-fkeep-inline-functions` so ``g++`` doesn't delete these
  functions.

  .. code-block:: sh

    $ g++ -c -fkeep-inline-functions file1.C
    $ g++ -c -fkeep-inline-functions file2.C
    $ gnatmake ada_unit -largs file1.o file2.o --LINK=g++


* Using GNAT and G++ from two different GCC installations: If both
  compilers are on the :envvar:`PATH`, you may use the previous
  method.  However, environment variables such as
  :envvar:`C_INCLUDE_PATH`, :envvar:`GCC_EXEC_PREFIX`,
  :envvar:`BINUTILS_ROOT`, and :envvar:`GCC_ROOT` affect both
  compilers at the same time and may make one of the two compilers
  operate improperly if set during invocation of the wrong compiler.
  It is also very important that the linker uses the proper
  :file:`libgcc.a` ``gcc`` library -- that is, the one from the C++
  compiler installation. You can replace the implicit link command as
  suggested in the ``gnatmake`` command from the former example with
  an explicit link command with the full-verbosity option
  in order to verify which library is used:

  .. code-block:: sh

    $ gnatbind ada_unit
    $ gnatlink -v -v ada_unit file1.o file2.o --LINK=c++

  If there's a problem due to interfering environment variables, you can
  work around it by using an intermediate script. The following example
  shows the proper script to use when GNAT has not been installed at its
  default location and ``g++`` has been installed at its default location:

  .. code-block:: sh

    $ cat ./my_script
    #!/bin/sh
    unset BINUTILS_ROOT
    unset GCC_ROOT
    c++ $*
    $ gnatlink -v -v ada_unit file1.o file2.o --LINK=./my_script


* Using a non-GNU C++ compiler: You can use the commands previously described
  used to insure that the C++ linker is used. Nonetheless, you need to add
  a few more parameters to the link command line, depending on the exception
  mechanism used.

  If you are using the ``setjmp`` / ``longjmp`` exception mechanism, you need only
  include the paths to the ``libgcc`` libraries:

  .. code-block:: sh

    $ cat ./my_script
    #!/bin/sh
    CC $* gcc -print-file-name=libgcc.a gcc -print-file-name=libgcc_eh.a
    $ gnatlink ada_unit file1.o file2.o --LINK=./my_script


  where CC is the name of the non-GNU C++ compiler.

  If you are using the "zero cost" exception mechanism and the platform
  supports automatic registration of exception tables (e.g., Solaris),
  you need to include paths to more objects:

  .. code-block:: sh

    $ cat ./my_script
    #!/bin/sh
    CC gcc -print-file-name=crtbegin.o $* \\
    gcc -print-file-name=libgcc.a gcc -print-file-name=libgcc_eh.a \\
    gcc -print-file-name=crtend.o
    $ gnatlink ada_unit file1.o file2.o --LINK=./my_script


  If you are using the "zero cost exception" mechanism is used and the platform
  doesn't support automatic registration of exception tables (e.g., HP-UX
  or AIX), the simple approach described above won't work and
  a you will need to preform a pre-linking phase using GNAT.


Another alternative is to use the :command:`gprbuild` multi-language builder
which has a large knowledge base and knows how to link Ada and C++ code
together automatically in most cases.

.. _A_Simple_Example:

A Simple Example
^^^^^^^^^^^^^^^^

The following example, provided as part of the GNAT examples, shows how
to achieve procedural interfacing between Ada and C++ in both
directions. The C++ class ``A`` has two methods. The first method is exported
to Ada by the means of an extern C wrapper function. The second method
calls an Ada subprogram. On the Ada side, the C++ calls are modelled by
a limited record with a layout comparable to the C++ class. The Ada
subprogram, in turn, calls the C++ method. So, starting from the C++
main program, execution passes back and forth between the two
languages.

Here are the compilation commands:

.. code-block:: sh

     $ gnatmake -c simple_cpp_interface
     $ g++ -c cpp_main.C
     $ g++ -c ex7.C
     $ gnatbind -n simple_cpp_interface
     $ gnatlink simple_cpp_interface -o cpp_main --LINK=g++ -lstdc++ ex7.o cpp_main.o

Here are the corresponding sources:

.. code-block:: cpp

     //cpp_main.C

     #include "ex7.h"

     extern "C" {
       void adainit (void);
       void adafinal (void);
       void method1 (A *t);
     }

     void method1 (A *t)
     {
       t->method1 ();
     }

     int main ()
     {
       A obj;
       adainit ();
       obj.method2 (3030);
       adafinal ();
     }

.. code-block:: cpp

     //ex7.h

     class Origin {
      public:
       int o_value;
     };
     class A : public Origin {
      public:
       void method1 (void);
       void method2 (int v);
       A();
       int   a_value;
     };

.. code-block:: cpp

     //ex7.C

     #include "ex7.h"
     #include <stdio.h>

     extern "C" { void ada_method2 (A *t, int v);}

     void A::method1 (void)
     {
       a_value = 2020;
       printf ("in A::method1, a_value = %d \\n",a_value);
     }

     void A::method2 (int v)
     {
        ada_method2 (this, v);
        printf ("in A::method2, a_value = %d \\n",a_value);
     }

     A::A(void)
     {
        a_value = 1010;
       printf ("in A::A, a_value = %d \\n",a_value);
     }

.. code-block:: ada

     -- simple_cpp_interface.ads
     with System;
     package Simple_Cpp_Interface is
        type A is limited
           record
              Vptr    : System.Address;
              O_Value : Integer;
              A_Value : Integer;
           end record;
        pragma Convention (C, A);

        procedure Method1 (This : in out A);
        pragma Import (C, Method1);

        procedure Ada_Method2 (This : in out A; V : Integer);
        pragma Export (C, Ada_Method2);

     end Simple_Cpp_Interface;

.. code-block:: ada

     -- simple_cpp_interface.adb
     package body Simple_Cpp_Interface is

        procedure Ada_Method2 (This : in out A; V : Integer) is
        begin
           Method1 (This);
           This.A_Value := V;
        end Ada_Method2;

     end Simple_Cpp_Interface;


.. _Interfacing_with_C++_constructors:

Interfacing with C++ constructors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To interface with C++ constructors GNAT provides the
``pragma CPP_Constructor`` (see the :title:`GNAT_Reference_Manual`
for additional information).
In this section, we present some common uses of C++ constructors
in mixed-languages programs in GNAT.

Let us assume we need to interface with the following
C++ class:

.. code-block:: cpp

     class Root {
     public:
       int  a_value;
       int  b_value;
       virtual int Get_Value ();
       Root();              // Default constructor
       Root(int v);         // 1st non-default constructor
       Root(int v, int w);  // 2nd non-default constructor
     };

For this purpose, we can write the following package spec (further
information on how to build this spec is available in
:ref:`Interfacing_with_C++_at_the_Class_Level` and
:ref:`Generating_Ada_Bindings_for_C_and_C++_headers`).

.. code-block:: ada

     with Interfaces.C; use Interfaces.C;
     package Pkg_Root is
       type Root is tagged limited record
          A_Value : int;
          B_Value : int;
       end record;
       pragma Import (CPP, Root);

       function Get_Value (Obj : Root) return int;
       pragma Import (CPP, Get_Value);

       function Constructor return Root;
       pragma Cpp_Constructor (Constructor, "_ZN4RootC1Ev");

       function Constructor (v : Integer) return Root;
       pragma Cpp_Constructor (Constructor, "_ZN4RootC1Ei");

       function Constructor (v, w : Integer) return Root;
       pragma Cpp_Constructor (Constructor, "_ZN4RootC1Eii");
     end Pkg_Root;

On the Ada side, the constructor is represented by a function (whose
name is arbitrary) that returns the classwide type corresponding to
the imported C++ class. Although the constructor is described as a
function, it's typically a procedure with an extra implicit argument
(the object being initialized) at the implementation level. GNAT
issues the appropriate call, whatever it is, to get the object
properly initialized.

Constructors can only appear in the following contexts:

* On the right side of an initialization of an object of type.
* On the right side of an initialization of a record component of type.
* In an Ada 2005 limited aggregate.
* In an Ada 2005 nested limited aggregate.
* In an Ada 2005 limited aggregate that initializes an object built in
  place by an extended return statement.

In a declaration of an object whose type is a class imported from C++,
either the default C++ constructor is implicitly called by GNAT or you must
explicitly call the required C++ constructor in the
expression that initializes the object. For example:

.. code-block:: ada

     Obj1 : Root;
     Obj2 : Root := Constructor;
     Obj3 : Root := Constructor (v => 10);
     Obj4 : Root := Constructor (30, 40);

The first two declarations are equivalent: in both cases the default C++
constructor is invoked (in the former case the call to the constructor is
implicit and in the latter case the call is explicit in the object
declaration). ``Obj3`` is initialized by the C++ non-default constructor
that takes an integer argument and ``Obj4`` is initialized by the
non-default C++ constructor that takes two integers.

Let's derive the imported C++ class in the Ada side. For example:

.. code-block:: ada

     type DT is new Root with record
        C_Value : Natural := 2009;
     end record;

In this case, you must initialize the components ``DT`` inherited from
the C++ side by a C++ constructor and the additional Ada components
of type DT are initialized by GNAT. The initialization of such an
object is done either by default, or by means of a function returning
an aggregate of type DT, or by means of an extension aggregate.

.. code-block:: ada

     Obj5 : DT;
     Obj6 : DT := Function_Returning_DT (50);
     Obj7 : DT := (Constructor (30,40) with C_Value => 50);

The declaration of ``Obj5`` invokes the default constructors: the
C++ default constructor of the parent type takes care of the initialization
of the components inherited from Root and GNAT takes care of the default
initialization of the additional Ada components of type DT (that is,
``C_Value`` is initialized to value 2009). The order of invocation of
the constructors is consistent with the order of elaboration required by
Ada and C++. That is, the constructor of the parent type is always called
before the constructor of the derived type.

Let's now consider a record that has components whose type is imported
from C++. For example:

.. code-block:: ada

     type Rec1 is limited record
        Data1 : Root := Constructor (10);
        Value : Natural := 1000;
     end record;

     type Rec2 (D : Integer := 20) is limited record
        Rec   : Rec1;
        Data2 : Root := Constructor (D, 30);
     end record;

The initialization of an object of type ``Rec2`` calls the non-default
C++ constructors specified for the imported components.  For example:

.. code-block:: ada

     Obj8 : Rec2 (40);

Using Ada 2005, we can use limited aggregates to initialize an object
invoking C++ constructors that differ from those specified in the type
declarations. For example:

.. code-block:: ada

     Obj9 : Rec2 := (Rec => (Data1 => Constructor (15, 16),
                             others => <>),
                     others => <>);

The above declaration uses an Ada 2005 limited aggregate to
initialize ``Obj9`` and the C++ constructor that has two integer
arguments is invoked to initialize the ``Data1`` component instead
of the constructor specified in the declaration of type ``Rec1``. In
Ada 2005, the box in the aggregate indicates that unspecified components
are initialized using the expression (if any) available in the component
declaration. That is, in this case discriminant ``D`` is initialized
to value ``20``, ``Value`` is initialized to value 1000, and the
non-default C++ constructor that handles two integers takes care of
initializing component ``Data2`` with values ``20,30``.

In Ada 2005, we can use the extended return statement to build the Ada
equivalent to C++ non-default constructors. For example:

.. code-block:: ada

     function Constructor (V : Integer) return Rec2 is
     begin
        return Obj : Rec2 := (Rec => (Data1  => Constructor (V, 20),
                                      others => <>),
                              others => <>) do
           --  Further actions required for construction of
           --  objects of type Rec2
           ...
        end record;
     end Constructor;

In this example, we use the extended return statement construct to
build in place the returned object whose components are initialized by
means of a limited aggregate. We could also place any further action
associated with the constructor inside the construct.

.. _Interfacing_with_C++_at_the_Class_Level:

Interfacing with C++ at the Class Level
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In this section, we demonstrate the GNAT features for interfacing with
C++ by means of an example making use of Ada 2005 abstract interface
types. This example consists of a classification of animals; classes
have been used to model our main classification of animals and
interfaces provide support for the management of secondary
classifications. We first demonstrate a case in which the types and
constructors are defined on the C++ side and imported from the Ada
side and then the reverse case.

The root of our derivation is the ``Animal`` class, with a
single private attribute (the ``Age`` of the animal), a constructor,
and two public primitives to set and get the value of this attribute.

.. code-block:: cpp

     class Animal {
      public:
        virtual void Set_Age (int New_Age);
        virtual int Age ();
        Animal() {Age_Count = 0;};
      private:
        int Age_Count;
     };

Abstract interface types are defined in C++ by means of classes with pure
virtual functions and no data members. In our example we use two
interfaces that provide support for the common management of ``Carnivore``
and ``Domestic`` animals:

.. code-block:: cpp

     class Carnivore {
     public:
        virtual int Number_Of_Teeth () = 0;
     };

     class Domestic {
     public:
        virtual void Set_Owner (char* Name) = 0;
     };

Using these declarations, we can now say that a ``Dog`` is an animal that is
both Carnivore and Domestic, that is:

.. code-block:: cpp

     class Dog : Animal, Carnivore, Domestic {
      public:
        virtual int  Number_Of_Teeth ();
        virtual void Set_Owner (char* Name);

        Dog(); // Constructor
      private:
        int  Tooth_Count;
        char *Owner;
     };

In the following examples we assume that the previous declarations are
located in a file named :file:`animals.h`. The following package demonstrates
how to import these C++ declarations from the Ada side:

.. code-block:: ada

     with Interfaces.C.Strings; use Interfaces.C.Strings;
     package Animals is
       type Carnivore is limited interface;
       pragma Convention (C_Plus_Plus, Carnivore);
       function Number_Of_Teeth (X : Carnivore)
          return Natural is abstract;

       type Domestic is limited interface;
       pragma Convention (C_Plus_Plus, Domestic);
       procedure Set_Owner
         (X    : in out Domestic;
          Name : Chars_Ptr) is abstract;

       type Animal is tagged limited record
         Age : Natural;
       end record;
       pragma Import (C_Plus_Plus, Animal);

       procedure Set_Age (X : in out Animal; Age : Integer);
       pragma Import (C_Plus_Plus, Set_Age);

       function Age (X : Animal) return Integer;
       pragma Import (C_Plus_Plus, Age);

       function New_Animal return Animal;
       pragma CPP_Constructor (New_Animal);
       pragma Import (CPP, New_Animal, "_ZN6AnimalC1Ev");

       type Dog is new Animal and Carnivore and Domestic with record
         Tooth_Count : Natural;
         Owner       : Chars_Ptr;
       end record;
       pragma Import (C_Plus_Plus, Dog);

       function Number_Of_Teeth (A : Dog) return Natural;
       pragma Import (C_Plus_Plus, Number_Of_Teeth);

       procedure Set_Owner (A : in out Dog; Name : Chars_Ptr);
       pragma Import (C_Plus_Plus, Set_Owner);

       function New_Dog return Dog;
       pragma CPP_Constructor (New_Dog);
       pragma Import (CPP, New_Dog, "_ZN3DogC2Ev");
     end Animals;

Thanks to the compatibility between GNAT run-time structures and the
C++ ABI, interfacing with these C++ classes is easy. The only
requirement is that you must declare all the primitives and components
exactly in the same order in the two languages.

Regarding the abstract interfaces, we must indicate to the GNAT
compiler, by means of a ``pragma Convention (C_Plus_Plus)``, that the
convention used to pass the arguments to the called primitives will be
the same as for C++. For the imported classes, we use ``pragma
Import`` with convention ``C_Plus_Plus`` to indicate they have been
defined on the C++ side; this is required because the dispatch table
associated with these tagged types will be built in the C++ side and
therefore will not contain the predefined Ada primitives which Ada
would otherwise expect.

As the reader can see, there is no need to indicate the C++ mangled names
associated with each subprogram because it is assumed that all the calls to
these primitives will be dispatching calls. The only exception is the
constructor, which we must register with the compiler by means of
``pragma CPP_Constructor`` and we need to provide its associated C++
mangled name because the Ada compiler generates direct calls to it.

With the above packages, we can now declare objects of type ``Dog`` on
the Ada side and dispatch calls to the corresponding subprograms on
the C++ side. We can also extend the tagged type ``Dog`` with further
fields and primitives and override some of its C++ primitives on the
Ada side. For example, here we have a type derivation defined on the
Ada side that inherits all the dispatching primitives of the ancestor
from the C++ side.

.. code-block:: ada

     with Animals; use Animals;
     package Vaccinated_Animals is
       type Vaccinated_Dog is new Dog with null record;
       function Vaccination_Expired (A : Vaccinated_Dog) return Boolean;
     end Vaccinated_Animals;

It is important to note that, because of the ABI compatibility, we
don't need to add any further information to indicate either the object
layout or the dispatch table entry associated with each dispatching operation.

Now let's define all the types and constructors on the Ada side and export
them to C++, using the same hierarchy of our previous example:

.. code-block:: ada

     with Interfaces.C.Strings;
     use Interfaces.C.Strings;
     package Animals is
       type Carnivore is limited interface;
       pragma Convention (C_Plus_Plus, Carnivore);
       function Number_Of_Teeth (X : Carnivore)
          return Natural is abstract;

       type Domestic is limited interface;
       pragma Convention (C_Plus_Plus, Domestic);
       procedure Set_Owner
         (X    : in out Domestic;
          Name : Chars_Ptr) is abstract;

       type Animal is tagged record
         Age : Natural;
       end record;
       pragma Convention (C_Plus_Plus, Animal);

       procedure Set_Age (X : in out Animal; Age : Integer);
       pragma Export (C_Plus_Plus, Set_Age);

       function Age (X : Animal) return Integer;
       pragma Export (C_Plus_Plus, Age);

       function New_Animal return Animal'Class;
       pragma Export (C_Plus_Plus, New_Animal);

       type Dog is new Animal and Carnivore and Domestic with record
         Tooth_Count : Natural;
         Owner       : String (1 .. 30);
       end record;
       pragma Convention (C_Plus_Plus, Dog);

       function Number_Of_Teeth (A : Dog) return Natural;
       pragma Export (C_Plus_Plus, Number_Of_Teeth);

       procedure Set_Owner (A : in out Dog; Name : Chars_Ptr);
       pragma Export (C_Plus_Plus, Set_Owner);

       function New_Dog return Dog'Class;
       pragma Export (C_Plus_Plus, New_Dog);
     end Animals;

Compared with our previous example the only differences are the use of
``pragma Convention`` (instead of ``pragma Import``) and the use of
``pragma Export`` to indicate to the GNAT compiler that the primitives will
be available to C++. Thanks to the ABI compatibility, on the C++ side there is
nothing else to be done; as explained above, the only requirement is that all
the primitives and components are declared in exactly the same order.

For completeness, let us see a brief C++ main program that uses the
declarations available in :file:`animals.h` (presented in our first example) to
import and use the declarations from the Ada side, properly initializing and
finalizing the Ada run-time system along the way:

.. code-block:: cpp

     #include "animals.h"
     #include <iostream>
     using namespace std;

     void Check_Carnivore (Carnivore *obj) {...}
     void Check_Domestic (Domestic *obj)   {...}
     void Check_Animal (Animal *obj)       {...}
     void Check_Dog (Dog *obj)             {...}

     extern "C" {
       void adainit (void);
       void adafinal (void);
       Dog* new_dog ();
     }

     void test ()
     {
       Dog *obj = new_dog();  // Ada constructor
       Check_Carnivore (obj); // Check secondary DT
       Check_Domestic (obj);  // Check secondary DT
       Check_Animal (obj);    // Check primary DT
       Check_Dog (obj);       // Check primary DT
     }

     int main ()
     {
       adainit ();  test();  adafinal ();
       return 0;
     }

.. _Partition_Wide_Settings:

Partition-Wide Settings
-----------------------

When building a mixed-language application, you must be aware that
Ada enforces some partition-wide settings that may implicitly impact the
behavior of the other languages.

This is the case for certain signals that are reserved to the
implementation to implement proper Ada semantics (such as the behavior
of ``abort`` statements).
It means that the Ada part of the application may override signal handlers
that were previously installed by either the system or by other user code.

If your application requires that either system or user signals be preserved,
you need to instruct the Ada part not to install its own signal handler.
You do this using ``pragma Interrupt_State`` that provides a general
mechanism for overriding such uses of interrupts.

Additionally, you can use pragma ``Interrupts_System_By_Default`` to default
all interrupts to System.

The set of interrupts for which the Ada run-time library sets a specific signal
handler is the following:

* Ada.Interrupts.Names.SIGSEGV
* Ada.Interrupts.Names.SIGBUS
* Ada.Interrupts.Names.SIGFPE
* Ada.Interrupts.Names.SIGILL
* Ada.Interrupts.Names.SIGABRT

You can instruct the run-time library not to install its signal
handler for a particular signal by using the configuration pragma
``Interrupt_State`` in the Ada code. For example:

.. code-block:: ada

   pragma Interrupt_State (Ada.Interrupts.Names.SIGSEGV, System);
   pragma Interrupt_State (Ada.Interrupts.Names.SIGBUS,  System);
   pragma Interrupt_State (Ada.Interrupts.Names.SIGFPE,  System);
   pragma Interrupt_State (Ada.Interrupts.Names.SIGILL,  System);
   pragma Interrupt_State (Ada.Interrupts.Names.SIGABRT, System);

Obviously, if the Ada run-time system cannot set these handlers it comes with the
drawback of not fully preserving Ada semantics. ``SIGSEGV``, ``SIGBUS``, ``SIGFPE``
and ``SIGILL`` are used to raise corresponding Ada exceptions in the application,
while ``SIGABRT`` is used to asynchronously abort an action or a task.

.. _Generating_Ada_Bindings_for_C_and_C++_headers:

Generating Ada Bindings for C and C++ headers
---------------------------------------------

.. index:: Binding generation (for C and C++ headers)
.. index:: C headers (binding generation)
.. index:: C++ headers (binding generation)

GNAT includes a binding generator for C and C++ headers, which is
intended to do 95% of the tedious work of generating Ada specs from C
or C++ header files.

This capability is not intended to generate 100% correct Ada specs and
it will in some cases require you to make manual adjustments, although
it can often be used out of the box in practice.

Some of the known limitations include:

* only very simple character constant macros are translated into Ada
  constants. Function macros (macros with arguments) are partially translated
  as comments, to be completed manually if needed.
* some extensions (e.g. vector types) are not supported
* pointers to pointers are mapped to ``System.Address``
* identifiers with names that are identical except for casing may generate
  compilation errors (e.g. ``shm_get`` vs ``SHM_GET``).

The code is generated using Ada 2012 syntax, which makes it easier to interface
with other languages. In most cases, you can still use the generated binding
even if your code is compiled using earlier versions of Ada (e.g. ``-gnat95``).

.. _Running_the_binding_generator:

Running the Binding Generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The binding generator is part of the ``gcc`` compiler and you can
invoke it via the :switch:`-fdump-ada-spec` switch, which generates Ada
spec files for the header files specified on the command line and all
header files needed by these files transitively. For example:

.. code-block:: sh

      $ gcc -c -fdump-ada-spec -C /usr/include/time.h
      $ gcc -c *.ads

generates, under GNU/Linux, the following files: :file:`time_h.ads`,
:file:`bits_time_h.ads`, :file:`stddef_h.ads`, :file:`bits_types_h.ads` which
correspond to the files :file:`/usr/include/time.h`, and
:file:`/usr/include/bits/time.h` and then compile these Ada specs.
The name of the Ada specs is consistent with the relative path
under :file:`/usr/include/` of the header files. This behavior is specific to
paths ending with :file:`/include/`; in all the other cases, the name of the
Ada specs is derived from the simple name of the header files instead.

The :switch:`-C` switch tells ``gcc`` to extract comments from headers,
and attempt to generate corresponding Ada comments.

If you want to generate a single Ada file and not the transitive closure, you
can use instead the :switch:`-fdump-ada-spec-slim` switch.

You can optionally specify a parent unit, of which all generated units will
be children, using :switch:`-fada-spec-parent={unit}`.

The simple ``gcc``-based command works only for C headers. For C++ headers
you need to use either the ``g++`` command or the combination ``gcc -x c++``.

In some cases, the generated bindings will be more complete or more meaningful
when defining some macros, which you can do via the :switch:`-D` switch. This
is for example the case with :file:`Xlib.h` under GNU/Linux:

.. code-block:: sh

      $ gcc -c -fdump-ada-spec -DXLIB_ILLEGAL_ACCESS -C /usr/include/X11/Xlib.h

The above generates more complete bindings than a call without
the :switch:`-DXLIB_ILLEGAL_ACCESS` switch.

In other cases, you can't parse a header file in a stand-alone
manner because other include files need to be included first. In this
case, the solution is to create a small header file including the needed
``#include`` and possible ``#define`` directives. For example, to
generate Ada bindings for :file:`readline/readline.h`, you need to first
include :file:`stdio.h`, so you can create a file with the following two
lines in e.g. :file:`readline1.h`:

.. code-block:: cpp

      #include <stdio.h>
      #include <readline/readline.h>

and then generate Ada bindings from this file:

.. code-block:: sh

      $ gcc -c -fdump-ada-spec readline1.h


.. _Generating_bindings_for_C++_headers:

Generating Bindings for C++ Headers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Generating bindings for C++ headers is done using the same options, but
with the ``g++`` compiler. Note that generating Ada spec from C++ headers is a
much more complex job and support for C++ headers is much more limited that
support for C headers. As a result, you will need to modify the resulting
bindings by hand more extensively when using C++ headers.

In this mode, C++ classes are mapped to Ada tagged types, constructors
are mapped using the ``CPP_Constructor`` pragma, and when possible,
multiple inheritance of abstract classes are mapped to Ada interfaces
(see the *Interfacing to C++* section in the :title:`GNAT Reference Manual`
for additional information on interfacing to C++).

For example, given the following C++ header file:

.. code-block:: cpp

       class Carnivore {
       public:
          virtual int Number_Of_Teeth () = 0;
       };

       class Domestic {
       public:
          virtual void Set_Owner (char* Name) = 0;
       };

       class Animal {
       public:
         int Age_Count;
         virtual void Set_Age (int New_Age);
       };

       class Dog : Animal, Carnivore, Domestic {
        public:
         int  Tooth_Count;
         char *Owner;

         virtual int  Number_Of_Teeth ();
         virtual void Set_Owner (char* Name);

         Dog();
       };

The corresponding Ada code is generated:

.. code-block:: ada

         package Class_Carnivore is
           type Carnivore is limited interface;
           pragma Import (CPP, Carnivore);

           function Number_Of_Teeth (this : access Carnivore) return int is abstract;
         end;
         use Class_Carnivore;

         package Class_Domestic is
           type Domestic is limited interface;
           pragma Import (CPP, Domestic);

           procedure Set_Owner
             (this : access Domestic;
              Name : Interfaces.C.Strings.chars_ptr) is abstract;
         end;
         use Class_Domestic;

         package Class_Animal is
           type Animal is tagged limited record
             Age_Count : aliased int;
           end record;
           pragma Import (CPP, Animal);

           procedure Set_Age (this : access Animal; New_Age : int);
           pragma Import (CPP, Set_Age, "_ZN6Animal7Set_AgeEi");
         end;
         use Class_Animal;

         package Class_Dog is
           type Dog is new Animal and Carnivore and Domestic with record
             Tooth_Count : aliased int;
             Owner : Interfaces.C.Strings.chars_ptr;
           end record;
           pragma Import (CPP, Dog);

           function Number_Of_Teeth (this : access Dog) return int;
           pragma Import (CPP, Number_Of_Teeth, "_ZN3Dog15Number_Of_TeethEv");

           procedure Set_Owner
             (this : access Dog; Name : Interfaces.C.Strings.chars_ptr);
           pragma Import (CPP, Set_Owner, "_ZN3Dog9Set_OwnerEPc");

           function New_Dog return Dog;
           pragma CPP_Constructor (New_Dog);
           pragma Import (CPP, New_Dog, "_ZN3DogC1Ev");
         end;
         use Class_Dog;


.. _Switches_for_Ada_Binding_Generation:

Switches
^^^^^^^^

.. index:: -fdump-ada-spec (gcc)

:switch:`-fdump-ada-spec`
  Generate Ada spec files for the given header files transitively (including
  all header files that these headers depend upon).

.. index:: -fdump-ada-spec-slim (gcc)

:switch:`-fdump-ada-spec-slim`
  Only generate Ada spec files for the header files specified on the
  command line.

.. index:: -fada-spec-parent (gcc)

:switch:`-fada-spec-parent={unit}`
  Specifies that all files generated by :switch:`-fdump-ada-spec` are
  to be child units of the specified parent unit.

.. index:: -C (gcc)

:switch:`-C`
  Extract comments from headers and generate Ada comments in the Ada spec files.

.. _Generating_C_Headers_for_Ada_Specifications:

Generating C Headers for Ada Specifications
-------------------------------------------

.. index:: Binding generation (for Ada specs)
.. index:: C headers (binding generation)

GNAT includes a C header generator for Ada specifications that
supports Ada types that have a direct mapping to C types. This
specifically includes support for:

* Scalar types
* Constrained arrays
* Records (untagged)
* Composition of the above types
* Constant declarations
* Object declarations
* Subprogram declarations

Running the C Header Generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The C header generator is part of the GNAT compiler and can be invoked via
the :switch:`-gnatceg` switch, which generates a :file:`.h`
file corresponding to the given input file (Ada spec or body). Note that
only spec files are processed, so giving a spec or a body file
as input is equivalent. For example:

.. code-block:: sh

   $ gcc -c -gnatceg pack1.ads

generates a self-contained file called :file:`pack1.h` including
common definitions from the Ada Standard package followed by the
definitions included in :file:`pack1.ads` as well as all the other units
withed by this file.

For instance, given the following Ada files:

.. code-block:: ada

   package Pack2 is
      type Int is range 1 .. 10;
   end Pack2;

.. code-block:: ada

   with Pack2;

   package Pack1 is
      type Rec is record
         Field1, Field2 : Pack2.Int;
      end record;

      Global : Rec := (1, 2);

      procedure Proc1 (R : Rec);
      procedure Proc2 (R : in out Rec);
   end Pack1;

The above ``gcc`` command generates the following :file:`pack1.h` file:

.. code-block:: c

   /* Standard definitions skipped */
   #ifndef PACK2_ADS
   #define PACK2_ADS
   typedef short_short_integer pack2__TintB;
   typedef pack2__TintB pack2__int;
   #endif /* PACK2_ADS */

   #ifndef PACK1_ADS
   #define PACK1_ADS
   typedef struct _pack1__rec {
     pack2__int field1;
     pack2__int field2;
   } pack1__rec;
   extern pack1__rec pack1__global;
   extern void pack1__proc1(const pack1__rec r);
   extern void pack1__proc2(pack1__rec *r);
   #endif /* PACK1_ADS */

You can then ``include`` :file:`pack1.h` from a C source file and use the types,
call subprograms, reference objects, and constants.

.. _GNAT_and_Other_Compilation_Models:

GNAT and Other Compilation Models
=================================

This section compares the GNAT model with the approaches taken in
other environments: first the C/C++ model and then the mechanism that
has been used in other Ada systems, in particular those traditionally
used for Ada 83.

.. _Comparison_between_GNAT_and_C/C++_Compilation_Models:

Comparison between GNAT and C/C++ Compilation Models
----------------------------------------------------

The GNAT compilation model is close to the C and C++ models. You can
think of Ada specs as corresponding to header files in C. As in C, you
don't need to compile specs; they are compiled when they are used. The
Ada |with| is similar in effect to the ``#include`` of a C header.

One notable difference is that, in Ada, you may compile specs separately
to check them for semantic and syntactic accuracy. This is not always
possible with C headers because they are fragments of programs that have
less specific syntactic or semantic rules.

The other major difference is the requirement for running the binder,
which performs two important functions. First, it checks for
consistency. In C or C++, the only defense against assembling
inconsistent programs lies outside the compiler, in a :file:`makefile`, for
example. The binder satisfies the Ada requirement that it be impossible
to construct an inconsistent program when the compiler is used in normal
mode.

.. index:: Elaboration order control

The other important function of the binder is to deal with elaboration
issues. There are also elaboration issues in C++ that are handled
automatically. This automatic handling has the advantage of being
simpler to use, but the C++ programmer has no control over elaboration.
Where ``gnatbind`` might complain there was no valid order of
elaboration, a C++ compiler would simply construct a program that
malfunctioned at run time.

.. _Comparison_between_GNAT_and_Conventional_Ada_Library_Models:

Comparison between GNAT and Conventional Ada Library Models
-----------------------------------------------------------

This section is intended for Ada programmers who have
used an Ada compiler implementing the traditional Ada library
model, as described in the Ada Reference Manual.

.. index:: GNAT library

In GNAT, there is no 'library' in the normal sense. Instead, the set of
source files themselves acts as the library. Compiling Ada programs does
not generate any centralized information, but rather an object file and
a :file:`.ali` file, which are of interest only to the binder and linker.
In a traditional system, the compiler reads information not only from
the source file being compiled but also from the centralized library.
This means that the effect of a compilation depends on what has been
previously compiled. In particular:

* When a unit is |withed|, the unit seen by the compiler corresponds
  to the version of the unit most recently compiled into the library.

* Inlining is effective only if the necessary body has already been
  compiled into the library.

* Compiling a unit may obsolete other units in the library.

In GNAT, compiling one unit never affects the compilation of any other
units because the compiler reads only source files. Only changes to source
files can affect the results of a compilation. In particular:

* When a unit is |withed|, the unit seen by the compiler corresponds
  to the source version of the unit that is currently accessible to the
  compiler.

  .. index:: Inlining

* Inlining requires the appropriate source files for the package or
  subprogram bodies to be available to the compiler. Inlining is always
  effective, independent of the order in which units are compiled.

* Compiling a unit never affects any other compilations. The editing of
  sources may cause previous compilations to be out of date if they
  depended on the source file being modified.

The most important result of these differences is that order of compilation
is never significant in GNAT. There is no situation in which you are
required to do one compilation before another. What shows up as order of
compilation requirements in the traditional Ada library becomes, in
GNAT, simple source dependencies; in other words, there is only a set
of rules saying what source files must be present when a file is
compiled.


.. _Using_GNAT_Files_with_External_Tools:

Using GNAT Files with External Tools
====================================

This section explains how files that are produced by GNAT may be
used with tools designed for other languages.


.. _Using_Other_Utility_Programs_with_GNAT:

Using Other Utility Programs with GNAT
--------------------------------------

The object files generated by GNAT are in standard system format and, in
particular, the debugging information uses this format. This means
programs generated by GNAT can be used with existing utilities that
depend on these formats.

In general, any utility program that works with C will also often work with
Ada programs generated by GNAT. This includes software utilities such as
``gprof`` (a profiling program), ``gdb`` (the FSF debugger), and utilities such
as ``Purify``.


.. _The_External_Symbol_Naming_Scheme_of_GNAT:

The External Symbol Naming Scheme of GNAT
-----------------------------------------

To interpret the output from GNAT when using tools that are
originally intended for use with other languages, you need to
understand the conventions used to generate link names from the Ada
entity names.

All link names are in all lowercase. With the exception of library
procedure names, the mechanism used is simply to use the full expanded
Ada name with dots replaced by double underscores. For example, suppose
we have the following package spec:

.. code-block:: ada

     package QRS is
        MN : Integer;
     end QRS;

.. index:: pragma Export

The variable ``MN`` has a full expanded Ada name of ``QRS.MN``, so
the corresponding link name is ``qrs__mn``.
Of course if you use a pragma ``Export``, you maye override this:

.. code-block:: ada

     package Exports is
        Var1 : Integer;
        pragma Export (Var1, C, External_Name => "var1_name");
        Var2 : Integer;
        pragma Export (Var2, C, Link_Name => "var2_link_name");
     end Exports;

In this case, the link name for ``Var1`` is whatever link name the
C compiler would assign for the C function ``var1_name``. This typically
would be either ``var1_name`` or ``_var1_name``, depending on operating
system conventions, but other possibilities exist. The link name for
``Var2`` is ``var2_link_name``, and this is not operating system
dependent.

One exception occurs for library level procedures. A potential ambiguity
arises between the required name ``_main`` for the C main program,
and the name we would otherwise assign to an Ada library level procedure
called ``Main`` (which might well not be the main program).

To avoid this ambiguity, GNAT adds the prefix ``_ada_`` to such
names. So if we have a library level procedure such as:

.. code-block:: ada

     procedure Hello (S : String);

the external name of this procedure is ``_ada_hello``.

---

### Gcc Doc Libgdiagnostics Topics Compatibility (`gcc/doc/libgdiagnostics/topics/compatibility.rst`)

.. Copyright (C) 2015-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

ABI and API compatibility
=========================

The libgdiagnostics developers strive for ABI and API backward-compatibility:
programs built against libgdiagnostics.so stand a good chance of running
without recompilation against newer versions of libgdiagnostics.so, and
ought to recompile without modification against newer versions of
libgdiagnostics.h.

.. note:: The libgdiagnostics++.h C++ API is more experimental, and less
          locked-down at this time.

API compatibility is achieved by extending the API rather than changing
it.  For ABI compatibility, we avoid bumping the SONAME, and instead use
symbol versioning to tag each symbol, so that a binary linked against
libgdiagnostics.so is tagged according to the symbols that it uses.

For example, :func:`diagnostic_logical_location_get_kind` was added in
``LIBGDIAGNOSTICS_ABI_1``.  If a client program uses it, this can be detected
from metadata by using ``objdump``:

.. code-block:: bash

   $ objdump -p testsuite/libgdiagnostics/test-logical-location.c.exe | tail -n 7

   Version References:
     required from libc.so.6:
       0x09691a75 0x00 04 GLIBC_2.2.5
     required from libgdiagnostics.so.0:
       0x0ec567d1 0x00 03 LIBGDIAGNOSTICS_ABI_1
       0x0ec567d0 0x00 02 LIBGDIAGNOSTICS_ABI_0

You can see the symbol tags provided by libgdiagnostics.so using ``objdump``:

.. code-block:: bash

   $ objdump -p libgdiagnostics.so | less
   [...snip...]
   Version definitions:
   1 0x01 0x099ea4b0 libgdiagnostics.so.0
   2 0x00 0x0ec567d0 LIBGDIAGNOSTICS_ABI_0
   3 0x00 0x0ec567d1 LIBGDIAGNOSTICS_ABI_1
           LIBGDIAGNOSTICS_ABI_0
   [...snip...]

ABI symbol tags
***************

.. _LIBGDIAGNOSTICS_ABI_0:

``LIBGDIAGNOSTICS_ABI_0``
-------------------------

All entrypoints in the initial release of libgdiagnostics (in GCC 15) are
tagged with ``LIBGDIAGNOSTICS_ABI_0``; these entrypoints are:

  * :func:`diagnostic_manager_new`

  * :func:`diagnostic_manager_release`

  * :func:`diagnostic_manager_set_tool_name`

  * :func:`diagnostic_manager_set_full_name`

  * :func:`diagnostic_manager_set_version_string`

  * :func:`diagnostic_manager_set_version_url`

  * :func:`diagnostic_manager_add_text_sink`

  * :func:`diagnostic_text_sink_set_source_printing_enabled`

  * :func:`diagnostic_text_sink_set_colorize`

  * :func:`diagnostic_text_sink_set_labelled_source_colorization_enabled`

  * :func:`diagnostic_manager_add_sarif_sink`

  * :func:`diagnostic_manager_write_patch`

  * :func:`diagnostic_manager_new_file`

  * :func:`diagnostic_file_set_buffered_content`

  * :func:`diagnostic_manager_debug_dump_file`

  * :func:`diagnostic_manager_new_location_from_file_and_line`

  * :func:`diagnostic_manager_new_location_from_file_line_column`

  * :func:`diagnostic_manager_new_location_from_range`

  * :func:`diagnostic_manager_debug_dump_location`

  * :func:`diagnostic_manager_new_logical_location`

  * :func:`diagnostic_manager_debug_dump_logical_location`

  * :func:`diagnostic_manager_begin_group`

  * :func:`diagnostic_manager_end_group`

  * :func:`diagnostic_begin`

  * :func:`diagnostic_set_cwe`

  * :func:`diagnostic_add_rule`

  * :func:`diagnostic_set_location`

  * :func:`diagnostic_set_location_with_label`

  * :func:`diagnostic_add_location`

  * :func:`diagnostic_add_location_with_label`

  * :func:`diagnostic_set_logical_location`

  * :func:`diagnostic_add_fix_it_hint_insert_before`

  * :func:`diagnostic_add_fix_it_hint_insert_after`

  * :func:`diagnostic_add_fix_it_hint_replace`

  * :func:`diagnostic_add_fix_it_hint_delete`

  * :func:`diagnostic_add_execution_path`

  * :func:`diagnostic_manager_new_execution_path`

  * :func:`diagnostic_take_execution_path`

  * :func:`diagnostic_execution_path_release`

  * :func:`diagnostic_execution_path_add_event`

  * :func:`diagnostic_execution_path_add_event_va`

  * :func:`diagnostic_finish`

  * :func:`diagnostic_finish_va`

  * :func:`diagnostic_physical_location_get_file`

.. _LIBGDIAGNOSTICS_ABI_1:

``LIBGDIAGNOSTICS_ABI_1``
-------------------------
``LIBGDIAGNOSTICS_ABI_1`` covers the addition of these functions for
accessing values within a :type:`diagnostic_logical_location`:

  * :func:`diagnostic_logical_location_get_kind`

  * :func:`diagnostic_logical_location_get_parent`

  * :func:`diagnostic_logical_location_get_short_name`

  * :func:`diagnostic_logical_location_get_fully_qualified_name`

  * :func:`diagnostic_logical_location_get_decorated_name`

.. _LIBGDIAGNOSTICS_ABI_2:

``LIBGDIAGNOSTICS_ABI_2``
-------------------------
``LIBGDIAGNOSTICS_ABI_2`` covers the addition of these functions for
supporting command-line options and SARIF playback:

  * :func:`diagnostic_manager_add_sink_from_spec`

  * :func:`diagnostic_manager_set_analysis_target`

.. _LIBGDIAGNOSTICS_ABI_3:

``LIBGDIAGNOSTICS_ABI_3``
-------------------------

``LIBGDIAGNOSTICS_ABI_3`` covers the addition of these functions for
working with directed graphs:

  * :func:`diagnostic_manager_new_graph`

  * :func:`diagnostic_manager_take_global_graph`

  * :func:`diagnostic_take_graph`

  * :func:`diagnostic_graph_release`

  * :func:`diagnostic_graph_set_description`

  * :func:`diagnostic_graph_add_node`

  * :func:`diagnostic_graph_add_edge`

  * :func:`diagnostic_graph_get_node_by_id`

  * :func:`diagnostic_graph_get_edge_by_id`

  * :func:`diagnostic_node_set_label`

  * :func:`diagnostic_node_set_location`

  * :func:`diagnostic_node_set_logical_location`

.. _LIBGDIAGNOSTICS_ABI_4:

``LIBGDIAGNOSTICS_ABI_4``
-------------------------

``LIBGDIAGNOSTICS_ABI_4`` covers the addition of these functions for
working with :type:`diagnostic_message_buffer`.

  * :func:`diagnostic_message_buffer_new`

  * :func:`diagnostic_message_buffer_release`

  * :func:`diagnostic_message_buffer_append_str`

  * :func:`diagnostic_message_buffer_append_text`

  * :func:`diagnostic_message_buffer_append_byte`

  * :func:`diagnostic_message_buffer_append_printf`

  * :func:`diagnostic_message_buffer_append_event_id`

  * :func:`diagnostic_message_buffer_begin_url`

  * :func:`diagnostic_message_buffer_end_url`

  * :func:`diagnostic_message_buffer_begin_quote`

  * :func:`diagnostic_message_buffer_end_quote`

  * :func:`diagnostic_message_buffer_begin_color`

  * :func:`diagnostic_message_buffer_end_color`

  * :func:`diagnostic_message_buffer_dump`

  * :func:`diagnostic_finish_via_msg_buf`

  * :func:`diagnostic_add_location_with_label_via_msg_buf`

  * :func:`diagnostic_execution_path_add_event_via_msg_buf`

.. _LIBGDIAGNOSTICS_ABI_5:

``LIBGDIAGNOSTICS_ABI_5``
-------------------------

``LIBGDIAGNOSTICS_ABI_5`` covers the addition of this function:

  * :func:`diagnostic_manager_set_debug_physical_locations`

---

### Gcc Doc Libgdiagnostics Topics Diagnostic Manager (`gcc/doc/libgdiagnostics/topics/diagnostic-manager.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Diagnostic Managers
===================

.. type:: diagnostic_manager;

A :type:`diagnostic_manager` is an opaque bundle of state for a client of
libgdiagnostics.

It has zero of more "output sinks" to which diagnostics are emitted.

Responsibilities include:

* location-management

* caching of source file content

* patch generation

.. function:: diagnostic_manager *diagnostic_manager_new (void)

   Create a new diagnostic_manager.
   The caller will need to call :func:`diagnostic_release_manager`
   on it at some point.

   .. note:: No output sinks are created by default; so you will want
      to create one with something like:

      .. code-block::

	diagnostic_manager_add_text_sink (diag_mgr, stderr,
                                          DIAGNOSTIC_COLORIZE_IF_TTY);

.. function::  void diagnostic_manager_release (diagnostic_manager *diag_mgr)

   Release a diagnostic_manager.

   This will flush output to all of the output sinks, and clean up.

   The parameter must be non-NULL.

.. function:: int diagnostic_manager_add_sink_from_spec (diagnostic_manager *affected_mgr, \
				       const char *option_name, \
				       const char *spec, \
				       diagnostic_manager *control_mgr)

   This function can be used to support option processing similar to GCC's
   `-fdiagnostics-add-output= <https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html#index-fdiagnostics-add-output>`_.
   This allows command-line tools to support the same domain-specific
   language for specifying output sinks as GCC does.

   The function will attempt to parse ``spec`` as if it were
   an argument to GCC's `-fdiagnostics-add-output= <https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Message-Formatting-Options.html#index-fdiagnostics-add-output>`_.
   If successful, it will add an output sink to ``affected_mgr`` and return zero.
   Otherwise, it will emit an error diagnostic to ``control_mgr`` and
   return non-zero.

   ``affected_mgr`` and ``control_mgr`` can be the same manager,
   or be different managers.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_2`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_manager_add_sink_from_spec

.. function:: void diagnostic_manager_set_analysis_target (diagnostic_manager *mgr, \
	                                                   const diagnostic_file *file)

   This function sets the "main input file" of ``mgr`` to be
   ``file``.
   This affects the :code:`<title>` of generated HTML and
   the :code:`role` of the :code:`artifact` in SARIF output
   (`SARIF v2.1.0 section 3.24.6 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790867>`_).

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_2`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_manager_set_analysis_target

---

### Gcc Doc Libgdiagnostics Topics Diagnostics (`gcc/doc/libgdiagnostics/topics/diagnostics.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Diagnostics
===========

.. type:: diagnostic

A :type:`diagnostic` is an opaque bundle of state for a particular
diagnostic that is being constructed in memory.


Lifecycle of a diagnostic
*************************

Diagnostics are

* *created* from a :type:`diagnostic_manager` by using
  :func:`diagnostic_begin`, then

* *populated* with data, such as physical locations, logical locations,
  metadata, execution paths, or fix-it hints, then

* *finished*, in which a formatting string and arguments are given,
  via a call to :func:`diagnostic_finish` or :func:`diagnostic_finish_va`.
  The :type:`diagnostic_manager` will emit the diagnostic to all of the
  manager's output sinks (either immediately, or at some later time,
  depending on the sink).

  Once a :type:`diagnostic` has had one of these "finish" functions called
  on it, it is freed, and is no longer valid for use.

  The formatting strings use their own syntax; see :doc:`message-formatting`.

.. function::  diagnostic *diagnostic_begin (diagnostic_manager *diag_mgr, \
                                             enum diagnostic_level level)

   Create a new :type:`diagnostic` associated with the given
   :type:`diagnostic_manager`.

   The parameter ``diag_mgr`` must be non-NULL.

   The parameter ``level`` describes the severity of the diagnostic.

.. enum:: diagnostic_level

   This enum describes the severity of a particular diagnostic.

   .. macro:: DIAGNOSTIC_LEVEL_ERROR

      A problem sufficiently severe that the program cannot successfully
      complete, or where the input being analyzed is definitely wrong
      (e.g. malformed).

   .. macro:: DIAGNOSTIC_LEVEL_WARNING

      A problem where the input is technically correct, but is likely
      not what the user intended, such as common mistakes, or other
      unusual conditions that *may* indicate trouble, such as use of
      obsolete features.

   .. macro:: DIAGNOSTIC_LEVEL_NOTE

      A supplementary message added to another :type:`diagnostic`, giving
      extra information that may help the user understand it.

   .. macro:: DIAGNOSTIC_LEVEL_SORRY

      A problem where the input is valid, but the tool isn't
      able to handle it.

.. function:: void diagnostic_finish (diagnostic *diag, const char *fmt, ...)

   Emit ``diag`` to all sinks of its manager, and release ``diag``.  It is not
   valid to use ``diag`` after this call.

   Use parameter ``fmt`` for the message.
   Note that this uses gcc's pretty-print format, which is *not* printf.
   See :doc:`message-formatting`.

   Both ``diag`` and ``fmt`` must be non-NULL.

   TODO: who is responsible for putting FMT through gettext?

.. function:: void diagnostic_finish_va (diagnostic *diag, const char *fmt, va_list *args)

   This is equivalent to :func:`diagnostic_finish`, but using a
   :type:`va_list` rather than directly taking variadic arguments.

   All three parameters must be non-NULL.

.. function:: void diagnostic_finish_via_msg_buf (diagnostic *diag, \
			       diagnostic_message_buffer *msg_buf)

   This is equivalent to :func:`diagnostic_finish`, but using a message
   buffer rather than a format string and variadic arguments.

   ``diag`` and ``msg_buf`` must both be non-NULL.

   Calling this function transfers ownership of ``msg_buf`` to the
   diagnostic - do not call :func:`diagnostic_message_buffer_release` on
   it.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Diagnostic groups
*****************

See :doc:`the "adding notes" section of the tutorial <../tutorial/04-notes>`
for an example of a diagnostic group.

.. function:: void diagnostic_manager_begin_group (diagnostic_manager *diag_mgr)

  Begin a diagnostic group.  All diagnostics emitted within
  ``diag_mgr`` after the first one will be treated as additional information
  relating to the initial diagnostic.

  The parameter ``diag_mgr`` must be non-NULL.

.. function:: void diagnostic_manager_end_group (diagnostic_manager *diag_mgr)

   Finish a diagnostic group.

   The parameter ``diag_mgr`` must be non-NULL.

---

### Gcc Doc Libgdiagnostics Topics Execution Paths (`gcc/doc/libgdiagnostics/topics/execution-paths.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Execution paths
===============

.. type:: diagnostic_execution_path

A :type:`diagnostic` can optionally contain a :type:`diagnostic_execution_path`
describing a path of execution through code.

.. function:: diagnostic_execution_path * diagnostic_add_execution_path (diagnostic *diag)

   Create and borrow a pointer to an execution path for ``diag``.

   The path is automatically cleaned up when ``diag`` is finished.

   ``diag`` must be non-NULL.

.. function:: diagnostic_execution_path * diagnostic_manager_new_execution_path (diagnostic_manager *diag_mgr)

   Create a new execution path. This is owned by the caller and must have either
   :func:`diagnostic_take_execution_path` or
   :func:`diagnostic_execution_path_release` called on it.

   ``diag_mgr`` must be non-NULL.

.. function:: void diagnostic_take_execution_path (diagnostic *diag, diagnostic_execution_path *path)

   Set ``diag`` to use ``path`` as its execution path, taking ownership of ``path``.

   Both parameters must be non-NULL.

.. function:: void diagnostic_execution_path_release (diagnostic_execution_path *path)

   Release ownership of ``path``, which must not have been taken by a diagnostic.

.. type:: diagnostic_event_id

A :type:`diagnostic_event_id` identifies a particular event within a
:type:`diagnostic_execution_path` and can be used for expressing
cross-references between events.  In particular FIXME

.. function:: diagnostic_event_id diagnostic_execution_path_add_event (diagnostic_execution_path *path, \
                                                                       const diagnostic_physical_location *physical_loc, \
                                                                       const diagnostic_logical_location *logical_loc, \
                                                                       unsigned stack_depth, \
                                                                       const char *fmt, ...)

   Append an event to the end of ``path``, which must be non-NULL.

   ``physical_loc`` can be NULL, or non-NULL to associate the event
   with a :type:`diagnostic_physical_location`.

   ``logical_loc`` can be NULL, or non-NULL to associate the event
   with a :type:`diagnostic_logical_location`.

   ``stack_depth`` is for use in interprocedural paths and identifies the
   depth of the stack at the event.  Purely intraprocedural paths should
   use a stack depth of 1 for their events

   ``fmt`` must be non-NULL.  See :doc:`message-formatting` for details of
   how to use it.

.. function:: diagnostic_event_id diagnostic_execution_path_add_event_va (diagnostic_execution_path *path, \
                                                                          const diagnostic_physical_location *physical_loc, \
                                                                          const diagnostic_logical_location *logical_loc, \
                                                                          unsigned stack_depth, \
                                                                          const char *fmt, \
                                                                          va_list *args)

   Equivalent to :func:`diagnostic_execution_path_add_event`, but using a
   :type:`va_list` rather than directly taking variadic arguments.

.. function:: diagnostic_event_id diagnostic_execution_path_add_event_via_msg_buf (diagnostic_execution_path *path, \
                                                                                   const diagnostic_physical_location *physical_loc, \
                                                                                   const diagnostic_logical_location *logical_loc, \
                                                                                   unsigned stack_depth, \
                                                                                   diagnostic_message_buffer *msg_buf)

   This is equivalent to :func:`diagnostic_execution_path_add_event` but
   using a message buffer rather than a format string and variadic
   arguments.

   ``path`` and ``msg_buf`` must both be non-NULL.

   Calling this function transfers ownership of ``msg_buf`` to the
   path - do not call :func:`diagnostic_message_buffer_release` on it.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Paths are printed to text sinks, and for SARIF sinks each path is added as
a ``codeFlow`` object (see SARIF 2.1.0
`§3.36 codeFlow object <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790990>`_).

---

### Gcc Doc Libgdiagnostics Topics Fix It Hints (`gcc/doc/libgdiagnostics/topics/fix-it-hints.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Fix-it hints
============

Adding fix-it hints to a diagnostic
***********************************

A :type:`diagnostic` can contain "fix-it hints", giving suggestions
for the user on how to edit their code to fix a problem.  These
can be expressed as insertions, replacements, and removals of text.

There is only limited support for newline characters in fix-it hints:
only hints with newlines which insert an entire new line are permitted,
inserting at the start of a line, and finishing with a newline
(with no interior newline characters).  Other attempts to add
fix-it hints containing newline characters will fail.
Similarly, attempts to delete or replace a range *affecting* multiple
lines will fail.

The API handles these failures gracefully, so that diagnostics can attempt
to add fix-it hints without each needing extensive checking.

Fix-it hints are printed to text sinks, and are emitted by SARIF sinks
as ``fix`` objects (see SARIF 2.1.0
`§3.55 fix object <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141791131>`_).

Fix-it hints within a :type:`diagnostic` are "atomic": if any hints can't
be applied, none of them will be, and no fix-its hints will be displayed
for that diagnostic.  This implies that diagnostic messages need to be worded
in such a way that they make sense whether or not the fix-it hints
are displayed.

All fix-it hints within one :type:`diagnostic` must affect the same
:type:`diagnostic_file`.

.. function:: void diagnostic_add_fix_it_hint_insert_before (diagnostic *diag, \
                                                             const diagnostic_physical_location *loc, \
                                                             const char *addition)

   Add a fix-it hint to ``diag`` suggesting the insertion of the string
   ``addition`` before ``LOC``.

   For example::

     ptr = arr[0];
           ^~~~~~
           &

   This :type:`diagnostic` has a single location covering ``arr[0]``,
   with the caret at the start.  It has a single insertion fix-it hint,
   inserting ``&`` before the start of ``loc``.

.. function:: void diagnostic_add_fix_it_hint_insert_after (diagnostic *diag, \
                                                            const diagnostic_physical_location *loc, \
                                                            const char *addition)

   Add a fix-it hint to ``diag`` suggesting the insertion of the string
   ``addition`` after the end of ``LOC``.

   For example, in::

      #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2)
                                      ^~~~  ^~~~  ^~~~
                                      (   ) (   ) (   )


   the :type:`diagnostic` has three physical locations, covering ``ARG0``,
   ``ARG1``, and ``ARG2``, and 6 insertion fix-it hints: each arg
   has a pair of insertion fix-it hints, suggesting wrapping
   them with parentheses: one a '(' inserted before,
   the other a ')' inserted after.

.. function:: void diagnostic_add_fix_it_hint_replace (diagnostic *diag, \
                                                       const diagnostic_physical_location *loc, \
                                                       const char *replacement)

   Add a fix-it hint to ``diag`` suggesting the replacement of the text
   at ``LOC`` with the string ``replacement``.

   For example, in::

      c = s.colour;
	    ^~~~~~
	    color

   This :type:`diagnostic` has a single physical location covering ``colour``,
   and a single "replace" fix-it hint, covering the same range, suggesting
   replacing it with ``color``.

.. function:: void diagnostic_add_fix_it_hint_delete (diagnostic *diag, \
                                                      const diagnostic_physical_location *loc)

   Add a fix-it hint to ``diag`` suggesting the deletion of the text
   at ``LOC``.


   For example, in::

     struct s {int i};;
		      ^
		      -

   This :type:`diagnostic` has a single physical location at the stray
   trailing semicolon, along with a single removal fix-it hint, covering
   the same location.


Generating patches
******************

.. function:: void diagnostic_manager_write_patch (diagnostic_manager *diag_mgr, \
                                                   FILE *dst_stream)

   Write a patch to ``dst_stream`` consisting of the effect of all fix-it hints
   on all diagnostics that have been finished on ``diag_mgr``.

   Both parameters must be non-NULL.

---

### Gcc Doc Libgdiagnostics Topics Graphs (`gcc/doc/libgdiagnostics/topics/graphs.rst`)

.. Copyright (C) 2025-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Graphs
======

.. type:: diagnostic_graph

SARIF has support for capturing directed graphs (such as callgraphs
and control flow graphs), both at the level of the run as a whole,
and at the level of individual results.

libgdiagnostics supports this with the following entrypoints, allowing
directed graphs to be

* created (with :func:`diagnostic_manager_new_graph`)

* reported "globally" (with :func:`diagnostic_manager_take_global_graph`)

* reported as part of a :type:`diagnostic` (with :func:`diagnostic_take_graph`), or

* discarded (with :func:`diagnostic_graph_release`).

.. function:: diagnostic_graph * diagnostic_manager_new_graph (diagnostic_manager *manager)

   Create a new directed graph.

   The resulting graph is owned by the caller and must have one of
   :func:`diagnostic_manager_take_global_graph`,
   :func:`diagnostic_take_graph`,
   or :func:`diagnostic_graph_release` called on it to avoid leaks.

   The parameter ``manager`` must be non-null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: void diagnostic_manager_take_global_graph (diagnostic_manager *manager, \
				      diagnostic_graph *graph)

   Report this graph "globally", taking ownership of it.
   This won't appear in text sinks, but in SARIF sinks the graph will be
   added to theRun.graphs (SARIF v2.1.0 3.14.20).

   Parameters ``manager`` and ``graph`` must both be non-null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: void diagnostic_take_graph (diagnostic *diag, \
		      diagnostic_graph *graph)

   Add this graph to ``diag``, transferring ownership of it to ``diag``.
   This won't appear in text sinks, but in SARIF sinks the graph will be
   added to theResult.graphs (SARIF v2.1.0 3.27.19).

   Parameters ``diag`` and ``graph`` must both be non-null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: void diagnostic_graph_release (diagnostic_graph *graph)

   Release ``graph`` which must still be owned by the caller
   i.e. it must *not* have had
   :func:`diagnostic_manager_take_global_graph` or
   :func:`diagnostic_take_graph` called on it.

   Parameters ``graph`` can be null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.


.. function:: void diagnostic_graph_set_description (diagnostic_graph *graph, \
				 const char *description)

   Set the description of ``graph`` for use in the value of the
   SARIF ``description`` property (SARIF v2.1.0 section 3.39.2).

   The parameter ``graph`` must be non-null.
   The parameter ``description`` can be null, for clearing any existing
   description.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: diagnostic_node * diagnostic_graph_add_node (diagnostic_graph *graph, \
			   const char *node_id, \
			   diagnostic_node *parent_node)

   Create and add a new node within ``graph`` with the given `id``.
   The id must be unique within nodes in ``graph``.

   The parameters ``graph`` and ``id`` must be non-null.

   ``parent_node`` can be NULL (for a top-level node in the graph),
   or non-null for a child node, allowing for arbitrary nesting of
   nodes.

   The new node is owned by ``graph``.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: diagnostic_edge * diagnostic_graph_add_edge (diagnostic_graph *graph, \
			   const char *edge_id, \
			   diagnostic_node *src_node, \
			   diagnostic_node *dst_node, \
			   const char *label)

   Create and add a new edge within ``graph``.

   The parameters ``graph``, ``src_node`` and ``dest_node``
   must be non-null.

   If non-null, then ``edge_id`` must be unique within ``graph``;
   if ``edge_id`` is null then a unique id of the form "edge0", "edge1",
   etc will be used automatically.

   If non-null, then ``label`` will be used for the value of the
   SARIF ``label`` property (SARIF v2.1.0 section 3.41.3).

   The new edge is owned by ``graph``.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: diagnostic_node *diagnostic_graph_get_node_by_id (diagnostic_graph *graph, \
				 const char *node_id)

   Get the node in ``graph`` with the given id, or null.

   The parameters ``graph`` and ``node_id`` must be non-null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: diagnostic_edge *diagnostic_graph_get_edge_by_id (diagnostic_graph *graph, \
				 const char *edge_id)

   Get the edge in ``graph`` with the given id, or null.

   The parameters ``graph`` and ``edge_id`` must be non-null.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.


.. type:: diagnostic_node

.. function:: void diagnostic_node_set_label (diagnostic_node *node, \
			   const char *label)

   Set the label of ``node`` for use in the value of the
   SARIF ``label`` property (SARIF v2.1.0 section 3.40.3).

   The parameter ``node`` must be non-null.
   The parameter ``label`` can be null, for clearing any existing
   label.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: void diagnostic_node_set_location (diagnostic_node *node, \
			      const diagnostic_physical_location *loc)

   Set the physical location of ``node``, if any.

   The parameter ``node`` must be non-null.
   The parameter ``loc`` can be null, for clearing any existing
   location.

   If set, the value will be used by SARIF sinks within the
   ``location`` property  (SARIF v2.1.0 section 3.40.4).

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

.. function:: void diagnostic_node_set_logical_location (diagnostic_node *node, \
				      const diagnostic_logical_location *logical_loc)

   Set the logical location of ``node``, if any.

   The parameter ``node`` must be non-null.
   The parameter ``logical_loc`` _can be null, for clearing any existing
   location.

   If set, the value will be used by SARIF sinks within the
   ``location`` property  (SARIF v2.1.0 section 3.40.4).

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`.

---

### Gcc Doc Libgdiagnostics Topics Index (`gcc/doc/libgdiagnostics/topics/index.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c


Topic reference
===============

.. toctree::
   :maxdepth: 2

   retrofitting.rst
   diagnostic-manager.rst
   diagnostics.rst
   message-formatting.rst
   message-buffers.rst
   physical-locations.rst
   logical-locations.rst
   metadata.rst
   fix-it-hints.rst
   execution-paths.rst
   text-output.rst
   sarif.rst
   graphs.rst
   ux.rst
   compatibility.rst

---

### Gcc Doc Libgdiagnostics Topics Logical Locations (`gcc/doc/libgdiagnostics/topics/logical-locations.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Logical locations
=================

A "logical" location is a location expressed in terms of
construct in a programming language, such as ``within function 'foo'``
(as opposed to a :doc:`"physical" location <physical-locations>`, which
refers to a specific file, and line(s) and/or column(s))

Creating location information
*****************************

.. type:: diagnostic_logical_location

A :type:`diagnostic_logical_location` is an opaque type describing a "logical"
source location

.. function:: const diagnostic_logical_location * diagnostic_manager_new_logical_location (diagnostic_manager *diag_mgr, \
                                                                                           enum diagnostic_logical_location_kind_t kind, \
                                                                                           const diagnostic_logical_location *parent, \
                                                                                           const char *short_name, \
                                                                                           const char *fully_qualified_name, \
                                                                                           const char *decorated_name)

   Create a :type:`diagnostic_logical_location`.

   ``diag_mgr`` must be non-NULL.

   ``kind`` describes the kind of logical location:

   .. enum:: diagnostic_logical_location_kind_t

      This roughly corresponds to the ``kind`` property in SARIF v2.1.0
      (`§3.33.7 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790976>`_).

      Kinds within executable code:

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MEMBER

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_MODULE

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_NAMESPACE

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_TYPE

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_RETURN_TYPE

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_PARAMETER

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_VARIABLE

      Kinds within XML or HTML documents:

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_ELEMENT

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_ATTRIBUTE

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_TEXT

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_COMMENT

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROCESSING_INSTRUCTION

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_DTD

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_DECLARATION

      Kinds within JSON documents:

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_OBJECT

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_ARRAY

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_PROPERTY

      .. macro:: DIAGNOSTIC_LOGICAL_LOCATION_KIND_VALUE

   ``parent`` can be NULL; if non-NULL it can be used to express tree-like
   nesting of logical locations, such as in::

     namespace foo { namespace bar { class baz { baz (); }; } }

   where a diagnostic within ``baz``'s constructor could be reported
   as being within ``foo::bar::baz::baz`` where the logical locations
   are two namespaces, a type, and a member, respectively.

   ``short_name`` can be NULL, or else a string suitable for use by
   the SARIF logicalLocation ``name`` property
   (SARIF v2.1.0 `§3.33.4 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790973>`_).

   ``fully_qualified_name`` can be NULL or else a string  suitable for use by
   the SARIF logicalLocation ``fullyQualifiedName`` property
   (SARIF v2.1.0 `§3.33.5 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790974>`_).

   ``decorated_name`` can be NULL or else a string suitable for use by
   the SARIF logicalLocation ``decoratedName`` property
   (SARIF v2.1.0 `§3.33.6 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790975>`_).

   Repeated calls to :func:`diagnostic_manager_new_logical_location` with
   "equal" input values on the same :type:`diagnostic_manager` will return
   the same instance of :type:`diagnostic_logical_location`.  "Equal" here
   includes different string buffers that compare as equal with
   :func:`strcmp`.

.. function:: void diagnostic_manager_debug_dump_logical_location (const diagnostic_manager *diag_mgr, \
                                                                   const diagnostic_logical_location *loc, \
                                                                   FILE *out)

   Write a representation of ``file`` to ``out``, for debugging.
   Both ``diag_mgr`` and ``out`` must be non-NULL.
   ``file`` may be NULL.

   TODO: example of output

Associating diagnostics with locations
**************************************

.. function:: void diagnostic_set_logical_location (diagnostic *diag, \
                                                    const diagnostic_logical_location *logical_loc)

    Set the logical location of ``diag``.

    ``diag`` must be non-NULL; ``logical_loc`` can be NULL.

Accessors
*********

The following functions can be used to access the data that was passed to a
:type:`diagnostic_logical_location` when it was created.  In each case, the
``loc`` parameter must be non-NULL.  The return values will point
at *copies* of the original buffer owned by the
:type:`diagnostic_logical_location`, or be null.

.. function:: enum diagnostic_logical_location_kind_t diagnostic_logical_location_get_kind (const diagnostic_logical_location *loc)

.. function:: const diagnostic_logical_location *diagnostic_logical_location_get_parent (const diagnostic_logical_location *loc)

.. function:: const char *diagnostic_logical_location_get_short_name (const diagnostic_logical_location *loc)

.. function:: const char *diagnostic_logical_location_get_fully_qualified_name (const diagnostic_logical_location *loc)

.. function:: const char *diagnostic_logical_location_get_decorated_name (const diagnostic_logical_location *loc)

The above accessors were added in :ref:`LIBGDIAGNOSTICS_ABI_1`; you can
test for their presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_LOGICAL_LOCATION_ACCESSORS

---

### Gcc Doc Libgdiagnostics Topics Message Buffers (`gcc/doc/libgdiagnostics/topics/message-buffers.rst`)

.. Copyright (C) 2025-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Message buffers
===============

.. type:: diagnostic_message_buffer

A :type:`diagnostic_message_buffer` is a buffer into which text can be
accumulated, before being used:

* as the message of a diagnostic, using :func:`diagnostic_finish_via_msg_buf`

* as the text of a label for a :type:`diagnostic_physical_location` using
  :func:`diagnostic_add_location_with_label_via_msg_buf`

* as the text of an event within a :type:`diagnostic_execution_path` using
  :func:`diagnostic_execution_path_add_event_via_msg_buf`

This is to allow more flexible creation of messages than a "format string
plus variadic arguments" API.

.. function:: diagnostic_message_buffer * diagnostic_message_buffer_new (void)

   This function creates a new :type:`diagnostic_message_buffer`.

   The caller is responsible for cleaning it up, either by handing it off
   to one of the API entrypoints that takes ownership of it (such as
   :func:`diagnostic_finish_via_msg_buf`), or by calling
   :func:`diagnostic_message_buffer_release` on it.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_release (diagnostic_message_buffer *msg_buf)

   This function releases ``msg_buf``.

   Typically you don't need to call this, but instead will pass the
   buffer to one of the API entrypoints that takes over ownership of
   it (such as :func:`diagnostic_finish_via_msg_buf`); calling it
   after this would lead to a double-free bug, as you no longer "own"
   the buffer.

   ``msg_buf`` must be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_append_str (diagnostic_message_buffer *msg_buf, \
				      const char *p)

   This function appends the null-terminated string ``p`` to the buffer.
   The string is assumed to be UTF-8 encoded.

   ``msg_buf`` and ``p`` must both be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_append_text (diagnostic_message_buffer *msg_buf, \
	       const char *p, \
	       size_t len)

   This function appends ``len`` bytes from ``p`` to the buffer.
   The bytes are assumed to be UTF-8 encoded.

   ``msg_buf`` and ``p`` must both be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_append_byte (diagnostic_message_buffer *msg_buf,\
				       char ch)

   This function appends ``ch`` to the buffer.  This should be either
   ASCII, or part of UTF-8 encoded text.

   ``msg_buf`` must be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_append_printf (diagnostic_message_buffer *msg_buf, \
					 const char *fmt, ...)

   This function appends a formatted string to the buffer, using the
   formatting rules for ``printf``.

   The string is assumed to be UTF-8 encoded.

   ``msg_buf`` and ``fmt`` must both be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_append_event_id (diagnostic_message_buffer *msg_buf, \
					   diagnostic_event_id event_id)

   This function appends a :type:`diagnostic_event_id` to the buffer.

   ``msg_buf`` must be non-NULL.

   For text output, the event will be printed in the form ``(1)``.

   This is analogous to the
   :doc:`%@ message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Hyperlink support
*****************

.. function:: void diagnostic_message_buffer_begin_url (diagnostic_message_buffer *msg_buf, \
				     const char *url)

   This function indicates the beginning of a run of text that should be
   associated with the given URL.  The run of text should be closed with
   a matching call to :func:`diagnostic_message_buffer_end_url`.

   ``msg_buf`` and ``url`` must both be non-NULL.

   For text output in a suitably modern terminal, the run of text will
   be emitted as a clickable hyperlink to the URL.

   For SARIF sinks, the run of text will be emitted using SARIF's
   embedded link syntax.

   This is analogous to the
   :doc:`%{ message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_end_url (diagnostic_message_buffer *msg_buf)

   This function ends a run of text within the buffer started with
   :func:`diagnostic_message_buffer_begin_url`.

   ``msg_buf`` must be non-NULL.

   This is analogous to the
   :doc:`%} message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Quoted text
***********

.. function:: void diagnostic_message_buffer_begin_quote (diagnostic_message_buffer *msg_buf)

   This function indicates the beginning of a run of text that should be
   printed in quotes.  The run of text should be closed with
   a matching call to :func:`diagnostic_message_buffer_end_quote`.

   ``msg_buf`` must be non-NULL.

   For text output in a suitably modern terminal, the run of text will
   appear in bold.
   be emitted as a clickable hyperlink to the URL.

   For SARIF sinks, the run of text will be emitted using SARIF's
   embedded link syntax.

   This is analogous to the
   ``%<``:doc:`message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_end_quote (diagnostic_message_buffer *msg_buf)

   This function ends a run of text started with
   :func:`diagnostic_message_buffer_begin_quote`.

   ``msg_buf`` must be non-NULL.

   This is analogous to the
   :doc:`%> message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Color
*****

.. function:: void diagnostic_message_buffer_begin_color (diagnostic_message_buffer *msg_buf, \
				     const char *color)

   This function indicates the beginning of a run of text that should be
   colorized as the given color.  The run of text should be closed with
   a matching call to :func:`diagnostic_message_buffer_end_color`.

   The precise set of available color names is currently undocumented.

   ``msg_buf`` and ``color`` must both be non-NULL.

   For text output in a suitable terminal, the run of text will
   be colorized.

   For SARIF sinks, the run of text will be emitted using SARIF's
   embedded link syntax.

   This is analogous to the
   :doc:`%r message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_message_buffer_end_color (diagnostic_message_buffer *msg_buf)

   This function ends a run of text within the buffer started with
   :func:`diagnostic_message_buffer_begin_color`.

   ``msg_buf`` must be non-NULL.

   This is analogous to the
   :doc:`%R message formatting code <message-formatting>`.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

Debugging a message buffer
**************************

.. function:: void diagnostic_message_buffer_dump (const diagnostic_message_buffer *msg_buf, \
				FILE *outf)

   This function writes a representation of the contents of ``msg_buf``
   to ``outf``, for debugging.

   ``msg_buf`` can be NULL or non-NULL.
   ``outf`` must be non-NULL.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_4`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

---

### Gcc Doc Libgdiagnostics Topics Message Formatting (`gcc/doc/libgdiagnostics/topics/message-formatting.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Message formatting
==================

Various libgdiagnostics entrypoints take a format string and
variadic arguments.

.. note::

   See also :type:`diagnostic_message_buffer`, which offers an
   alternative way to build up messages.

The format strings take codes prefixed by ``%``, or ``%q`` to put
the result in quotes.  For example::

   "hello %s", "world"

would print::

   hello world

whereas::

   "hello %qs", "world"

would print::

   hello `world'

where ```world'`` would be displayed in bold if colorization were enabled
in the terminal.

The following format specifiers are accepted:


Numbers
*******

``d`` and ``i`` (``signed int``), ``u`` (``unsigned int``)
   ``%d``, ``%i``, and ``%u`` print integers in base ten.  For example::

     "the answer is %i", 42

   would print::

     the answer is 42

``o`` (``unsigned int``)
   Print the integer in base eight

``x`` (``unsigned int``)
   Print the integer in base sixteen

The above can be prefixed with ``l`` and ``ll`` prefixes to take
``long`` and ``long long`` values of the appropriate signedness.

For example::

   "address: %lx", (unsigned long)0x108b516

would print::

   address: 108b516

Similarly, the prefix ``z`` can be used for ``size_t``::

  "size: %zd", sizeof(struct foo)
  size: 32

and ``t`` for ptrdiff_t.
  
``f`` (``double``)
   ``%f`` prints a floating-point value.  For example::

     "value: %f", 1.0

   might print::

     value: 1.000000


Strings
*******

``c`` (``char``)
   ``%c`` prints a single character.

``s`` (``const char *``)
   ``%s`` prints a string.

   Note that if the string refers to something that might
   appear in the input file (such as the name of a function), it's better
   to quote the value; for example::

     "unrecognized identifier: %qs", "foo"

   might print::

     unrecognized identifier: `foo'

``m`` (no argument)
   Prints ``strerror(errno)``, for example::

     "can't open %qs: %m"

   might print::

     can't open `foo.txt': No such file or directory

``%`` (no argument)
   ``%%`` prints a `%` character, for example::

     "8%% of 75 is 75%% of 8, and is thus 6"

   prints::

     8% of 75 is 75% of 8, and is thus 6

``'`` (no argument)
  ``%'`` prints an apostrophe.  This should only be used in untranslated messages;
  translations should use appropriate punctuation directly.


Other format specifiers
***********************

``p`` (pointer)
   ``%p`` prints a pointer, although the precise format is
   implementation-defined.

``r`` (``const char *``)
   ``%r`` starts colorization on suitable text sinks, where the argument
   specifies the name of the kind of entity to be colored, such as ``error``.

``R`` (no argument)
   ``%R`` stops colorization

``<`` and ``>`` (no arguments)
   ``%<`` adds an opening quote and ``%>`` a closing quote, such as::

     "missing element %<%s:%s%>", ns, name

   which might be printed as::

     missing element `xhtml:head'

   If the thing to be quoted can be handled with another format specifier,
   then it's simpler to use ``q`` with it.  For example, it's much
   simpler to print a ``const char *`` in quotes via::

      "%qs", str

   rather than the error-prone::
     
      "%<%s%>", str

``{`` (``const char *``)
   ``%{`` starts a link; the argument is the URL.  This will be displayed
   in a suitably-capable terminal if a text sink is directly connected to
   a tty, and will be captured in SARIF output.

``}`` (no argument)
   ``%}`` stops a link started with ``%{``.

   For example::

      "for more information see %{the documentation%}", "https://example.com"

   would be printed as::

      for more information see the documentation

   with the URL emitted in suitable output sinks.

``@`` (``diagnostic_event_id *``)
   ``%@`` prints a reference to an event in a
   :type:`diagnostic_execution_path`, where the :type:`diagnostic_event_id`
   is passed by pointer.

   For example, if ``event_id`` refers to the first event in a path, then::

      "double-%qs of %qs; first %qs was at %@",
      function, ptr, function, &event_id

   might print::

     double-`free' of `p'; first `free` was at (1)

.. :

   TODO:

   %.*s: a substring the length of which is specified by an argument
	 integer.
   %Ns: likewise, but length specified as constant in the format string.
   %Z: Requires two arguments - array of int, and len. Prints elements
   of the array.

   %e: Consumes a pp_element * argument.

   Arguments can be used sequentially, or through %N$ resp. *N$
   notation Nth argument after the format string.  If %N$ / *N$
   notation is used, it must be used for all arguments, except %m, %%,
   %<, %>, %} and %', which may not have a number, as they do not consume
   an argument.  When %M$.*N$s is used, M must be N + 1.  (This may
   also be written %M$.*s, provided N is not otherwise used.)  The
   format string must have conversion specifiers with argument numbers
   1 up to highest argument; each argument may only be used once.
   A format string can have at most 30 arguments.  */

---

### Gcc Doc Libgdiagnostics Topics Metadata (`gcc/doc/libgdiagnostics/topics/metadata.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Adding metadata
===============

Tool metadata
*************

It's possible to set up various metadata on the :type:`diagnostic_manager`
as a whole, describing the program creating the diagnostics.

.. note::

   It's not required to set up any of this up on a
   :type:`diagnostic_manager`.  However, if you are doing
   :doc:`SARIF output <sarif>`, then you need to at least call
   :func:`diagnostic_manager_set_tool_name` or the generated ``.sarif``
   file will not validate against the schema.

.. function:: void diagnostic_manager_set_tool_name (diagnostic_manager *diag_mgr, \
                                                     const char *value)

   Set a string for the name of the tool emitting the diagnostics.

   Both parameters must be non-NULL.

   If set, this string will be used

   * by :doc:`text output sinks <text-output>` as a prefix for output
     when no physical location is available, replacing ``progname``
     in the following:

     .. code-block:: console

	$ ./tut01-hello-world
	progname: error: I'm sorry Dave, I'm afraid I can't do that

   * by :doc:`SARIF output sinks <sarif>` as the value for the
     ``name`` property of the ``driver``
     (`SARIF v2.1.0 §3.19.8 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790791>`_).

.. function:: void diagnostic_manager_set_full_name (diagnostic_manager *diag_mgr, \
                                                      const char *value)

   Set a string giving the name of the tool along with the its version and
   other useful information::

     diagnostic_manager_set_full_name (diag_mgr, "FooChecker 0.1 (en_US)");

   If set, this string will be used by :doc:`SARIF output sinks <sarif>` as
   the value for the ``fullName`` property of the ``driver``
   (`SARIF v2.1.0 §3.19.9 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790792>`_).

   Both parameters must be non-NULL.

.. function:: void diagnostic_manager_set_version_string (diagnostic_manager *diag_mgr, \
                                                          const char *value)

   Set a string suitable for use as the value of the SARIF ``version`` property
   of the ``driver``.
   (`SARIF v2.1.0 §3.19.13 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790796>`_)::

     diagnostic_manager_set_version_string (diag_mgr, "0.1");

   Both parameters must be non-NULL.

.. function:: void diagnostic_manager_set_version_url (diagnostic_manager *diag_mgr, \
                                                       const char *value)

   Set a string suitable for use as the value of the SARIF ``informationUri``
   property of the ``driver``.
   (`SARIF v2.1.0 §3.19.17 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790800>`_)::

     diagnostic_manager_set_version_url (diag_mgr,
                                         "https://www.example.com/foo-checker/releases/0.1/");

  Both parameters must be non-NULL.

Adding metadata to a diagnostic
*******************************

.. function:: void diagnostic_set_cwe (diagnostic *diag, \
                                       unsigned cwe_id)

   Associate ``diag`` with the given ID within
   the `Common Weakness Enumeration <https://cwe.mitre.org/>`_::

     /* CWE-242: Use of Inherently Dangerous Function.  */
     diagnostic_set_cwe (d, 242);

   ``diag`` must be non-NULL.

   The CWE value will be printed by text sinks after the message::

     test-metadata.c:21:3: warning: never use 'gets' [CWE-242]

   and in a sufficiently-capable terminal will be a link to
   documentation about the CWE.

.. function:: void diagnostic_add_rule (diagnostic *diag, \
                                        const char *title, \
                                        const char *url)

   Associate this :type:`diagnostic` with a particular rule that has been
   violated (such as in a coding standard, or within a specification).

   A diagnostic can be associated with zero or more rules.

   ``diag`` must be non-NULL.  The rule must have at least one of a
   title and a URL, but these can be NULL.

   For example, given::

     diagnostic_add_rule (d,
                          "MSC24-C",
                          "https://wiki.sei.cmu.edu/confluence/display/c/MSC24-C.+Do+not+use+deprecated+or+obsolescent+functions");

   the rule name will be printed by text sinks after the message::

     test-metadata.c:21:3: warning: never use 'gets' [MSC24-C]
      21 |   gets (buf);
         |   ^~~~~~~~~~

   and if so, the URL will be available in a sufficiently capable
   terminal.

   This can be used in conjunction with :func:`diagnostic_set_cwe`,
   giving output like this::

     test-metadata.c:21:3: warning: never use 'gets' [CWE-242] [MSC24-C]
      21 |   gets (buf);
         |   ^~~~~~~~~~

---

### Gcc Doc Libgdiagnostics Topics Physical Locations (`gcc/doc/libgdiagnostics/topics/physical-locations.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Physical locations
==================

A "physical" source location is a location expressed in terms of
a specific file, and line(s) and column(s) (as opposed to a
:doc:`"logical" location <logical-locations>`,
which refers to semantic constructs in a programming language).

Creating location information
*****************************

The :type:`diagnostic_manager` manages various objects relating to
locations.

.. type:: diagnostic_file

   A :type:`diagnostic_file` is an opaque type describing a particular input file.

.. function:: diagnostic_file * diagnostic_manager_new_file (diagnostic_manager *diag_mgr, \
                                                             const char *name, \
                                                             const char *sarif_source_language)

   Create a new :type:`diagnostic_file` for file ``name``. Repeated calls
   with strings that match ``name`` will return the same object.

   Both ``diag_mgr`` and ``name`` must be non-NULL.

   If ``sarif_source_language`` is non-NULL, it specifies a
   ``sourceLanguage`` value for the file for use when writing
   :doc:`SARIF <sarif>`
   (`SARIF v2.1.0 §3.24.10 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790871>`_).
   See
   `SARIF v2.1.0 Appendix J <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141791197>`_
   for suggested values for various programming languages.

   For example, this creates a :type:`diagnostic_file` for ``foo.c``
   and identifies it as C source code::

     foo_c = diagnostic_manager_new_file (diag_mgr,
                                          "foo.c",
                                          "c" /* source_language */);

.. function::  void diagnostic_manager_debug_dump_file (diagnostic_manager *diag_mgr, \
                                                        const diagnostic_file *file, \
                                                        FILE *out)

   Write a representation of ``file`` to ``out``, for debugging.
   Both ``diag_mgr`` and ``out`` must be non-NULL.
   `file`` may be NULL.

   For example::

     diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr);

   might lead to this output::

      file(name="foo.c", sarif_source_language="c")

.. type:: diagnostic_line_num_t

A :type:`diagnostic_line_num_t` is used for representing line numbers
within text files.  libgdiagnostics treats the first line of a text file
as line 1.

.. type:: diagnostic_column_num_t

A :type:`diagnostic_column_num_t` is used for representing column numbers
within text files.  libgdiagnostics treats the first column of a text line
as column 1, **not** column 0.

.. note::

   Both libgdiagnostics and Emacs number source *lines* starting at 1, but
   they have differing conventions for *columns*.

   libgdiagnostics uses a 1-based convention for source columns,
   whereas Emacs's ``M-x column-number-mode`` uses a 0-based convention.

   For example, an error in the initial, left-hand
   column of source line 3 is reported by libgdiagnostics as::

     some-file.c:3:1: error: ...etc...

   On navigating to the location of that error in Emacs
   (e.g. via ``next-error``),
   the locus is reported in the Mode Line
   (assuming ``M-x column-number-mode``) as::

     some-file.c   10%   (3, 0)

   i.e. ``3:1:`` in libgdiagnostics corresponds to ``(3, 0)`` in Emacs.

.. type:: diagnostic_physical_location

A :type:`diagnostic_physical_location` is an opaque type representing a
key into a database of source locations within a :type:`diagnostic_manager`.

:type:`diagnostic_physical_location` instances are created by various API
calls into the :type:`diagnostic_manager` expressing source code points
and ranges.

They persist until the :type:`diagnostic_manager` is released, which
cleans them up.

A ``NULL`` value means "unknown", and can be returned by the
:type:`diagnostic_manager` as a fallback when a problem occurs
(e.g. too many locations).

A :type:`diagnostic_physical_location` can be a single point within the
source code, such as here (at the the '"' at the start of the string literal)::

  int i = "foo";
          ^

or be a range with a start and finish, and a "caret" location::

   a = (foo && bar)
       ~~~~~^~~~~~~

where the caret here is at the first "&", and the start and finish
are at the parentheses.

.. function::  const diagnostic_physical_location *diagnostic_manager_new_location_from_file_and_line (diagnostic_manager *diag_mgr, \
                                                                                                       const diagnostic_file *file,  \
                                                                                                       diagnostic_line_num_t line_num)

   Attempt to create a :type:`diagnostic_physical_location` representing
   ``FILENAME:LINE_NUM``, with no column information (thus representing
   the whole of the given line.

   Both ``diag_mgr`` and ``file`` must be non-NULL.

.. function::  const diagnostic_physical_location * diagnostic_manager_new_location_from_file_line_column (diagnostic_manager *diag_mgr, \
                                                                                                           const diagnostic_file *file, \
                                                                                                           diagnostic_line_num_t line_num, \
                                                                                                           diagnostic_column_num_t column_num)

   Attempt to create a :type:`diagnostic_physical_location` for
   ``FILENAME:LINE_NUM:COLUMN_NUM`` representing a particular point
   in the source file.

   Both ``diag_mgr`` and ``file`` must be non-NULL.

.. function::  const diagnostic_physical_location *diagnostic_manager_new_location_from_range (diagnostic_manager *diag_mgr,\
                                                                                               const diagnostic_physical_location *loc_caret,\
                                                                                               const diagnostic_physical_location *loc_start,\
                                                                                               const diagnostic_physical_location *loc_end)

   Attempt to create a diagnostic_physical_location representing a
   range within a source file, with a highlighted "caret" location.

   All must be within the same file, but they can be on different lines.

   For example, consider the location of the binary expression below::

     ...|__________1111111112222222
     ...|12345678901234567890123456
     ...|
     521|int sum (int foo, int bar)
     522|{
     523|   return foo + bar;
     ...|          ~~~~^~~~~
     524|}

   The location's caret is at the "+", line 523 column 15, but starts
   earlier, at the "f" of "foo" at column 11.  The finish is at the "r"
   of "bar" at column 19.

   ``diag_mgr`` must be non-NULL.

.. function::  void diagnostic_manager_debug_dump_location (const diagnostic_manager *diag_mgr,\
                                                            const diagnostic_physical_location *loc, \
                                                            FILE *out)

   Write a representation of ``loc`` to ``out``, for debugging.

   Both ``diag_mgr`` and ``out`` must be non-NULL.
   `loc`` may be NULL.

   TODO: example of output

.. function::  diagnostic_file *diagnostic_physical_location_get_file (const diagnostic_physical_location *physical_loc)

   Get the :type:`diagnostic_file` associated with a given physical location.


Associating diagnostics with locations
**************************************

A :type:`diagnostic` has an optional primary physical location
and zero or more secondary physical locations.  For example::

   a = (foo && bar)
       ~~~~~^~~~~~~

This diagnostic has a single :type:`diagnostic_physical_location`,
with the caret at the first "&", and the start/finish at the parentheses.

Contrast with::

   a = (foo && bar)
        ~~~ ^~ ~~~

This diagnostic has three locations

* The primary location (at "&&") has its caret and start location at
  the first "&" and end at the second "&.

* The secondary location for "foo" has its start and finish at the "f"
  and "o" of "foo"; the caret is not displayed, but is perhaps at
  the "f" of "foo".

* Similarly, the other secondary location (for "bar") has its start and
  finish at the "b" and "r" of "bar"; the caret is not displayed, but
  is perhaps at the"b" of "bar".

.. function::  void diagnostic_set_location (diagnostic *diag, \
                                             const diagnostic_physical_location * loc)

   Set the primary location of ``diag``.

   ``diag`` must be non-NULL; ``loc`` can be NULL.

.. function:: void diagnostic_set_location_with_label (diagnostic *diag, \
                                                       const diagnostic_physical_location *loc, \
                                                       const char *fmt, ...)

   Set the primary location of ``diag``, with a label.  The label is
   formatted as per the rules FIXME

   ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL.

   See :doc:`message-formatting` for details of how to use ``fmt``.

   TODO: example of use

.. function:: void diagnostic_add_location (diagnostic *diag, \
                                            const diagnostic_physical_location * loc)

   Add a secondary location to ``diag``.

   ``diag`` must be non-NULL; ``loc`` can be NULL.


.. function:: void diagnostic_add_location_with_label (diagnostic *diag, \
                                                       const diagnostic_physical_location *loc, \
                                                       const char *text)

   Add a secondary location to ``diag``, with a label.  The label is
   formatted as per the rules FIXME

   ``diag`` and ``fmt`` must be non-NULL; ``loc`` can be NULL.

   For example,

      .. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-labelled-ranges.c
	 :language: c
	 :start-after: /* begin quoted source */
	 :end-before:  /* end quoted source */

   might give this text output::

      test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *'
         19 |   42 + "foo"
            |   ~~ ^ ~~~~~
            |   |    |
            |   int  const char *

.. function:: void diagnostic_add_location_with_label_via_msg_buf (diagnostic *diag, \
						const diagnostic_physical_location *loc, \
						diagnostic_message_buffer *msg_buf)

   This is equivalent to :func:`diagnostic_add_location_with_label` but
   using a message buffer rather than a text string.

   ``diag`` and ``msg_buf`` must both be non-NULL.

   Calling this function transfers ownership of ``msg_buf`` to the
   diagnostic - do not call :func:`diagnostic_message_buffer_release` on
   it.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_3`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_message_buffer

.. function:: void diagnostic_manager_set_debug_physical_locations (diagnostic_manager *mgr, \
						 int value)

   Calling ``diagnostic_manager_set_debug_physical_locations (mgr, 1);``
   will lead to debugging information being printed to ``stderr`` when
   creating :type:`diagnostic_physical_location` instances.

   The precise format of these messages is subject to change.

   This function was added in :ref:`LIBGDIAGNOSTICS_ABI_5`; you can
   test for its presence using

   .. code-block:: c

      #ifdef LIBDIAGNOSTICS_HAVE_diagnostic_manager_set_debug_physical_locations

---

### Gcc Doc Libgdiagnostics Topics Retrofitting (`gcc/doc/libgdiagnostics/topics/retrofitting.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Adding libgdiagnostics to an existing project
=============================================

TODO

---

### Gcc Doc Libgdiagnostics Topics Sarif (`gcc/doc/libgdiagnostics/topics/sarif.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

SARIF support
=============

`SARIF <https://sarif.info>`_ is a machine-readable format, originally
designed for the output of static analysis tools, but which can be used
for diagnostics in general.

.. function:: void diagnostic_manager_add_sarif_sink (diagnostic_manager *diag_mgr, \
                                                      FILE *dst_stream, \
                                                      const diagnostic_file *main_input_file, \
                                                      enum diagnostic_sarif_version version)

   Add a new output sink to ``diag_mgr``, which writes SARIF of the given
   version to ``dst_stream``.

   The output is not written until ``diag_mgr`` is released.

   ``dst_stream`` is borrowed, and must outlive ``diag_mgr``.

   For the result to be a valid SARIF file according to the schema,
   ``diag_mgr`` must have had :func:`diagnostic_manager_set_tool_name`
   called on it.

   ``diag_mgr``, ``dst_stream``, and ``main_input_file`` must all be non-NULL.

  .. enum:: diagnostic_sarif_version

     An enum for choosing the SARIF version for a SARIF output sink.

     .. macro:: DIAGNOSTIC_SARIF_VERSION_2_1_0

     .. macro:: DIAGNOSTIC_SARIF_VERSION_2_2_PRERELEASE

---

### Gcc Doc Libgdiagnostics Topics Text Output (`gcc/doc/libgdiagnostics/topics/text-output.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Text output
===========

.. type:: diagnostic_text_sink

.. function:: diagnostic_text_sink * diagnostic_manager_add_text_sink (diagnostic_manager *diag_mgr,\
                                                                       FILE *dst_stream, \
                                                                       enum diagnostic_colorize colorize)

   Add a new output sink to ``diag_mgr``, which writes GCC-style diagnostics
   to ``dst_stream``.
   Return a borrowed pointer to the sink, which is cleaned up when ``diag_mgr``
   is released.

   ``diag_mgr`` must be non-NULL.

   ``dst_stream`` must be non-NULL.  It is borrowed and must outlive ``DIAG_MGR``.

   The output for each diagnostic is written and flushed as each
   :type:`diagnostic` is finished.

   .. enum:: diagnostic_colorize

      An enum for determining if we should colorize a text output sink.

      .. macro:: DIAGNOSTIC_COLORIZE_IF_TTY

	 Diagnostics should be colorized if the destination stream is
	 directly connected to a tty.

      .. macro:: DIAGNOSTIC_COLORIZE_NO

	 Diagnostics should not be colorized.

      .. macro:: DIAGNOSTIC_COLORIZE_YES

	 Diagnostics should be colorized.

.. function:: void diagnostic_text_sink_set_source_printing_enabled (diagnostic_text_sink *text_sink, \
                                                                     int value)

   Enable or disable printing of source text in the text sink.

   ``text_sink`` must be non-NULL.

   Default: enabled.

.. function:: void diagnostic_text_sink_set_colorize (diagnostic_text_sink *text_sink, \
                                                      enum diagnostic_colorize colorize)

   Update colorization of text sink.

   ``text_sink`` must be non-NULL.

.. function:: void diagnostic_text_sink_set_labelled_source_colorization_enabled (diagnostic_text_sink *text_sink, \
                                                                                  int value)

   ``text_sink`` must be non-NULL.

   Enable or disable colorization of the characters of source text
   that are underlined.

   This should be true for clients that generate range information
   (so that the ranges of code are colorized), and false for clients that
   merely specify points within the source code (to avoid e.g. colorizing
   just the first character in a token, which would look strange).

   Default: enabled.

---

### Gcc Doc Libgdiagnostics Topics Ux (`gcc/doc/libgdiagnostics/topics/ux.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

User Experience
===============

Refer to
`GCC's user experience guidelines <https://gcc.gnu.org/onlinedocs/gccint/User-Experience-Guidelines.html>`_
for notes on
`what makes a good diagnostic <https://gcc.gnu.org/onlinedocs/gccint/Guidelines-for-Diagnostics.html>`_.

---

### Gcc Doc Libgdiagnostics Tutorial 01 Hello World (`gcc/doc/libgdiagnostics/tutorial/01-hello-world.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 1: "Hello world"
==============================

Before we look at the details of the API, let's look at building and
running programs that use the library.

Here's a toy program that uses libgdiagnostics to emit an error message
to stderr.

  .. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-example-1.c
     :language: c
     :start-after: /* begin quoted source */
     :end-before:  /* end quoted source */

Copy the above to `tut01-hello-world.c`.

Assuming you have libgdiagnostics installed, build the test program
using:

.. code-block:: console

  $ gcc \
      tut01-hello-world.c \
      -o tut01-hello-world \
      -lgdiagnostics

You should then be able to run the built program:

.. code-block:: console

  $ ./tut01-hello-world
  progname: error: I'm sorry Dave, I'm afraid I can't do that

If stderr is connected to a terminal, you should get colorized output
(using `SGR control codes <https://en.wikipedia.org/wiki/ANSI_escape_code>`_).

.. image:: example-1.png

Otherwise, the output will be plain text.

Obviously a trivial example like the above could be done using ``fprintf``
on stderr, and it's fairly easy to colorize text at the terminal.

In :doc:`the next part of the tutorial <02-physical-locations>` we'll add
file/location information to our error messages, and libgdiagnostics will
quote the pertinent parts of the file, underlining them, which is less trivial
to reimplement.  libgdiagnostics gives us many other such abilities, such as
fix-it hints and execution paths, which we'll cover in the following
tutorials.  Also, once a program's diagnostics are using libgdiagnostics,
it is trivial to add support for outputting them in
machine-readable form as :doc:`SARIF <../topics/sarif>`.


Structure
*********

The above example shows the typical structure of a program using
libgdiagnostics:

* **initialization**: create a :type:`diagnostic_manager` instance,
  and create an output sink for it, and other one-time initialization

* **emission**: create various :type:`diagnostic` instances, populating
  them with data, and calling "finish" once they're ready to be emitted.
  :doc:`Text sinks <../topics/text-output>` emit their diagnostics as soon
  as "finish" is called on them.

* **cleanup**: call :func:`diagnostic_manager_release` on the
  :type:`diagnostic_manager` to finish and free up resources.
  :doc:`SARIF sinks <../topics/sarif>` write their output when
  :func:`diagnostic_manager_release` is called on the manager.

For non-trivial examples we'll also want to create location information,
which could happen during initialization, or during a parsing phase of
the program using libgdiagnostics.  See :doc:`02-physical-locations` for
more information.


Formatted messages
******************

The above example uses :func:`diagnostic_finish`, which takes a format
string and arguments.  libgdiagnostics has its own style of format
string arguments used for :func:`diagnostic_finish` and some other
entrypoints.

.. note:: The format syntax is *not* the same as ``printf``; see
   :doc:`supported formatting options <../topics/message-formatting>`.

You can use the ``q`` modifier on arguments
to quote them, so, for example ``%qs`` is a quoted string, consuming a
``const char *`` argument::

   diagnostic_finish (d, "can't find %qs", "foo");

This gives output like this:

.. code-block:: console

  progname: error: can't find ‘foo’

where the quoted string will appear in bold in a suitably-capable
terminal, and the quotes will be internationalized, so that e.g. with
``LANG=fr_FR.UTF8`` we might get:

.. code-block:: console

  progname: erreur: can't find « foo »

Note that:

* the string ``error`` has been localized by libgdiagnostics to
  ``erreur``,

* locale-specific quoting has been used (``«`` and ``»`` rather than
  ``‘`` and ``’``),

* ``foo`` hasn't been localized - you would typically use quoted strings
  for referring to identifiers in the input language (such as function names
  in code, property names in JSON, etc),

* the message itself hasn't been localized: you are responsible for
  passing a translated format string to :func:`diagnostic_finish` if you
  want to internationalize the output.

There are many :doc:`supported formatting options <../topics/message-formatting>`.


Naming the program
******************

In the above output the message was preceded with ``progname``.  This
appears for diagnostics that don't have any location information associated
with them.  We'll look at setting up location information in the
:doc:`next tutorial <02-physical-locations>`, but we can override this
default name via :func:`diagnostic_manager_set_tool_name`::

   diagnostic_manager_set_tool_name (diag_mgr, "my-awesome-checker");

leading to output like this::

   my-awesome-checker: error: can't find ‘foo’

There are various other functions for
:doc:`supplying metadata to libgdiagnostics <../../topics/metadata>`.


Moving beyond trivial examples
******************************

Obviously it's not very useful if we can't refer to specific files and
specific locations in those files in our diagnostics, so read
:doc:`part 2 of the tutorial <02-physical-locations>` for information on
how to do this.

---

### Gcc Doc Libgdiagnostics Tutorial 02 Physical Locations (`gcc/doc/libgdiagnostics/tutorial/02-physical-locations.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 2: physical locations
===================================

libgdiagnostics has two kinds of location:

* *physical locations* expressed in terms of a specific file, and line(s)
  and perhaps column(s), such as ``some-file.c:3:1``, or a range of
  columns, such as in::

    test-typo.c:19:13: error: unknown field 'colour'
       19 |   return p->colour;
          |             ^~~~~~

  or even a range spanning multiple lines of a file.

  All of these are instances of :type:`diagnostic_physical_location`.

* *logical locations* which refers to semantic constructs
  in the input, such as ``within function 'foo'``, or within
  namespace ``foo``'s class ``bar``'s member function ``get_color``.

  These are instances of :type:`diagnostic_logical_location`,

A :type:`diagnostic` can have zero or more physical locations,
and optionally have a logical location.

Let's extend the previous example to add a physical location to the
:type:`diagnostic`; we'll cover logical locations in the
:doc:`next section <03-logical-locations>`.


Source files
************

Given these declarations::

  static diagnostic_manager *diag_mgr;
  static diagnostic_file *main_file;

we can create a :type:`diagnostic_file` describing an input file ``foo.c``
via :func:`diagnostic_manager_new_file`::

     foo_c = diagnostic_manager_new_file (diag_mgr,
                                          "foo.c",
                                          "c" /* source_language */);

You can use :func:`diagnostic_manager_debug_dump_file` to print a
representation of a :type:`diagnostic_file` for debugging.
For example::

   diagnostic_manager_debug_dump_file (diag_mgr, foo_c, stderr);

might lead to this output on ``stderr``::

   file(name="foo.c", sarif_source_language="c")

Once we have a :type:`diagnostic_file` we can use it to create instances
of :type:`diagnostic_physical_location` within the :type:`diagnostic_manager`.
These are owned by the :type:`diagnostic_manager` and cleaned up
automatically when :func:`diagnostic_manager_release` is called.

Instances of :type:`diagnostic_physical_location` can refer to

* a source line as a whole, created via
  :func:`diagnostic_manager_new_location_from_file_and_line`.

* a particular point within a source file (line/column), created via
  :func:`diagnostic_manager_new_location_from_file_line_column`.

* a range of text within of source file, created via
  :func:`diagnostic_manager_new_location_from_range`.


Diagnostics affecting a whole source line
*****************************************

If we want a diagnostic to refer to an entire source line,
we can use :func:`diagnostic_manager_new_location_from_file_and_line`.

For example, given this example input where the tool can't find the header::

   #include <foo.h>

we could complain about it via libgdiagnostics via:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-no-column.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

leading to output like this::

   foo.c:17: error: can't find 'foo.h'"
      17 | #include <foo.h>

where libgdiagnostics will attempt to load ``foo.c`` and
quote the pertinent line.

If libgdiagnostics cannot open ``foo.c``, it will merely print::

   foo.c:17: error: can't find 'foo.h'

You can use :func:`diagnostic_manager_debug_dump_location` to dump a
:type:`diagnostic_physical_location`.  For the above example::

   diagnostic_manager_debug_dump_location (diag_mgr, loc, stderr);

might print::

   foo.c:17

to stderr.


Columns and ranges
******************

If we want to generate output like this::

   foo.c:17:11: error: can't find 'foo'"
      17 | #include <foo.h>
         |           ^~~~~

where the diagnostic is marked as relating to the above range of
characters in line 17, we need to express the range of characters
within the line of interest.

We can do this by creating a :type:`diagnostic_physical_location` for the
start of the range, another one for the end of the range, and then using
these two to create a :type:`diagnostic_physical_location` for the
range as a whole:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-error.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

On compiling and running the program, we should get this output::

   foo.c:17:11: error: can't find 'foo.h'
      17 | #include <foo.h>
         |           ^~~~~

where libgdiagnostics will attempt to load ``foo.c`` and
underling the pertinent part of the given line.

If libgdiagnostics cannot open ``foo.c``, it will merely print::

   foo.c:17:8: error: can't find 'foo.h'

A range can span multiple lines within the same file, but cannot
span multiple files.

As before, you can use :func:`diagnostic_manager_debug_dump_location` to
dump the locations.  For the above example::

   diagnostic_manager_debug_dump_location (diag_mgr, loc_start, stderr);

and::

   diagnostic_manager_debug_dump_location (diag_mgr, loc_range, stderr);

might print::

   foo.c:17:11

to stderr, whereas::

   diagnostic_manager_debug_dump_location (diag_mgr, loc_end, stderr);

might print::

   foo.c:17:15


Multiple locations
******************

As well as the primary physical location seen above, a :type:`diagnostic`
can have additional physical locations.  You can add these secondary
locations via :func:`diagnostic_add_location`.

For example, for this valid but suspicious-looking C code::

   const char *strs[3] = {"foo",
                          "bar"
                          "baz"};

the following :type:`diagnostic` has its primary location where the missing
comma should be, and secondary locations for each of the string literals
``"foo"``, ``"bar"``, and ``"baz"``, added via :func:`diagnostic_add_location`:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-multiple-lines.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

where the text output might be::

   test-multiple-lines.c:23:29: warning: missing comma
      22 | const char *strs[3] = {"foo",
         |                        ~~~~~
      23 |                        "bar"
         |                        ~~~~~^
      24 |                        "baz"};
         |                        ~~~~~


Labelling locations
*******************

You can give the locations labels using
:func:`diagnostic_set_location_with_label` and
:func:`diagnostic_add_location_with_label`.

Consider emitting a "type mismatch" diagnostic for::

  42 + "foo"

where the primary location is on the ``+``, with secondary locations on the``42``
and the ``"foo"``:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-labelled-ranges.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

giving this text output::

   test-labelled-ranges.c:9:6: error: mismatching types: 'int' and 'const char *'
      19 |   42 + "foo"
         |   ~~ ^ ~~~~~
         |   |    |
         |   int  const char *


More on locations
*****************

For more details on the above, see :doc:`../topics/physical-locations`.
Otherwise the :doc:`next part of the tutorial <03-logical-locations>`
covers logical locations.

---

### Gcc Doc Libgdiagnostics Tutorial 03 Logical Locations (`gcc/doc/libgdiagnostics/tutorial/03-logical-locations.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 3: logical locations
==================================

Let's extend the previous example to add a
:doc:`logical location <../topics/logical-locations>` to the
:type:`diagnostic`.

First we create a :type:`diagnostic_logical_location` representing a
particular function::

  const diagnostic_logical_location *logical_loc
    = diagnostic_manager_new_logical_location (diag_mgr,
					       DIAGNOSTIC_LOGICAL_LOCATION_KIND_FUNCTION,
					       NULL, /* parent */
					       "foo",
					       NULL,
					       NULL);

In this simple example we specify that it is a function, and just give
it a name (``foo``).  For more complicated cases we can set up tree-like
hierarchies of logical locations, set qualified names, "mangled" names,
and so on; see :func:`diagnostic_manager_new_logical_location` for details.
    
Once we have :type:`diagnostic_logical_location` we can associate it with
a :type:`diagnostic` with :func:`diagnostic_set_logical_location`::
      
  diagnostic_set_logical_location (d, logical_loc);

The logical location will be printed by text output sinks like this::

  In function 'foo':

and will be captured in :doc:`SARIF <../topics/sarif>` output.


Find out more
*************

For more details on the above, see :doc:`../topics/logical-locations`.
Otherwise the :doc:`next part of the tutorial <04-notes>` covers adding
supplementary "notes" to a :type:`diagnostic`.

---

### Gcc Doc Libgdiagnostics Tutorial 04 Notes (`gcc/doc/libgdiagnostics/tutorial/04-notes.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 4: adding notes
=============================

Let's further extend the previous example to add a "note" to it.

We want to generate output like this::

   test-with-note.c:17:11: error: can't find 'foo.h'
   17 | #include <foo.h>
      |           ^~~~~
   test-with-note.c:17:11: note: have you looked behind the couch?

The "error" and "note" are both instances of :type:`diagnostic`.
We want to let libgdiagnostics know that they are grouped together.
The way to do this is to use :func:`diagnostic_manager_begin_group`
and :func:`diagnostic_manager_end_group` around the "finish" calls
to the diagnostics.

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-error-with-note.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

On compiling and running the program, we should get the desired output::

   test-with-note.c:17:11: error: can't find 'foo.h'
   17 | #include <foo.h>
      |           ^~~~~
   test-with-note.c:17:11: note: have you looked behind the couch?

The grouping doesn't affect text output sinks, but a
:doc:`SARIF sink <../topics/sarif>` will group the note within the error
(via the ``relatedLocations`` property of ``result`` objects; see SARIF v2.1.0
`§3.27.22 <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790910>`_).

In the above, the note had the same physical location as the error
(``loc_range``).  This can be useful for splitting up a message into two
parts to make localization easier, but they could have different locations, such
as in::

  test.xml:10:2: error: 'foo' is not valid here
  test.xml:5:1: note: within element 'bar'

where each :type:`diagnostic` had its own :type:`diagnostic_physical_location`.

In :doc:`the next tutorial <05-warnings>` we'll look at issuing warnings,
rather than errors.

---

### Gcc Doc Libgdiagnostics Tutorial 05 Warnings (`gcc/doc/libgdiagnostics/tutorial/05-warnings.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 5: warnings
=========================

So far we've only emitted errors, but other kinds of diagnostic are possible,
such as warnings.

We can select different kinds of diagnostic via :enum:`diagnostic_level`
when calling :func:`diagnostic_begin`:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

On compiling and running the program, we should get output similar to::

   test-warning.c:17:11: warning: this is a warning
   17 | #include <foo.h>
      |           ^~~~~

Various severities are possible, see  :enum:`diagnostic_level` for more
information.

In :doc:`the next section of the tutorial <06-fix-it-hints>` we'll look
at adding fix-it hints to diagnostics.

---

### Gcc Doc Libgdiagnostics Tutorial 06 Fix It Hints (`gcc/doc/libgdiagnostics/tutorial/06-fix-it-hints.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 6: fix-it hints
=============================

libgdiagnostics supports adding "fix-it hints" to a :type:`diagnostic`:
suggestions for the user on how to edit their code to fix a problem.  These
can be expressed as insertions, replacements, and removals of text.

For example, here we use :func:`diagnostic_add_fix_it_hint_replace` to add
a replacement fix-it hint to a diagnostic:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-fix-it-hint.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

On compiling and running the program, we should get output similar to::

   test-fix-it-hint.c:19:13: error: unknown field 'colour'; did you mean 'color'
      19 |   return p->colour;
         |             ^~~~~~
         |             color

We can also add a call to :func:`diagnostic_manager_write_patch` to the
program cleanup code::

  diagnostic_manager_write_patch (diag_mgr, stderr);

This will write a patch to the stream (here ``stderr``) giving the effect
of all fix-it hints on all diagnostics emitted by the
:type:`diagnostic_manager`, giving something like::

   @@ -16,7 +16,7 @@
    struct rgb
    get_color (struct object *p)
    {
   -  return p->colour;
   +  return p->color;
    }
    

See the :doc:`guide to fix-it hints <../topics/fix-it-hints>`
for more information, or go on to
:doc:`the next section of the tutorial <07-execution-paths>`.

---

### Gcc Doc Libgdiagnostics Tutorial 07 Execution Paths (`gcc/doc/libgdiagnostics/tutorial/07-execution-paths.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 7: execution paths
================================

A :type:`diagnostic` can optionally have a :type:`diagnostic_execution_path`
describing a path of execution through code.

For example, let's pretend we're writing a static analysis tool for finding
bugs in `CPython extension code <https://docs.python.org/3/c-api/index.html>`_.

Let's say we're analyzing this code:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin fake source
   :end-before:  end fake source

This code attempts to take an Python integer parameter and then build a
list of that length, containing random integers.  However, there are
**numerous bugs** in this code: a type mismatch, mistakes in
reference-counting, and an almost total lack of error-handling.

For example, ``PyList_Append`` requires a non-NULL first parameter (``list``),
but ``PyList_New`` can fail, returning NULL, and this isn't checked for,
which would lead to a segfault if ``PyList_New`` fails.

We can add a :type:`diagnostic_execution_path` to the :type:`diagnostic`
via :func:`diagnostic_add_execution_path`, and then add events to it
using :func:`diagnostic_execution_path_add_event`.

For example, with::

  diagnostic_event_id alloc_event_id
    = diagnostic_execution_path_add_event (path,
					   loc_call_to_PyList_New,
					   logical_loc, 0,
					   "when %qs fails, returning NULL",
					   "PyList_New");

we create an event that will be worded as::

  (1) when `PyList_New' fails, returning NULL

Note that :func:`diagnostic_execution_path_add_event` returns a
:type:`diagnostic_event_id`.  We can use this to refer to this event
in another event using the ``%@`` format code in its message, which
takes the address of a :type:`diagnostic_event_id`::

  diagnostic_execution_path_add_event (path,
				       loc_call_to_PyList_Append,
				       logical_loc, 0,
				       "when calling %qs, passing NULL from %@ as argument %i",
				       "PyList_Append", &alloc_event_id, 1);

where the latter event will be worded as::

  (2) when calling `PyList_Append', passing NULL from (1) as argument 1

where the ``%@`` reference to the other event has been printed as ``(1)``.
In SARIF output the text "(1)" will have a embedded link referring within the sarif
log to the ``threadFlowLocation`` object for the other event, via JSON
pointer (see `§3.10.3 "URIs that use the sarif scheme" <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790707>`_).

Let's add an event between these describing control flow, creating three
events in all:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin path creation
   :end-before:  end path creation

Assuming we also gave it :type:`diagnostic_logical_location` with:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin create logical locs
   :end-before:  end create logical locs

and finish the :type:`diagnostic` with :func:`diagnostic_finish` like this::

  diagnostic_finish (d,
		     "passing NULL as argument %i to %qs"
		     " which requires a non-NULL parameter",
		     1, "PyList_Append");

then we should get output to text sinks similar to the following::

   In function 'make_a_list_of_random_ints_badly':
   test-warning-with-path.c:30:5: warning: passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter"
      30 |     PyList_Append(list, item);
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   make_a_list_of_random_ints_badly': events 1-3
      26 |   list = PyList_New(0);
         |          ^~~~~~~~~~~~~
         |          |
         |          (1) when 'PyList_New' fails, returning NULL
      27 | 
      28 |   for (i = 0; i < count; i++) {
         |               ~~~~~~~~~
         |               |
         |               (2) when 'i < count'
      29 |     item = PyLong_FromLong(random());
      30 |     PyList_Append(list, item);
         |     ~~~~~~~~~~~~~~~~~~~~~~~~~
         |     |
         |     (3) when calling 'PyList_Append', passing NULL from (1) as argument 1

and for SARIF sinks the path will be added as a ``codeFlow`` object
(see SARIF 2.1.0 `§3.36 codeFlow object <https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790990>`_).

Here's the above example in full:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-warning-with-path.c
   :language: c
   :start-after: begin full example
   :end-before:  end full example


See the :doc:`guide to execution paths <../topics/execution-paths>`
for more information, or go on to
:doc:`the next section of the tutorial <08-message-buffers>`.

---

### Gcc Doc Libgdiagnostics Tutorial 08 Message Buffers (`gcc/doc/libgdiagnostics/tutorial/08-message-buffers.rst`)

.. Copyright (C) 2025-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 8: message buffers
================================

In previous examples, we finished a diagnostic with a call to
:func:`diagnostic_finish`, which takes a format string and arguments
to determine the text message of the diagnostic.

Sometimes this approach is inconvenient, such as where you might want to
build up a message programmatically from a series of components.
Additionally, you might have existing code that uses ``fprintf``, whereas
:func:`diagnostic_finish` has its
:doc:`own formatting conventions <../topics/message-formatting>` which are
:strong:`not` the same as printf.

For this reason libgdiagnostics (from ``LIBGDIAGNOSTICS_ABI_3`` onwards)
supports :type:`diagnostic_message_buffer`, which can be used to accumulate a
message before using it.

You create a :type:`diagnostic_message_buffer` using
:func:`diagnostic_message_buffer_new`.

There are various API entrypoints for accumulating text into the buffer.

For example:

.. literalinclude:: ../../../testsuite/libgdiagnostics.dg/test-message-buffer.c
   :language: c
   :start-after: /* begin quoted source */
   :end-before:  /* end quoted source */

Running this will produce this text output::

.. code-block:: console

  $ ./test-message-buffer.c.exe
  ./test-message-buffer.c.exe: error: this is a string; foo; int: 42 str: mostly harmless; this is a link  'this is quoted' highlight A highlight B (1).

where in a suitably-capable terminal if a text sink is directly
connected to a tty:

* the ``this is a link`` will be a clickable hyperlink
  (and the URL will be captured in SARIF output).

* the quoted text will be in bold

* the ``highlight A`` and ``highlight B`` text will be colorized

* the event ID will be colorized (and will be a URL in SARIF output
  if used within a :type:`diagnostic_execution_path`).


Moving on
*********

That's the end of the tutorial.  For more information on libgdiagnostics, see
the :doc:`topic guide <../topics/index>`.

---

### Gcc Doc Libgdiagnostics Tutorial Index (`gcc/doc/libgdiagnostics/tutorial/index.rst`)

.. Copyright (C) 2024-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial
========

The following tutorial gives an overview of how to use libgdiagnostics.

.. toctree::
   :maxdepth: 2

   01-hello-world.rst
   02-physical-locations.rst
   03-logical-locations.rst
   04-notes.rst
   05-warnings.rst
   06-fix-it-hints.rst
   07-execution-paths.rst
   08-message-buffers.rst

---

### Gcc Jit Docs Cp Index (`gcc/jit/docs/cp/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

C++ bindings for libgccjit
==========================

This document describes the C++ bindings to
`libgccjit <https://gcc.gnu.org/wiki/JIT>`_, an API for embedding GCC
inside programs and libraries.

The C++ bindings consist of a single header file ``libgccjit++.h``.

This is a collection of "thin" wrapper classes around the C API.
Everything is an inline function, implemented in terms of the C API,
so there is nothing extra to link against.

Contents:

.. toctree::
   :maxdepth: 2

   intro/index.rst
   topics/index.rst

---

### Gcc Jit Docs Internals Index (`gcc/jit/docs/internals/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Internals
=========

Working on the JIT library
--------------------------
Having checked out the source code (to "src"), you can configure and build
the JIT library like this:

.. code-block:: bash

  mkdir build
  mkdir install
  PREFIX=$(pwd)/install
  cd build
  ../src/configure \
     --enable-host-shared \
     --enable-languages=jit,c++ \
     --disable-bootstrap \
     --enable-checking=release \
     --prefix=$PREFIX
  nice make -j4 # altering the "4" to however many cores you have

This should build a libgccjit.so within jit/build/gcc:

.. code-block:: console

 [build] $ file gcc/libgccjit.so*
 gcc/libgccjit.so:       symbolic link to `libgccjit.so.0'
 gcc/libgccjit.so.0:     symbolic link to `libgccjit.so.0.0.1'
 gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

Here's what those configuration options mean:

.. option:: --enable-host-shared

  Configuring with this option means that the compiler is built as
  position-independent code, which incurs a slight performance hit,
  but it necessary for a shared library.

.. option:: --enable-languages=jit,c++

  This specifies which frontends to build.  The JIT library looks like
  a frontend to the rest of the code.

  The C++ portion of the JIT test suite requires the C++ frontend to be
  enabled at configure-time, or you may see errors like this when
  running the test suite:

  .. code-block:: console

    xgcc: error: /home/david/jit/src/gcc/testsuite/jit.dg/test-quadratic.cc: C++ compiler not installed on this system
    c++: error trying to exec 'cc1plus': execvp: No such file or directory

.. option:: --disable-bootstrap

  For hacking on the "jit" subdirectory, performing a full
  bootstrap can be overkill, since it's unused by a bootstrap.  However,
  when submitting patches, you should remove this option, to ensure that
  the compiler can still bootstrap itself.

.. option:: --enable-checking=release

  The compile can perform extensive self-checking as it runs, useful when
  debugging, but slowing things down.

  For maximum speed, configure with ``--enable-checking=release`` to
  disable this self-checking.

Running the test suite
----------------------

.. code-block:: console

  [build] $ cd gcc
  [gcc] $ make check-jit RUNTESTFLAGS="-v -v -v"

A summary of the tests can then be seen in:

.. code-block:: console

  jit/build/gcc/testsuite/jit/jit.sum

and detailed logs in:

.. code-block:: console

  jit/build/gcc/testsuite/jit/jit.log

The test executables are normally deleted after each test is run.  For
debugging, they can be preserved by setting :envvar:`PRESERVE_EXECUTABLES`
in the environment.  If so, they can then be seen as:

.. code-block:: console

  jit/build/gcc/testsuite/jit/*.exe

which can be run independently.

You can compile and run individual tests by passing "jit.exp=TESTNAME" to RUNTESTFLAGS e.g.:

.. code-block:: console

   [gcc] $ PRESERVE_EXECUTABLES= \
             make check-jit \
               RUNTESTFLAGS="-v -v -v jit.exp=test-factorial.c"

and once a test has been compiled, you can debug it directly:

.. code-block:: console

   [gcc] $ PATH=.:$PATH \
           LD_LIBRARY_PATH=. \
           LIBRARY_PATH=. \
             gdb --args \
               testsuite/jit/test-factorial.c.exe

Running under valgrind
**********************

The jit testsuite detects if :envvar:`RUN_UNDER_VALGRIND` is present in the
environment (with any value).  If it is present, it runs the test client
code under `valgrind <https://valgrind.org>`_,
specifically, the default
`memcheck <https://valgrind.org/docs/manual/mc-manual.html>`_
tool with
`--leak-check=full
<https://valgrind.org/docs/manual/mc-manual.html#opt.leak-check>`_.

It automatically parses the output from valgrind, injecting XFAIL results if
any issues are found, or PASS results if the output is clean.  The output
is saved to ``TESTNAME.exe.valgrind.txt``.

For example, the following invocation verbosely runs the testcase
``test-sum-of-squares.c`` under valgrind, showing an issue:

.. code-block:: console

  $ RUN_UNDER_VALGRIND= \
      make check-jit \
        RUNTESTFLAGS="-v -v -v jit.exp=test-sum-of-squares.c"

  (...verbose log contains detailed valgrind errors, if any...)

                  === jit Summary ===

  # of expected passes            28
  # of expected failures          2

  $ less testsuite/jit/jit.sum
  (...other results...)
  XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: definitely lost: 8 bytes in 1 blocks
  XFAIL: jit.dg/test-sum-of-squares.c: test-sum-of-squares.c.exe.valgrind.txt: unsuppressed errors: 1
  (...other results...)

  $ less testsuite/jit/test-sum-of-squares.c.exe.valgrind.txt
  (...shows full valgrind report for this test case...)

When running under valgrind, it's best to have configured gcc with
:option:`--enable-valgrind-annotations`, which automatically suppresses
various known false positives.

Environment variables
---------------------
When running client code against a locally-built libgccjit, three
environment variables need to be set up:

.. envvar:: LD_LIBRARY_PATH

   `libgccjit.so` is dynamically linked into client code, so if running
   against a locally-built library, ``LD_LIBRARY_PATH`` needs to be set
   up appropriately.  The library can be found within the "gcc"
   subdirectory of the build tree:

  .. code-block:: console

    $ file libgccjit.so*
    libgccjit.so:       symbolic link to `libgccjit.so.0'
    libgccjit.so.0:     symbolic link to `libgccjit.so.0.0.1'
    libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, not stripped

.. envvar:: PATH

  The library uses a driver executable for converting from .s assembler
  files to .so shared libraries.  Specifically, it looks for a name
  expanded from
  ``${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}``
  such as ``x86_64-unknown-linux-gnu-gcc-5.0.0``.

  Hence ``PATH`` needs to include a directory where the library can
  locate this executable.

  The executable is normally installed to the installation bindir
  (e.g. /usr/bin), but a copy is also created within the "gcc"
  subdirectory of the build tree for running the testsuite, and for ease
  of development.

.. envvar:: LIBRARY_PATH

  The driver executable invokes the linker, and the latter needs to locate
  support libraries needed by the generated code, or you will see errors
  like:

  .. code-block:: console

    ld: cannot find crtbeginS.o: No such file or directory
    ld: cannot find -lgcc
    ld: cannot find -lgcc_s

  Hence if running directly from a locally-built copy (without installing),
  ``LIBRARY_PATH`` needs to contain the "gcc" subdirectory of the build
  tree.

For example, to run a binary that uses the library against a non-installed
build of the library in LIBGCCJIT_BUILD_DIR you need an invocation of the
client code like this, to prepend the dir to each of the environment
variables:

.. code-block:: console

  $ LD_LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LD_LIBRARY_PATH) \
    PATH=$(LIBGCCJIT_BUILD_DIR):$(PATH) \
    LIBRARY_PATH=$(LIBGCCJIT_BUILD_DIR):$(LIBRARY_PATH) \
      ./jit-hello-world
  hello world

Packaging notes
---------------
The configure-time option :option:`--enable-host-shared` is needed when
building the jit in order to get position-independent code.  This will
slow down the regular compiler by a few percent.  Hence when packaging gcc
with libgccjit, please configure and build twice:

  * once without :option:`--enable-host-shared` for most languages, and

  * once with :option:`--enable-host-shared` for the jit

For example:

.. code-block:: bash

  # Configure and build with --enable-host-shared
  # for the jit:
  mkdir configuration-for-jit
  pushd configuration-for-jit
  $(SRCDIR)/configure \
    --enable-host-shared \
    --enable-languages=jit \
    --prefix=$(DESTDIR)
  make
  popd

  # Configure and build *without* --enable-host-shared
  # for maximum speed:
  mkdir standard-configuration
  pushd standard-configuration
  $(SRCDIR)/configure \
    --enable-languages=all \
    --prefix=$(DESTDIR)
  make
  popd

  # Both of the above are configured to install to $(DESTDIR)
  # Install the configuration with --enable-host-shared first
  # *then* the one without, so that the faster build
  # of "cc1" et al overwrites the slower build.
  pushd configuration-for-jit
  make install
  popd

  pushd standard-configuration
  make install
  popd

Overview of code structure
--------------------------

The library is implemented in C++.

* ``libgccjit.cc`` implements the API entrypoints.  It performs error
  checking, then calls into classes of the gcc::jit::recording namespace
  within ``jit-recording.cc`` and ``jit-recording.h``.

* The gcc::jit::recording classes (within ``jit-recording.cc`` and
  ``jit-recording.h``) record the API calls that are made:

   .. literalinclude:: ../../jit-common.h
    :start-after: /* Recording types.  */
    :end-before: /* End of recording types. */
    :language: c++

* When the context is compiled, the gcc::jit::playback classes (within
  ``jit-playback.cc`` and ``jit-playback.h``) replay the API calls
  within langhook:parse_file:

   .. literalinclude:: ../../jit-common.h
    :start-after: /* Playback types.  */
    :end-before: /* End of playback types. */
    :language: c++

   .. literalinclude:: ../../notes.txt
    :lines: 1-

Here is a high-level summary from ``jit-common.h``:

.. include:: ../../jit-common.h
  :start-after: This comment is included by the docs.
  :end-before: End of comment for inclusion in the docs.  */

.. _example-of-log-file:

Another way to understand the structure of the code is to enable logging,
via :c:func:`gcc_jit_context_set_logfile`.  Here is an example of a log
generated via this call:

.. literalinclude:: test-hello-world.exe.log.txt
    :lines: 1-

Design notes
------------
It should not be possible for client code to cause an internal compiler
error.  If this *does* happen, the root cause should be isolated (perhaps
using :c:func:`gcc_jit_context_dump_reproducer_to_file`) and the cause
should be rejected via additional checking.  The checking ideally should
be within the libgccjit API entrypoints in libgccjit.cc, since this is as
close as possible to the error; failing that, a good place is within
``recording::context::validate ()`` in jit-recording.cc.

Submitting patches
------------------
Please read the contribution guidelines for gcc at
https://gcc.gnu.org/contribute.html.

Patches for the jit should be sent to both the
gcc-patches@gcc.gnu.org and jit@gcc.gnu.org mailing lists,
with "jit" and "PATCH" in the Subject line.

You don't need to do a full bootstrap for code that just touches the
``jit`` and ``testsuite/jit.dg`` subdirectories.  However, please run
``make check-jit`` before submitting the patch, and mention the results
in your email (along with the host triple that the tests were run on).

A good patch should contain the information listed in the
gcc contribution guide linked to above; for a ``jit`` patch, the patch
should contain:

  * the code itself (for example, a new API entrypoint will typically
    touch ``libgccjit.h`` and ``.c``, along with support code in
    ``jit-recording.[ch]`` and ``jit-playback.[ch]`` as appropriate)

  * test coverage

  * documentation for the C API

  * documentation for the C++ API

A patch that adds new API entrypoints should also contain:

  * a feature macro in ``libgccjit.h`` so that client code that doesn't
    use a "configure" mechanism can still easily detect the presence of
    the entrypoint.  See e.g. ``LIBGCCJIT_HAVE_SWITCH_STATEMENTS`` (for
    a category of entrypoints) and
    ``LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks``
    (for an individual entrypoint).

  * a new ABI tag containing the new symbols (in ``libgccjit.map``), so
    that we can detect client code that uses them

  * Support for :c:func:`gcc_jit_context_dump_reproducer_to_file`.  Most
    jit testcases attempt to dump their contexts to a .c file; ``jit.exp``
    then sanity-checks the generated c by compiling them (though
    not running them).   A new API entrypoint
    needs to "know" how to write itself back out to C (by implementing
    ``gcc::jit::recording::memento::write_reproducer`` for the appropriate
    ``memento`` subclass).

  * C++ bindings for the new entrypoints (see ``libgccjit++.h``); ideally
    with test coverage, though the C++ API test coverage is admittedly
    spotty at the moment

  * documentation for the new C entrypoints

  * documentation for the new C++ entrypoints

  * documentation for the new ABI tag (see ``topics/compatibility.rst``).

Depending on the patch you can either extend an existing test case, or
add a new test case.  If you add an entirely new testcase: ``jit.exp``
expects jit testcases to begin with ``test-``, or ``test-error-`` (for a
testcase that generates an error on a :c:type:`gcc_jit_context`).

Every new testcase that doesn't generate errors should also touch
``gcc/testsuite/jit.dg/all-non-failing-tests.h``:

  * Testcases that don't generate errors should ideally be added to the
    ``testcases`` array in that file; this means that, in addition
    to being run standalone, they also get run within
    ``test-combination.c`` (which runs all successful tests inside one
    big :c:type:`gcc_jit_context`), and ``test-threads.c`` (which runs all
    successful tests in one process, each one running in a different
    thread on a different :c:type:`gcc_jit_context`).

    .. note::

       Given that exported functions within a :c:type:`gcc_jit_context`
       must have unique names, and most testcases are run within
       ``test-combination.c``, this means that every jit-compiled test
       function typically needs a name that's unique across the entire
       test suite.

  * Testcases that aren't to be added to the ``testcases`` array should
    instead add a comment to the file clarifying why they're not in that
    array. See the file for examples.

Typically a patch that touches the .rst documentation will also need the
texinfo to be regenerated.  You can do this with
`Sphinx 1.0 <https://sphinx-doc.org/>`_ or later by
running ``make texinfo`` within ``SRCDIR/gcc/jit/docs``.   Don't do this
within the patch sent to the mailing list; it can often be relatively
large and inconsequential (e.g. anchor renumbering), rather like generated
"configure" changes from configure.ac.  You can regenerate it when
committing to svn.

---

### Gcc Jit Docs Internals Test Hello World.Exe.Log (`gcc/jit/docs/internals/test-hello-world.exe.log.txt`)

JIT: libgccjit (GCC) version 6.0.0 20150803 (experimental) (x86_64-pc-linux-gnu)
JIT:	compiled by GNU C version 4.8.3 20140911 (Red Hat 4.8.3-7), GMP version 5.1.2, MPFR version 3.1.2, MPC version 1.0.1
JIT: entering: gcc_jit_context_set_str_option
JIT:  GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
JIT: exiting: gcc_jit_context_set_str_option
JIT: entering: gcc_jit_context_set_int_option
JIT:  GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
JIT: exiting: gcc_jit_context_set_int_option
JIT: entering: gcc_jit_context_set_bool_option
JIT:  GCC_JIT_BOOL_OPTION_DEBUGINFO: true
JIT: exiting: gcc_jit_context_set_bool_option
JIT: entering: gcc_jit_context_set_bool_option
JIT:  GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
JIT: exiting: gcc_jit_context_set_bool_option
JIT: entering: gcc_jit_context_set_bool_option
JIT:  GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
JIT: exiting: gcc_jit_context_set_bool_option
JIT: entering: gcc_jit_context_set_bool_option
JIT:  GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
JIT: exiting: gcc_jit_context_set_bool_option
JIT: entering: gcc_jit_context_set_bool_option
JIT:  GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
JIT: exiting: gcc_jit_context_set_bool_option
JIT: entering: gcc_jit_context_get_type
JIT: exiting: gcc_jit_context_get_type
JIT: entering: gcc_jit_context_get_type
JIT: exiting: gcc_jit_context_get_type
JIT: entering: gcc_jit_context_new_param
JIT: exiting: gcc_jit_context_new_param
JIT: entering: gcc_jit_context_new_function
JIT: exiting: gcc_jit_context_new_function
JIT: entering: gcc_jit_context_new_param
JIT: exiting: gcc_jit_context_new_param
JIT: entering: gcc_jit_context_get_type
JIT: exiting: gcc_jit_context_get_type
JIT: entering: gcc_jit_context_new_function
JIT: exiting: gcc_jit_context_new_function
JIT: entering: gcc_jit_context_new_string_literal
JIT: exiting: gcc_jit_context_new_string_literal
JIT: entering: gcc_jit_function_new_block
JIT: exiting: gcc_jit_function_new_block
JIT: entering: gcc_jit_block_add_comment
JIT: exiting: gcc_jit_block_add_comment
JIT: entering: gcc_jit_context_new_call
JIT: exiting: gcc_jit_context_new_call
JIT: entering: gcc_jit_block_add_eval
JIT: exiting: gcc_jit_block_add_eval
JIT: entering: gcc_jit_block_end_with_void_return
JIT: exiting: gcc_jit_block_end_with_void_return
JIT: entering: gcc_jit_context_dump_reproducer_to_file
JIT:  entering: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
JIT:  exiting: void gcc::jit::recording::context::dump_reproducer_to_file(const char*)
JIT: exiting: gcc_jit_context_dump_reproducer_to_file
JIT: entering: gcc_jit_context_compile
JIT:  in-memory compile of ctxt: 0x1283e20
JIT:  entering: gcc::jit::result* gcc::jit::recording::context::compile()
JIT:   GCC_JIT_STR_OPTION_PROGNAME: "./test-hello-world.c.exe"
JIT:   GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL: 3
JIT:   GCC_JIT_BOOL_OPTION_DEBUGINFO: true
JIT:   GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE: false
JIT:   GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE: false
JIT:   GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE: false
JIT:   GCC_JIT_BOOL_OPTION_DUMP_SUMMARY: false
JIT:   GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING: false
JIT:   GCC_JIT_BOOL_OPTION_SELFCHECK_GC: true
JIT:   GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES: false
JIT:   gcc_jit_context_set_bool_allow_unreachable_blocks: false
JIT:   gcc_jit_context_set_bool_use_external_driver: false
JIT:   entering: void gcc::jit::recording::context::validate()
JIT:   exiting: void gcc::jit::recording::context::validate()
JIT:   entering: gcc::jit::playback::context::context(gcc::jit::recording::context*)
JIT:   exiting: gcc::jit::playback::context::context(gcc::jit::recording::context*)
JIT:   entering: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
JIT:   exiting: gcc::jit::playback::compile_to_memory::compile_to_memory(gcc::jit::recording::context*)
JIT:   entering: void gcc::jit::playback::context::compile()
JIT:    entering: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
JIT:    exiting: gcc::jit::tempdir::tempdir(gcc::jit::logger*, int)
JIT:    entering: bool gcc::jit::tempdir::create()
JIT:     m_path_template: /tmp/libgccjit-XXXXXX
JIT:     m_path_tempdir: /tmp/libgccjit-CKq1M9
JIT:    exiting: bool gcc::jit::tempdir::create()
JIT:    entering: void gcc::jit::playback::context::acquire_mutex()
JIT:    exiting: void gcc::jit::playback::context::acquire_mutex()
JIT:    entering: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
JIT:     reusing cached configure-time options
JIT:     configure_time_options[0]: -mtune=generic
JIT:     configure_time_options[1]: -march=x86-64
JIT:    exiting: void gcc::jit::playback::context::make_fake_args(vec<char*>*, const char*, vec<gcc::jit::recording::requested_dump>*)
JIT:    entering: toplev::main
JIT:     argv[0]: ./test-hello-world.c.exe
JIT:     argv[1]: /tmp/libgccjit-CKq1M9/fake.c
JIT:     argv[2]: -fPIC
JIT:     argv[3]: -O3
JIT:     argv[4]: -g
JIT:     argv[5]: -quiet
JIT:     argv[6]: --param
JIT:     argv[7]: ggc-min-expand=0
JIT:     argv[8]: --param
JIT:     argv[9]: ggc-min-heapsize=0
JIT:     argv[10]: -mtune=generic
JIT:     argv[11]: -march=x86-64
JIT:     entering: bool jit_langhook_init()
JIT:     exiting: bool jit_langhook_init()
JIT:     entering: void gcc::jit::playback::context::replay()
JIT:      entering: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
JIT:      exiting: void gcc::jit::recording::context::replay_into(gcc::jit::replayer*)
JIT:      entering: void gcc::jit::recording::context::disassociate_from_playback()
JIT:      exiting: void gcc::jit::recording::context::disassociate_from_playback()
JIT:      entering: void gcc::jit::playback::context::handle_locations()
JIT:      exiting: void gcc::jit::playback::context::handle_locations()
JIT:      entering: void gcc::jit::playback::function::build_stmt_list()
JIT:      exiting: void gcc::jit::playback::function::build_stmt_list()
JIT:      entering: void gcc::jit::playback::function::build_stmt_list()
JIT:      exiting: void gcc::jit::playback::function::build_stmt_list()
JIT:      entering: void gcc::jit::playback::function::postprocess()
JIT:      exiting: void gcc::jit::playback::function::postprocess()
JIT:      entering: void gcc::jit::playback::function::postprocess()
JIT:      exiting: void gcc::jit::playback::function::postprocess()
JIT:     exiting: void gcc::jit::playback::context::replay()
JIT:    exiting: toplev::main
JIT:    entering: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
JIT:    exiting: void gcc::jit::playback::context::extract_any_requested_dumps(vec<gcc::jit::recording::requested_dump>*)
JIT:    entering: toplev::finalize
JIT:    exiting: toplev::finalize
JIT:    entering: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
JIT:     entering: void gcc::jit::playback::context::convert_to_dso(const char*)
JIT:      entering: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
JIT:       entering: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
JIT:       exiting: void gcc::jit::playback::context::add_multilib_driver_arguments(vec<char*>*)
JIT:       argv[0]: x86_64-unknown-linux-gnu-gcc-6.0.0
JIT:       argv[1]: -m64
JIT:       argv[2]: -shared
JIT:       argv[3]: /tmp/libgccjit-CKq1M9/fake.s
JIT:       argv[4]: -o
JIT:       argv[5]: /tmp/libgccjit-CKq1M9/fake.so
JIT:       argv[6]: -fno-use-linker-plugin
JIT:       entering: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*)
JIT:       exiting: void gcc::jit::playback::context::invoke_embedded_driver(const vec<char*>*)
JIT:      exiting: void gcc::jit::playback::context::invoke_driver(const char*, const char*, const char*, timevar_id_t, bool, bool)
JIT:     exiting: void gcc::jit::playback::context::convert_to_dso(const char*)
JIT:     entering: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
JIT:      GCC_JIT_BOOL_OPTION_DEBUGINFO was set: handing over tempdir to jit::result
JIT:      entering: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
JIT:      exiting: gcc::jit::result::result(gcc::jit::logger*, void*, gcc::jit::tempdir*)
JIT:     exiting: gcc::jit::result* gcc::jit::playback::context::dlopen_built_dso()
JIT:    exiting: virtual void gcc::jit::playback::compile_to_memory::postprocess(const char*)
JIT:    entering: void gcc::jit::playback::context::release_mutex()
JIT:    exiting: void gcc::jit::playback::context::release_mutex()
JIT:   exiting: void gcc::jit::playback::context::compile()
JIT:   entering: gcc::jit::playback::context::~context()
JIT:   exiting: gcc::jit::playback::context::~context()
JIT:  exiting: gcc::jit::result* gcc::jit::recording::context::compile()
JIT:  gcc_jit_context_compile: returning (gcc_jit_result *)0x12f75d0
JIT: exiting: gcc_jit_context_compile
JIT: entering: gcc_jit_result_get_code
JIT:  locating fnname: hello_world
JIT:  entering: void* gcc::jit::result::get_code(const char*)
JIT:  exiting: void* gcc::jit::result::get_code(const char*)
JIT:  gcc_jit_result_get_code: returning (void *)0x7ff6b8cd87f0
JIT: exiting: gcc_jit_result_get_code
JIT: entering: gcc_jit_context_release
JIT:  deleting ctxt: 0x1283e20
JIT:  entering: gcc::jit::recording::context::~context()
JIT:  exiting: gcc::jit::recording::context::~context()
JIT: exiting: gcc_jit_context_release
JIT: entering: gcc_jit_result_release
JIT:  deleting result: 0x12f75d0
JIT:  entering: virtual gcc::jit::result::~result()
JIT:   entering: gcc::jit::tempdir::~tempdir()
JIT:    unlinking .s file: /tmp/libgccjit-CKq1M9/fake.s
JIT:    unlinking .so file: /tmp/libgccjit-CKq1M9/fake.so
JIT:    removing tempdir: /tmp/libgccjit-CKq1M9
JIT:   exiting: gcc::jit::tempdir::~tempdir()
JIT:  exiting: virtual gcc::jit::result::~result()
JIT: exiting: gcc_jit_result_release
JIT: gcc::jit::logger::~logger()

---

### Gcc Jit Docs Intro Index (`gcc/jit/docs/intro/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial
========

.. toctree::
   :maxdepth: 2

   tutorial01.rst
   tutorial02.rst
   tutorial03.rst
   tutorial04.rst
   tutorial05.rst

---

### Gcc Jit Docs Intro Tutorial01 (`gcc/jit/docs/intro/tutorial01.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 1: "Hello world"
==============================

Before we look at the details of the API, let's look at building and
running programs that use the library.

Here's a toy "hello world" program that uses the library to synthesize
a call to `printf` and uses it to write a message to stdout.

Don't worry about the content of the program for now; we'll cover
the details in later parts of this tutorial.

   .. literalinclude:: ../examples/tut01-hello-world.c
    :language: c

Copy the above to `tut01-hello-world.c`.

Assuming you have the jit library installed, build the test program
using:

.. code-block:: console

  $ gcc \
      tut01-hello-world.c \
      -o tut01-hello-world \
      -lgccjit

You should then be able to run the built program:

.. code-block:: console

  $ ./tut01-hello-world
  hello world

---

### Gcc Jit Docs Intro Tutorial02 (`gcc/jit/docs/intro/tutorial02.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Tutorial part 2: Creating a trivial machine code function
---------------------------------------------------------

Consider this C function:

.. code-block:: c

   int square (int i)
   {
     return i * i;
   }

How can we construct this at run-time using libgccjit?

First we need to include the relevant header:

.. code-block:: c

  #include <libgccjit.h>

All state associated with compilation is associated with a
:c:expr:`gcc_jit_context *`.

Create one using :c:func:`gcc_jit_context_acquire`:

.. code-block:: c

  gcc_jit_context *ctxt;
  ctxt = gcc_jit_context_acquire ();

The JIT library has a system of types.  It is statically-typed: every
expression is of a specific type, fixed at compile-time.  In our example,
all of the expressions are of the C `int` type, so let's obtain this from
the context, as a :c:expr:`gcc_jit_type *`, using
:c:func:`gcc_jit_context_get_type`:

.. code-block:: c

  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

:c:expr:`gcc_jit_type *` is an example of a "contextual" object: every
entity in the API is associated with a :c:expr:`gcc_jit_context *`.

Memory management is easy: all such "contextual" objects are automatically
cleaned up for you when the context is released, using
:c:func:`gcc_jit_context_release`:

.. code-block:: c

  gcc_jit_context_release (ctxt);

so you don't need to manually track and cleanup all objects, just the
contexts.

Although the API is C-based, there is a form of class hierarchy, which
looks like this::

  +- gcc_jit_object
      +- gcc_jit_location
      +- gcc_jit_type
         +- gcc_jit_struct
      +- gcc_jit_field
      +- gcc_jit_function
      +- gcc_jit_block
      +- gcc_jit_rvalue
          +- gcc_jit_lvalue
             +- gcc_jit_param

There are casting methods for upcasting from subclasses to parent classes.
For example, :c:func:`gcc_jit_type_as_object`:

.. code-block:: c

   gcc_jit_object *obj = gcc_jit_type_as_object (int_type);

One thing you can do with a :c:expr:`gcc_jit_object *` is
to ask it for a human-readable description, using
:c:func:`gcc_jit_object_get_debug_string`:

.. code-block:: c

   printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));

giving this text on stdout:

.. code-block:: bash

   obj: int

This is invaluable when debugging.

Let's create the function.  To do so, we first need to construct
its single parameter, specifying its type and giving it a name,
using :c:func:`gcc_jit_context_new_param`:

.. code-block:: c

  gcc_jit_param *param_i =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "i");

Now we can create the function, using
:c:func:`gcc_jit_context_new_function`:

.. code-block:: c

  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  int_type,
                                  "square",
                                  1, &param_i,
                                  0);

To define the code within the function, we must create basic blocks
containing statements.

Every basic block contains a list of statements, eventually terminated
by a statement that either returns, or jumps to another basic block.

Our function has no control-flow, so we just need one basic block:

.. code-block:: c

  gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);

Our basic block is relatively simple: it immediately terminates by
returning the value of an expression.

We can build the expression using :c:func:`gcc_jit_context_new_binary_op`:

.. code-block:: c

   gcc_jit_rvalue *expr =
     gcc_jit_context_new_binary_op (
       ctxt, NULL,
       GCC_JIT_BINARY_OP_MULT, int_type,
       gcc_jit_param_as_rvalue (param_i),
       gcc_jit_param_as_rvalue (param_i));

A :c:expr:`gcc_jit_rvalue *` is another example of a
:c:expr:`gcc_jit_object *` subclass.  We can upcast it using
:c:func:`gcc_jit_rvalue_as_object` and as before print it with
:c:func:`gcc_jit_object_get_debug_string`.

.. code-block:: c

   printf ("expr: %s\n",
           gcc_jit_object_get_debug_string (
             gcc_jit_rvalue_as_object (expr)));

giving this output:

.. code-block:: bash

   expr: i * i

Creating the expression in itself doesn't do anything; we have to add
this expression to a statement within the block.  In this case, we use it
to build a return statement, which terminates the basic block:

.. code-block:: c

  gcc_jit_block_end_with_return (block, NULL, expr);

OK, we've populated the context.  We can now compile it using
:c:func:`gcc_jit_context_compile`:

.. code-block:: c

   gcc_jit_result *result;
   result = gcc_jit_context_compile (ctxt);

and get a :c:expr:`gcc_jit_result *`.

At this point we're done with the context; we can release it:

.. code-block:: c

   gcc_jit_context_release (ctxt);

We can now use :c:func:`gcc_jit_result_get_code` to look up a specific
machine code routine within the result, in this case, the function we
created above.

.. code-block:: c

   void *fn_ptr = gcc_jit_result_get_code (result, "square");
   if (!fn_ptr)
     {
       fprintf (stderr, "NULL fn_ptr");
       goto error;
     }

We can now cast the pointer to an appropriate function pointer type, and
then call it:

.. code-block:: c

  typedef int (*fn_type) (int);
  fn_type square = (fn_type)fn_ptr;
  printf ("result: %d", square (5));

.. code-block:: bash

  result: 25

Once we're done with the code, we can release the result:

.. code-block:: c

   gcc_jit_result_release (result);

We can't call ``square`` anymore once we've released ``result``.


Error-handling
**************
Various kinds of errors are possible when using the API, such as
mismatched types in an assignment.  You can only compile and get code
from a context if no errors occur.

Errors are printed on stderr; they typically contain the name of the API
entrypoint where the error occurred, and pertinent information on the
problem:

.. code-block:: console

  ./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)

The API is designed to cope with errors without crashing, so you can get
away with having a single error-handling check in your code:

.. code-block:: c

   void *fn_ptr = gcc_jit_result_get_code (result, "square");
   if (!fn_ptr)
     {
       fprintf (stderr, "NULL fn_ptr");
       goto error;
     }

For more information, see the :ref:`error-handling guide <error-handling>`
within the Topic reference.


Options
*******

To get more information on what's going on, you can set debugging flags
on the context using :c:func:`gcc_jit_context_set_bool_option`.

.. (I'm deliberately not mentioning
    :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
    it's probably more of use to implementors than to users)

Setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE` will dump a
C-like representation to stderr when you compile (GCC's "GIMPLE"
representation):

.. code-block:: c

   gcc_jit_context_set_bool_option (
     ctxt,
     GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
     1);
   result = gcc_jit_context_compile (ctxt);

.. code-block:: c

  square (signed int i)
  {
    signed int D.260;

    entry:
    D.260 = i * i;
    return D.260;
  }

We can see the generated machine code in assembler form (on stderr) by
setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE` on the context
before compiling:

.. code-block:: c

  gcc_jit_context_set_bool_option (
    ctxt,
    GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
    1);
  result = gcc_jit_context_compile (ctxt);

.. code-block:: gas

        .file   "fake.c"
        .text
        .globl  square
        .type   square, @function
  square:
  .LFB6:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
  .L14:
        movl    -4(%rbp), %eax
        imull   -4(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
  .LFE6:
        .size   square, .-square
        .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
        .section       .note.GNU-stack,"",@progbits

By default, no optimizations are performed, the equivalent of GCC's
`-O0` option.  We can turn things up to e.g. `-O3` by calling
:c:func:`gcc_jit_context_set_int_option` with
:c:macro:`GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL`:

.. code-block:: c

  gcc_jit_context_set_int_option (
    ctxt,
    GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
    3);

.. code-block:: gas

        .file   "fake.c"
        .text
        .p2align 4,,15
        .globl  square
        .type   square, @function
  square:
  .LFB7:
        .cfi_startproc
  .L16:
        movl    %edi, %eax
        imull   %edi, %eax
        ret
        .cfi_endproc
  .LFE7:
        .size   square, .-square
        .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
        .section        .note.GNU-stack,"",@progbits

Naturally this has only a small effect on such a trivial function.


Full example
************

Here's what the above looks like as a complete program:

   .. literalinclude:: ../examples/tut02-square.c
    :lines: 1-
    :language: c

Building and running it:

.. code-block:: console

  $ gcc \
      tut02-square.c \
      -o tut02-square \
      -lgccjit

  # Run the built program:
  $ ./tut02-square
  result: 25

---

### Gcc Jit Docs Intro Tutorial03 (`gcc/jit/docs/intro/tutorial03.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial part 3: Loops and variables
------------------------------------
Consider this C function:

 .. code-block:: c

  int loop_test (int n)
  {
    int sum = 0;
    for (int i = 0; i < n; i++)
      sum += i * i;
    return sum;
  }

This example demonstrates some more features of libgccjit, with local
variables and a loop.

To break this down into libgccjit terms, it's usually easier to reword
the `for` loop as a `while` loop, giving:

 .. code-block:: c

  int loop_test (int n)
  {
    int sum = 0;
    int i = 0;
    while (i < n)
    {
      sum += i * i;
      i++;
    }
    return sum;
  }

Here's what the final control flow graph will look like:

    .. figure:: sum-of-squares.png
      :alt: image of a control flow graph

As before, we include the libgccjit header and make a
:c:expr:`gcc_jit_context *`.

.. code-block:: c

  #include <libgccjit.h>

  void test (void)
  {
    gcc_jit_context *ctxt;
    ctxt = gcc_jit_context_acquire ();

The function works with the C `int` type:

.. code-block:: c

  gcc_jit_type *the_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *return_type = the_type;

though we could equally well make it work on, say, `double`:

.. code-block:: c

  gcc_jit_type *the_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);

Let's build the function:

.. code-block:: c

  gcc_jit_param *n =
    gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
  gcc_jit_param *params[1] = {n};
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  return_type,
				  "loop_test",
				  1, params, 0);

Expressions: lvalues and rvalues
********************************

The base class of expression is the :c:expr:`gcc_jit_rvalue *`,
representing an expression that can be on the *right*-hand side of
an assignment: a value that can be computed somehow, and assigned
*to* a storage area (such as a variable).  It has a specific
:c:expr:`gcc_jit_type *`.

Another important class is :c:expr:`gcc_jit_lvalue *`.
A :c:expr:`gcc_jit_lvalue *`. is something that can of the *left*-hand
side of an assignment: a storage area (such as a variable).

In other words, every assignment can be thought of as:

.. code-block:: c

   LVALUE = RVALUE;

Note that :c:expr:`gcc_jit_lvalue *` is a subclass of
:c:expr:`gcc_jit_rvalue *`, where in an assignment of the form:

.. code-block:: c

   LVALUE_A = LVALUE_B;

the `LVALUE_B` implies reading the current value of that storage
area, assigning it into the `LVALUE_A`.

So far the only expressions we've seen are `i * i`:

.. code-block:: c

   gcc_jit_rvalue *expr =
     gcc_jit_context_new_binary_op (
       ctxt, NULL,
       GCC_JIT_BINARY_OP_MULT, int_type,
       gcc_jit_param_as_rvalue (param_i),
       gcc_jit_param_as_rvalue (param_i));

which is a :c:expr:`gcc_jit_rvalue *`, and the various function
parameters: `param_i` and `param_n`, instances of
:c:expr:`gcc_jit_param *`, which is a subclass of
:c:expr:`gcc_jit_lvalue *` (and, in turn, of :c:expr:`gcc_jit_rvalue *`):
we can both read from and write to function parameters within the
body of a function.

Our new example has a couple of local variables.  We create them by
calling :c:func:`gcc_jit_function_new_local`, supplying a type and a
name:

.. code-block:: c

  /* Build locals:  */
  gcc_jit_lvalue *i =
    gcc_jit_function_new_local (func, NULL, the_type, "i");
  gcc_jit_lvalue *sum =
    gcc_jit_function_new_local (func, NULL, the_type, "sum");

These are instances of :c:expr:`gcc_jit_lvalue *` - they can be read from
and written to.

Note that there is no precanned way to create *and* initialize a variable
like in C:

.. code-block:: c

   int i = 0;

Instead, having added the local to the function, we have to separately add
an assignment of `0` to `local_i` at the beginning of the function.

Control flow
************

This function has a loop, so we need to build some basic blocks to
handle the control flow.  In this case, we need 4 blocks:

1. before the loop (initializing the locals)
2. the conditional at the top of the loop (comparing `i < n`)
3. the body of the loop
4. after the loop terminates (`return sum`)

so we create these as :c:expr:`gcc_jit_block *` instances within the
:c:expr:`gcc_jit_function *`:

.. code-block:: c

  gcc_jit_block *b_initial =
    gcc_jit_function_new_block (func, "initial");
  gcc_jit_block *b_loop_cond =
    gcc_jit_function_new_block (func, "loop_cond");
  gcc_jit_block *b_loop_body =
    gcc_jit_function_new_block (func, "loop_body");
  gcc_jit_block *b_after_loop =
    gcc_jit_function_new_block (func, "after_loop");

We now populate each block with statements.

The entry block `b_initial` consists of initializations followed by a jump
to the conditional.  We assign `0` to `i` and to `sum`, using
:c:func:`gcc_jit_block_add_assignment` to add
an assignment statement, and using :c:func:`gcc_jit_context_zero` to get
the constant value `0` for the relevant type for the right-hand side of
the assignment:

.. code-block:: c

  /* sum = 0; */
  gcc_jit_block_add_assignment (
    b_initial, NULL,
    sum,
    gcc_jit_context_zero (ctxt, the_type));

  /* i = 0; */
  gcc_jit_block_add_assignment (
    b_initial, NULL,
    i,
    gcc_jit_context_zero (ctxt, the_type));

We can then terminate the entry block by jumping to the conditional:

.. code-block:: c

  gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);

The conditional block is equivalent to the line `while (i < n)` from our
C example. It contains a single statement: a conditional, which jumps to
one of two destination blocks depending on a boolean
:c:expr:`gcc_jit_rvalue *`, in this case the comparison of `i` and `n`.
We build the comparison using :c:func:`gcc_jit_context_new_comparison`:

.. code-block:: c

  /* (i >= n) */
   gcc_jit_rvalue *guard =
     gcc_jit_context_new_comparison (
       ctxt, NULL,
       GCC_JIT_COMPARISON_GE,
       gcc_jit_lvalue_as_rvalue (i),
       gcc_jit_param_as_rvalue (n));

and can then use this to add `b_loop_cond`'s sole statement, via
:c:func:`gcc_jit_block_end_with_conditional`:

.. code-block:: c

  /* Equivalent to:
       if (guard)
         goto after_loop;
       else
         goto loop_body;  */
  gcc_jit_block_end_with_conditional (
    b_loop_cond, NULL,
    guard,
    b_after_loop, /* on_true */
    b_loop_body); /* on_false */

Next, we populate the body of the loop.

The C statement `sum += i * i;` is an assignment operation, where an
lvalue is modified "in-place".  We use
:c:func:`gcc_jit_block_add_assignment_op` to handle these operations:

.. code-block:: c

  /* sum += i * i */
  gcc_jit_block_add_assignment_op (
    b_loop_body, NULL,
    sum,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT, the_type,
      gcc_jit_lvalue_as_rvalue (i),
      gcc_jit_lvalue_as_rvalue (i)));

The `i++` can be thought of as `i += 1`, and can thus be handled in
a similar way.  We use :c:func:`gcc_jit_context_one` to get the constant
value `1` (for the relevant type) for the right-hand side
of the assignment.

.. code-block:: c

  /* i++ */
  gcc_jit_block_add_assignment_op (
    b_loop_body, NULL,
    i,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_one (ctxt, the_type));

.. note::

  For numeric constants other than 0 or 1, we could use
  :c:func:`gcc_jit_context_new_rvalue_from_int` and
  :c:func:`gcc_jit_context_new_rvalue_from_double`.

The loop body completes by jumping back to the conditional:

.. code-block:: c

  gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);

Finally, we populate the `b_after_loop` block, reached when the loop
conditional is false.  We want to generate the equivalent of:

.. code-block:: c

   return sum;

so the block is just one statement:

.. code-block:: c

  /* return sum */
  gcc_jit_block_end_with_return (
    b_after_loop,
    NULL,
    gcc_jit_lvalue_as_rvalue (sum));

.. note::

   You can intermingle block creation with statement creation,
   but given that the terminator statements generally include references
   to other blocks, I find it's clearer to create all the blocks,
   *then* all the statements.

We've finished populating the function.  As before, we can now compile it
to machine code:

.. code-block:: c

   gcc_jit_result *result;
   result = gcc_jit_context_compile (ctxt);

   typedef int (*loop_test_fn_type) (int);
   loop_test_fn_type loop_test =
    (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
   if (!loop_test)
     goto error;
   printf ("result: %d", loop_test (10));

.. code-block:: bash

   result: 285


Visualizing the control flow graph
**********************************

You can see the control flow graph of a function using
:c:func:`gcc_jit_function_dump_to_dot`:

.. code-block:: c

  gcc_jit_function_dump_to_dot (func, "/tmp/sum-of-squares.dot");

giving a .dot file in GraphViz format.

You can convert this to an image using `dot`:

.. code-block:: bash

   $ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png

or use a viewer (my preferred one is xdot.py; see
https://github.com/jrfonseca/xdot.py; on Fedora you can
install it with `yum install python-xdot`):

    .. figure:: sum-of-squares.png
      :alt: image of a control flow graph

Full example
************

   .. literalinclude:: ../examples/tut03-sum-of-squares.c
    :lines: 1-
    :language: c

Building and running it:

.. code-block:: console

  $ gcc \
      tut03-sum-of-squares.c \
      -o tut03-sum-of-squares \
      -lgccjit

  # Run the built program:
  $ ./tut03-sum-of-squares
  loop_test returned: 285

---

### Gcc Jit Docs Intro Tutorial04 (`gcc/jit/docs/intro/tutorial04.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial part 4: Adding JIT-compilation to a toy interpreter
------------------------------------------------------------
In this example we construct a "toy" interpreter, and add JIT-compilation
to it.

Our toy interpreter
*******************

It's a stack-based interpreter, and is intended as a (very simple) example
of the kind of bytecode interpreter seen in dynamic languages such as
Python, Ruby etc.

For the sake of simplicity, our toy virtual machine is very limited:

  * The only data type is `int`

  * It can only work on one function at a time (so that the only
    function call that can be made is to recurse).

  * Functions can only take one parameter.

  * Functions have a stack of `int` values.

  * We'll implement function call within the interpreter by calling a
    function in our implementation, rather than implementing our own
    frame stack.

  * The parser is only good enough to get the examples to work.

Naturally, a real interpreter would be much more complicated that this.

The following operations are supported:

.. list-table::
   :header-rows: 1
   :widths: 35 50 25 25

   * - Operation
     - Meaning
     - Old Stack
     - New Stack

   * - DUP
     - Duplicate top of stack.
     - ``[..., x]``
     - ``[..., x, x]``
   * - ROT
     - Swap top two elements of stack.
     - ``[..., x, y]``
     - ``[..., y, x]``
   * - BINARY_ADD
     - Add the top two elements on the stack.
     - ``[..., x, y]``
     - ``[..., (x+y)]``
   * - BINARY_SUBTRACT
     - Likewise, but subtract.
     - ``[..., x, y]``
     - ``[..., (x-y)]``
   * - BINARY_MULT
     - Likewise, but multiply.
     - ``[..., x, y]``
     - ``[..., (x*y)]``
   * - BINARY_COMPARE_LT
     - Compare the top two elements on the stack and push a nonzero/zero if (x<y).
     - ``[..., x, y]``
     - ``[..., (x<y)]``
   * - RECURSE
     - Recurse, passing the top of the stack, and popping the result.
     - ``[..., x]``
     - ``[..., fn(x)]``
   * - RETURN
     - Return the top of the stack.
     - ``[x]``
     - ``[]``
   * - PUSH_CONST `arg`
     - Push an int const.
     - ``[...]``
     - ``[..., arg]``
   * - JUMP_ABS_IF_TRUE `arg`
     - Pop; if top of stack was nonzero, jump to ``arg``.
     - ``[..., x]``
     - ``[...]``

Programs can be interpreted, disassembled, and compiled to machine code.

The interpreter reads ``.toy`` scripts.  Here's what a simple recursive
factorial program looks like, the script ``factorial.toy``.
The parser ignores lines beginning with a `#`.

   .. literalinclude:: ../examples/tut04-toyvm/factorial.toy
    :lines: 1-
    :language: c

The interpreter is a simple infinite loop with a big ``switch`` statement
based on what the next opcode is:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Execute the given function.  */
    :end-before: /* JIT compilation.  */
    :language: c

Compiling to machine code
*************************
We want to generate machine code that can be cast to this type and
then directly executed in-process:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Functions are compiled to this function ptr type.  */
    :end-before: enum opcode
    :language: c

The lifetime of the code is tied to that of a :c:expr:`gcc_jit_result *`.
We'll handle this by bundling them up in a structure, so that we can
clean them up together by calling :c:func:`gcc_jit_result_release`:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* A struct to hold the compilation results.  */
    :end-before: /* The main compilation hook.  */
    :language: c

Our compiler isn't very sophisticated; it takes the implementation of
each opcode above, and maps it directly to the operations supported by
the libgccjit API.

How should we handle the stack?  In theory we could calculate what the
stack depth will be at each opcode, and optimize away the stack
manipulation "by hand".  We'll see below that libgccjit is able to do
this for us, so we'll implement stack manipulation
in a direct way, by creating a ``stack`` array and ``stack_depth``
variables, local within the generated function, equivalent to this C code:

.. code-block:: c

  int stack_depth;
  int stack[MAX_STACK_DEPTH];

We'll also have local variables ``x`` and ``y`` for use when implementing
the opcodes, equivalent to this:

.. code-block:: c

  int x;
  int y;

This means our compiler has the following state:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* JIT compilation.  */
    :end-before: /* Stack manipulation.  */
    :language: c

Setting things up
*****************

First we create our types:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Create types.  */
    :end-before: /* The constant value 1.  */
    :language: c

along with extracting a useful `int` constant:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* The constant value 1.  */
    :end-before: /* Create locations.  */
    :language: c

We'll implement push and pop in terms of the ``stack`` array and
``stack_depth``.  Here are helper functions for adding statements to
a block, implementing pushing and popping values:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Stack manipulation.  */
    :end-before: /* A struct to hold the compilation results.  */
    :language: c

We will support single-stepping through the generated code in the
debugger, so we need to create :c:type:`gcc_jit_location` instances, one
per operation in the source code.  These will reference the lines of
e.g. ``factorial.toy``.

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Create locations.  */
    :end-before: /* Creating the function.  */
    :language: c

Let's create the function itself.  As usual, we create its parameter
first, then use the parameter to create the function:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Creating the function.  */
    :end-before: /* Create stack lvalues.  */
    :language: c

We create the locals within the function.

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Create stack lvalues.  */
    :end-before: /* 1st pass: create blocks, one per opcode.
    :language: c

Populating the function
***********************

There's some one-time initialization, and the API treats the first block
you create as the entrypoint of the function, so we need to create that
block first:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: first.  */
    :end-before: /* Create a block per operation.  */
    :language: c

We can now create blocks for each of the operations.  Most of these will
be consolidated into larger blocks when the optimizer runs.

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Create a block per operation.  */
    :end-before: /* Populate the initial block.  */
    :language: c

Now that we have a block it can jump to when it's done, we can populate
the initial block:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Populate the initial block.  */
    :end-before: /* 2nd pass: fill in instructions.  */
    :language: c

We can now populate the blocks for the individual operations.  We loop
through them, adding instructions to their blocks:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* 2nd pass: fill in instructions.  */
    :end-before: /* Helper macros.  */
    :language: c

We're going to have another big ``switch`` statement for implementing
the opcodes, this time for compiling them, rather than interpreting
them.  It's helpful to have macros for implementing push and pop, so that
we can make the ``switch`` statement that's coming up look as much as
possible like the one above within the interpreter:

.. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Helper macros.  */
    :end-before: gcc_jit_block_add_comment
    :language: c

.. note::

   A particularly clever implementation would have an *identical*
   ``switch`` statement shared by the interpreter and the compiler, with
   some preprocessor "magic".  We're not doing that here, for the sake
   of simplicity.

When I first implemented this compiler, I accidentally missed an edit
when copying and pasting the ``Y_EQUALS_POP`` macro, so that popping the
stack into ``y`` instead erroneously assigned it to ``x``, leaving ``y``
uninitialized.

To track this kind of thing down, we can use
:c:func:`gcc_jit_block_add_comment` to add descriptive comments
to the internal representation.  This is invaluable when looking through
the generated IR for, say ``factorial``:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y))
    :end-before: /* Handle the individual opcodes.  */
    :language: c

We can now write the big ``switch`` statement that implements the
individual opcodes, populating the relevant block with statements:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Handle the individual opcodes.  */
    :end-before: /* Go to the next block.  */
    :language: c

Every block must be terminated, via a call to one of the
``gcc_jit_block_end_with_`` entrypoints.  This has been done for two
of the opcodes, but we need to do it for the other ones, by jumping
to the next block.

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* Go to the next block.  */
    :end-before: /* end of loop on PC locations.  */
    :language: c

This is analogous to simply incrementing the program counter.

Verifying the control flow graph
********************************
Having finished looping over the blocks, the context is complete.

As before, we can verify that the control flow and statements are sane by
using :c:func:`gcc_jit_function_dump_to_dot`:

.. code-block:: c

  gcc_jit_function_dump_to_dot (state.fn, "/tmp/factorial.dot");

and viewing the result.  Note how the label names, comments, and
variable names show up in the dump, to make it easier to spot
errors in our compiler.

  .. figure:: factorial.png
    :alt: image of a control flow graph

Compiling the context
*********************
Having finished looping over the blocks and populating them with
statements, the context is complete.

We can now compile it, and extract machine code from the result:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* We've now finished populating the context.  Compile it.  */
    :end-before: /* (this leaks "jit_result" and "funcname") */
    :language: c

We can now run the result:

   .. literalinclude:: ../examples/tut04-toyvm/toyvm.c
    :start-after: /* JIT-compilation.  */
    :end-before: return 0;
    :language: c

Single-stepping through the generated code
******************************************

It's possible to debug the generated code.  To do this we need to both:

  * Set up source code locations for our statements, so that we can
    meaningfully step through the code.  We did this above by
    calling :c:func:`gcc_jit_context_new_location` and using the
    results.

  * Enable the generation of debugging information, by setting
    :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` on the
    :c:type:`gcc_jit_context` via
    :c:func:`gcc_jit_context_set_bool_option`:

    .. code-block:: c

     gcc_jit_context_set_bool_option (
       ctxt,
       GCC_JIT_BOOL_OPTION_DEBUGINFO,
       1);

Having done this, we can put a breakpoint on the generated function:

.. code-block:: console

  $ gdb --args ./toyvm factorial.toy 10
  (gdb) break factorial
  Function "factorial" not defined.
  Make breakpoint pending on future shared library load? (y or [n]) y
  Breakpoint 1 (factorial) pending.
  (gdb) run
  Breakpoint 1, factorial (arg=10) at factorial.toy:14
  14	DUP

We've set up location information, which references ``factorial.toy``.
This allows us to use e.g. ``list`` to see where we are in the script:

.. code-block:: console

  (gdb) list
  9
  10    # Initial state:
  11    # stack: [arg]
  12
  13    # 0:
  14    DUP
  15    # stack: [arg, arg]
  16
  17    # 1:
  18    PUSH_CONST 2

and to step through the function, examining the data:

.. code-block:: console

  (gdb) n
  18    PUSH_CONST 2
  (gdb) n
  22    BINARY_COMPARE_LT
  (gdb) print stack
  $5 = {10, 10, 2, 0, -7152, 32767, 0, 0}
  (gdb) print stack_depth
  $6 = 3

You'll see that the parts of the ``stack`` array that haven't been
touched yet are uninitialized.

.. note::

   Turning on optimizations may lead to unpredictable results when
   stepping through the generated code: the execution may appear to
   "jump around" the source code.  This is analogous to turning up the
   optimization level in a regular compiler.

Examining the generated code
****************************

How good is the optimized code?

We can turn up optimizations, by calling
:c:func:`gcc_jit_context_set_int_option` with
:c:macro:`GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL`:

.. code-block:: c

  gcc_jit_context_set_int_option (
    ctxt,
    GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
    3);

One of GCC's internal representations is called "gimple".  A dump of the
initial gimple representation of the code can be seen by setting:

.. code-block:: c

  gcc_jit_context_set_bool_option (ctxt,
                                   GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
                                   1);

With optimization on and source locations displayed, this gives:

.. We'll use "c" for gimple dumps

.. code-block:: c

  factorial (signed int arg)
  {
    <unnamed type> D.80;
    signed int D.81;
    signed int D.82;
    signed int D.83;
    signed int D.84;
    signed int D.85;
    signed int y;
    signed int x;
    signed int stack_depth;
    signed int stack[8];

    try
      {
        initial:
        stack_depth = 0;
        stack[stack_depth] = arg;
        stack_depth = stack_depth + 1;
        goto instr0;
        instr0:
        /* DUP */:
        stack_depth = stack_depth + -1;
        x = stack[stack_depth];
        stack[stack_depth] = x;
        stack_depth = stack_depth + 1;
        stack[stack_depth] = x;
        stack_depth = stack_depth + 1;
        goto instr1;
        instr1:
        /* PUSH_CONST */:
        stack[stack_depth] = 2;
        stack_depth = stack_depth + 1;
        goto instr2;

        /* etc */

You can see the generated machine code in assembly form via:

.. code-block:: c

  gcc_jit_context_set_bool_option (
    ctxt,
    GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
    1);
  result = gcc_jit_context_compile (ctxt);

which shows that (on this x86_64 box) the compiler has unrolled the loop
and is using MMX instructions to perform several multiplications
simultaneously:

.. code-block:: gas

          .file   "fake.c"
          .text
  .Ltext0:
          .p2align 4,,15
          .globl  factorial
          .type   factorial, @function
  factorial:
  .LFB0:
          .file 1 "factorial.toy"
          .loc 1 14 0
          .cfi_startproc
  .LVL0:
  .L2:
          .loc 1 26 0
          cmpl    $1, %edi
          jle     .L13
          leal    -1(%rdi), %edx
          movl    %edx, %ecx
          shrl    $2, %ecx
          leal    0(,%rcx,4), %esi
          testl   %esi, %esi
          je      .L14
          cmpl    $9, %edx
          jbe     .L14
          leal    -2(%rdi), %eax
          movl    %eax, -16(%rsp)
          leal    -3(%rdi), %eax
          movd    -16(%rsp), %xmm0
          movl    %edi, -16(%rsp)
          movl    %eax, -12(%rsp)
          movd    -16(%rsp), %xmm1
          xorl    %eax, %eax
          movl    %edx, -16(%rsp)
          movd    -12(%rsp), %xmm4
          movd    -16(%rsp), %xmm6
          punpckldq       %xmm4, %xmm0
          movdqa  .LC1(%rip), %xmm4
          punpckldq       %xmm6, %xmm1
          punpcklqdq      %xmm0, %xmm1
          movdqa  .LC0(%rip), %xmm0
          jmp     .L5
          # etc - edited for brevity

This is clearly overkill for a function that will likely overflow the
``int`` type before the vectorization is worthwhile - but then again, this
is a toy example.

Turning down the optimization level to 2:

.. code-block:: c

  gcc_jit_context_set_int_option (
    ctxt,
    GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
    3);

yields this code, which is simple enough to quote in its entirety:

.. code-block:: gas

          .file   "fake.c"
          .text
          .p2align 4,,15
          .globl  factorial
          .type   factorial, @function
  factorial:
  .LFB0:
          .cfi_startproc
  .L2:
          cmpl    $1, %edi
          jle     .L8
          movl    $1, %edx
          jmp     .L4
          .p2align 4,,10
          .p2align 3
  .L6:
          movl    %eax, %edi
  .L4:
  .L5:
          leal    -1(%rdi), %eax
          imull   %edi, %edx
          cmpl    $1, %eax
          jne     .L6
  .L3:
  .L7:
          imull   %edx, %eax
          ret
  .L8:
          movl    %edi, %eax
          movl    $1, %edx
          jmp     .L7
          .cfi_endproc
  .LFE0:
          .size   factorial, .-factorial
          .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
          .section        .note.GNU-stack,"",@progbits

Note that the stack pushing and popping have been eliminated, as has the
recursive call (in favor of an iteration).

Putting it all together
***********************

The complete example can be seen in the source tree at
``gcc/jit/docs/examples/tut04-toyvm/toyvm.c``

along with a Makefile and a couple of sample .toy scripts:

.. code-block:: console

  $ ls -al
  drwxrwxr-x. 2 david david   4096 Sep 19 17:46 .
  drwxrwxr-x. 3 david david   4096 Sep 19 15:26 ..
  -rw-rw-r--. 1 david david    615 Sep 19 12:43 factorial.toy
  -rw-rw-r--. 1 david david    834 Sep 19 13:08 fibonacci.toy
  -rw-rw-r--. 1 david david    238 Sep 19 14:22 Makefile
  -rw-rw-r--. 1 david david  16457 Sep 19 17:07 toyvm.c

  $ make toyvm
  g++ -Wall -g -o toyvm toyvm.c -lgccjit

  $ ./toyvm factorial.toy 10
  interpreter result: 3628800
  compiler result: 3628800

  $ ./toyvm fibonacci.toy 10
  interpreter result: 55
  compiler result: 55

Behind the curtain: How does our code get optimized?
****************************************************

Our example is done, but you may be wondering about exactly how the
compiler turned what we gave it into the machine code seen above.

We can examine what the compiler is doing in detail by setting:

.. code-block:: c

  gcc_jit_context_set_bool_option (state.ctxt,
                                   GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
                                   1);
  gcc_jit_context_set_bool_option (state.ctxt,
                                   GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
                                   1);

This will dump detailed information about the compiler's state to a
directory under ``/tmp``, and keep it from being cleaned up.

The precise names and their formats of these files is subject to change.
Higher optimization levels lead to more files.
Here's what I saw (edited for brevity; there were almost 200 files):

.. code-block:: console

  intermediate files written to /tmp/libgccjit-KPQbGw
  $ ls /tmp/libgccjit-KPQbGw/
  fake.c.000i.cgraph
  fake.c.000i.type-inheritance
  fake.c.004t.gimple
  fake.c.007t.omplower
  fake.c.008t.lower
  fake.c.011t.eh
  fake.c.012t.cfg
  fake.c.014i.visibility
  fake.c.015i.early_local_cleanups
  fake.c.016t.ssa
  # etc

The gimple code is converted into Static Single Assignment form,
with annotations for use when generating the debuginfo:

.. code-block:: console

  $ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;
    signed int _56;

  initial:
    stack_depth_3 = 0;
    # DEBUG stack_depth => stack_depth_3
    stack[stack_depth_3] = arg_5(D);
    stack_depth_7 = stack_depth_3 + 1;
    # DEBUG stack_depth => stack_depth_7
    # DEBUG instr0 => NULL
    # DEBUG /* DUP */ => NULL
    stack_depth_8 = stack_depth_7 + -1;
    # DEBUG stack_depth => stack_depth_8
    x_9 = stack[stack_depth_8];
    # DEBUG x => x_9
    stack[stack_depth_8] = x_9;
    stack_depth_11 = stack_depth_8 + 1;
    # DEBUG stack_depth => stack_depth_11
    stack[stack_depth_11] = x_9;
    stack_depth_13 = stack_depth_11 + 1;
    # DEBUG stack_depth => stack_depth_13
    # DEBUG instr1 => NULL
    # DEBUG /* PUSH_CONST */ => NULL
    stack[stack_depth_13] = 2;

    /* etc; edited for brevity */

We can perhaps better see the code by turning off
:c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to suppress all those ``DEBUG``
statements, giving:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;
    signed int _56;

  initial:
    stack_depth_3 = 0;
    stack[stack_depth_3] = arg_5(D);
    stack_depth_7 = stack_depth_3 + 1;
    stack_depth_8 = stack_depth_7 + -1;
    x_9 = stack[stack_depth_8];
    stack[stack_depth_8] = x_9;
    stack_depth_11 = stack_depth_8 + 1;
    stack[stack_depth_11] = x_9;
    stack_depth_13 = stack_depth_11 + 1;
    stack[stack_depth_13] = 2;
    stack_depth_15 = stack_depth_13 + 1;
    stack_depth_16 = stack_depth_15 + -1;
    y_17 = stack[stack_depth_16];
    stack_depth_18 = stack_depth_16 + -1;
    x_19 = stack[stack_depth_18];
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack[stack_depth_18] = _21;
    stack_depth_23 = stack_depth_18 + 1;
    stack_depth_24 = stack_depth_23 + -1;
    x_25 = stack[stack_depth_24];
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    stack_depth_26 = stack_depth_24 + -1;
    x_27 = stack[stack_depth_26];
    stack[stack_depth_26] = x_27;
    stack_depth_29 = stack_depth_26 + 1;
    stack[stack_depth_29] = x_27;
    stack_depth_31 = stack_depth_29 + 1;
    stack[stack_depth_31] = 1;
    stack_depth_33 = stack_depth_31 + 1;
    stack_depth_34 = stack_depth_33 + -1;
    y_35 = stack[stack_depth_34];
    stack_depth_36 = stack_depth_34 + -1;
    x_37 = stack[stack_depth_36];
    _38 = x_37 - y_35;
    stack[stack_depth_36] = _38;
    stack_depth_40 = stack_depth_36 + 1;
    stack_depth_41 = stack_depth_40 + -1;
    x_42 = stack[stack_depth_41];
    _44 = factorial (x_42);
    stack[stack_depth_41] = _44;
    stack_depth_46 = stack_depth_41 + 1;
    stack_depth_47 = stack_depth_46 + -1;
    y_48 = stack[stack_depth_47];
    stack_depth_49 = stack_depth_47 + -1;
    x_50 = stack[stack_depth_49];
    _51 = x_50 * y_48;
    stack[stack_depth_49] = _51;
    stack_depth_53 = stack_depth_49 + 1;

    # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
  instr9:
  /* RETURN */:
    stack_depth_54 = stack_depth_1 + -1;
    x_55 = stack[stack_depth_54];
    _56 = x_55;
    stack ={v} {CLOBBER};
    return _56;

  }

Note in the above how all the :c:type:`gcc_jit_block` instances we
created have been consolidated into just 3 blocks in GCC's internal
representation: ``initial``, ``instr4`` and ``instr9``.

Optimizing away stack manipulation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Recall our simple implementation of stack operations.  Let's examine
how the stack operations are optimized away.

After a pass of constant-propagation, the depth of the stack at each
opcode can be determined at compile-time:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack[0] = arg_5(D);
    x_9 = stack[0];
    stack[0] = x_9;
    stack[1] = x_9;
    stack[2] = 2;
    y_17 = stack[2];
    x_19 = stack[1];
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack[1] = _21;
    x_25 = stack[1];
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    x_27 = stack[0];
    stack[0] = x_27;
    stack[1] = x_27;
    stack[2] = 1;
    y_35 = stack[2];
    x_37 = stack[1];
    _38 = x_37 - y_35;
    stack[1] = _38;
    x_42 = stack[1];
    _44 = factorial (x_42);
    stack[1] = _44;
    y_48 = stack[1];
    x_50 = stack[0];
    _51 = x_50 * y_48;
    stack[0] = _51;

  instr9:
  /* RETURN */:
    x_55 = stack[0];
    x_56 = x_55;
    stack ={v} {CLOBBER};
    return x_56;

  }

Note how, in the above, all those ``stack_depth`` values are now just
constants: we're accessing specific stack locations at each opcode.

The "esra" pass ("Early Scalar Replacement of Aggregates") breaks
out our "stack" array into individual elements:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  Created a replacement for stack offset: 0, size: 32: stack$0
  Created a replacement for stack offset: 32, size: 32: stack$1
  Created a replacement for stack offset: 64, size: 32: stack$2

  Symbols to be put in SSA form
  { D.89 D.90 D.91 }
  Incremental SSA update started at block: 0
  Number of blocks in CFG: 5
  Number of blocks to update: 4 ( 80%)


  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack$0_45 = arg_5(D);
    x_9 = stack$0_45;
    stack$0_39 = x_9;
    stack$1_32 = x_9;
    stack$2_30 = 2;
    y_17 = stack$2_30;
    x_19 = stack$1_32;
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack$1_28 = _21;
    x_25 = stack$1_28;
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    x_27 = stack$0_39;
    stack$0_22 = x_27;
    stack$1_14 = x_27;
    stack$2_12 = 1;
    y_35 = stack$2_12;
    x_37 = stack$1_14;
    _38 = x_37 - y_35;
    stack$1_10 = _38;
    x_42 = stack$1_10;
    _44 = factorial (x_42);
    stack$1_6 = _44;
    y_48 = stack$1_6;
    x_50 = stack$0_22;
    _51 = x_50 * y_48;
    stack$0_1 = _51;

    # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
  instr9:
  /* RETURN */:
    x_55 = stack$0_52;
    x_56 = x_55;
    stack ={v} {CLOBBER};
    return x_56;

  }

Hence at this point, all those pushes and pops of the stack are now
simply assignments to specific temporary variables.

After some copy propagation, the stack manipulation has been completely
optimized away:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack$0_39 = arg_5(D);
    _20 = arg_5(D) <= 1;
    _21 = (signed int) _20;
    if (_21 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _38 = arg_5(D) + -1;
    _44 = factorial (_38);
    _51 = arg_5(D) * _44;
    stack$0_1 = _51;

    # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
  instr9:
  /* RETURN */:
    stack ={v} {CLOBBER};
    return stack$0_52;

  }

Later on, another pass finally eliminated ``stack_depth`` local and the
unused parts of the `stack`` array altogether:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  Released 44 names, 314.29%, removed 44 holes
  factorial (signed int arg)
  {
    signed int stack$0;
    signed int mult_acc_1;
    <unnamed type> _5;
    signed int _6;
    signed int _7;
    signed int mul_tmp_10;
    signed int mult_acc_11;
    signed int mult_acc_13;

    # arg_9 = PHI <arg_8(D)(0)>
    # mult_acc_13 = PHI <1(0)>
  initial:

    <bb 5>:
    # arg_4 = PHI <arg_9(2), _7(3)>
    # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
    _5 = arg_4 <= 1;
    _6 = (signed int) _5;
    if (_6 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _7 = arg_4 + -1;
    mult_acc_11 = mult_acc_1 * arg_4;
    goto <bb 5>;

    # stack$0_12 = PHI <arg_4(5)>
  instr9:
  /* RETURN */:
    mul_tmp_10 = mult_acc_1 * stack$0_12;
    return mul_tmp_10;

  }


Elimination of tail recursion
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another significant optimization is the detection that the call to
``factorial`` is tail recursion, which can be eliminated in favor of
an iteration:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)


  Symbols to be put in SSA form
  { D.88 }
  Incremental SSA update started at block: 0
  Number of blocks in CFG: 5
  Number of blocks to update: 4 ( 80%)


  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    signed int mult_acc_1;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int mul_tmp_44;
    signed int mult_acc_51;

    # arg_5 = PHI <arg_39(D)(0), _38(3)>
    # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
  initial:
    _20 = arg_5 <= 1;
    _21 = (signed int) _20;
    if (_21 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _38 = arg_5 + -1;
    mult_acc_51 = mult_acc_1 * arg_5;
    goto <bb 2> (initial);

    # stack$0_52 = PHI <arg_5(2)>
  instr9:
  /* RETURN */:
    stack ={v} {CLOBBER};
    mul_tmp_44 = mult_acc_1 * stack$0_52;
    return mul_tmp_44;

  }

---

### Gcc Jit Docs Intro Tutorial05 (`gcc/jit/docs/intro/tutorial05.rst`)

.. Copyright (C) 2015-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial part 5: Implementing an Ahead-of-Time compiler
-------------------------------------------------------

If you have a pre-existing language frontend that's compatible with
libgccjit's license, it's possible to hook it up to libgccjit as a
backend.  In the previous example we showed
how to do that for in-memory JIT-compilation, but libgccjit can also
compile code directly to a file, allowing you to implement a more
traditional ahead-of-time compiler ("JIT" is something of a misnomer
for this use-case).

The essential difference is to compile the context using
:c:func:`gcc_jit_context_compile_to_file` rather than
:c:func:`gcc_jit_context_compile`.

The "brainf" language
*********************

In this example we use libgccjit to construct an ahead-of-time compiler
for an esoteric programming language that we shall refer to as "brainf".

brainf scripts operate on an array of bytes, with a notional data pointer
within the array.

brainf is hard for humans to read, but it's trivial to write a parser for
it, as there is no lexing; just a stream of bytes.  The operations are:

.. list-table::
   :header-rows: 1

   * - Character
     - Meaning

   * - ``>``
     - ``idx += 1``
   * - ``<``
     - ``idx -= 1``
   * - ``+``
     - ``data[idx] += 1``
   * - ``-``
     - ``data[idx] -= 1``
   * - ``.``
     - ``output (data[idx])``
   * - ``,``
     - ``data[idx] = input ()``
   * - ``[``
     - loop until ``data[idx] == 0``
   * - ``]``
     - end of loop
   * - Anything else
     - ignored

Unlike the previous example, we'll implement an ahead-of-time compiler,
which reads ``.bf`` scripts and outputs executables (though it would
be trivial to have it run them JIT-compiled in-process).

Here's what a simple ``.bf`` script looks like:

   .. literalinclude:: ../examples/emit-alphabet.bf
    :lines: 1-

.. note::

   This example makes use of whitespace and comments for legibility, but
   could have been written as::

     ++++++++++++++++++++++++++
     >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
     [>.+<-]

   It's not a particularly useful language, except for providing
   compiler-writers with a test case that's easy to parse.  The point
   is that you can use :c:func:`gcc_jit_context_compile_to_file`
   to use libgccjit as a backend for a pre-existing language frontend
   (provided that the pre-existing frontend is compatible with libgccjit's
   license).

Converting a brainf script to libgccjit IR
******************************************

As before we write simple code to populate a :c:expr:`gcc_jit_context *`.

   .. literalinclude:: ../examples/tut05-bf.c
    :start-after: #define MAX_OPEN_PARENS 16
    :end-before: /* Entrypoint to the compiler.  */
    :language: c

Compiling a context to a file
*****************************

Unlike the previous tutorial, this time we'll compile the context
directly to an executable, using :c:func:`gcc_jit_context_compile_to_file`:

.. code-block:: c

    gcc_jit_context_compile_to_file (ctxt,
                                     GCC_JIT_OUTPUT_KIND_EXECUTABLE,
                                     output_file);

Here's the top-level of the compiler, which is what actually calls into
:c:func:`gcc_jit_context_compile_to_file`:

 .. literalinclude:: ../examples/tut05-bf.c
    :start-after: /* Entrypoint to the compiler.  */
    :end-before: /* Use the built compiler to compile the example to an executable:
    :language: c

Note how once the context is populated you could trivially instead compile
it to memory using :c:func:`gcc_jit_context_compile` and run it in-process
as in the previous tutorial.

To create an executable, we need to export a ``main`` function.  Here's
how to create one from the JIT API:

 .. literalinclude:: ../examples/tut05-bf.c
    :start-after: #include "libgccjit.h"
    :end-before: #define MAX_OPEN_PARENS 16
    :language: c

.. note::

   The above implementation ignores ``argc`` and ``argv``, but you could
   make use of them by exposing ``param_argc`` and ``param_argv`` to the
   caller.

Upon compiling this C code, we obtain a bf-to-machine-code compiler;
let's call it ``bfc``:

.. code-block:: console

  $ gcc \
      tut05-bf.c \
      -o bfc \
      -lgccjit

We can now use ``bfc`` to compile .bf files into machine code executables:

.. code-block:: console

  $ ./bfc \
       emit-alphabet.bf \
       a.out

which we can run directly:

.. code-block:: console

  $ ./a.out
  ABCDEFGHIJKLMNOPQRSTUVWXYZ

Success!

We can also inspect the generated executable using standard tools:

.. code-block:: console

  $ objdump -d a.out |less

which shows that libgccjit has managed to optimize the function
somewhat (for example, the runs of 26 and 65 increment operations
have become integer constants 0x1a and 0x41):

.. code-block:: console

  0000000000400620 <main>:
    400620:     80 3d 39 0a 20 00 00    cmpb   $0x0,0x200a39(%rip)        # 601060 <data
    400627:     74 07                   je     400630 <main
    400629:     eb fe                   jmp    400629 <main+0x9>
    40062b:     0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
    400630:     48 83 ec 08             sub    $0x8,%rsp
    400634:     0f b6 05 26 0a 20 00    movzbl 0x200a26(%rip),%eax        # 601061 <data_cells+0x1>
    40063b:     c6 05 1e 0a 20 00 1a    movb   $0x1a,0x200a1e(%rip)       # 601060 <data_cells>
    400642:     8d 78 41                lea    0x41(%rax),%edi
    400645:     40 88 3d 15 0a 20 00    mov    %dil,0x200a15(%rip)        # 601061 <data_cells+0x1>
    40064c:     0f 1f 40 00             nopl   0x0(%rax)
    400650:     40 0f b6 ff             movzbl %dil,%edi
    400654:     e8 87 fe ff ff          callq  4004e0 <putchar@plt>
    400659:     0f b6 05 01 0a 20 00    movzbl 0x200a01(%rip),%eax        # 601061 <data_cells+0x1>
    400660:     80 2d f9 09 20 00 01    subb   $0x1,0x2009f9(%rip)        # 601060 <data_cells>
    400667:     8d 78 01                lea    0x1(%rax),%edi
    40066a:     40 88 3d f0 09 20 00    mov    %dil,0x2009f0(%rip)        # 601061 <data_cells+0x1>
    400671:     75 dd                   jne    400650 <main+0x30>
    400673:     31 c0                   xor    %eax,%eax
    400675:     48 83 c4 08             add    $0x8,%rsp
    400679:     c3                      retq
    40067a:     66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

We also set up debugging information (via
:c:func:`gcc_jit_context_new_location` and
:c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO`), so it's possible to use ``gdb``
to singlestep through the generated binary and inspect the internal
state ``idx`` and ``data_cells``:

.. code-block:: console

  (gdb) break main
  Breakpoint 1 at 0x400790
  (gdb) run
  Starting program: a.out

  Breakpoint 1, 0x0000000000400790 in main (argc=1, argv=0x7fffffffe448)
  (gdb) stepi
  0x0000000000400797 in main (argc=1, argv=0x7fffffffe448)
  (gdb) stepi
  0x00000000004007a0 in main (argc=1, argv=0x7fffffffe448)
  (gdb) stepi
  9     >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
  (gdb) list
  4
  5     cell 0 = 26
  6     ++++++++++++++++++++++++++
  7
  8     cell 1 = 65
  9     >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
  10
  11    while cell#0 != 0
  12    [
  13     >
  (gdb) n
  6     ++++++++++++++++++++++++++
  (gdb) n
  9     >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
  (gdb) p idx
  $1 = 1
  (gdb) p data_cells
  $2 = "\032", '\000' <repeats 29998 times>
  (gdb) p data_cells[0]
  $3 = 26 '\032'
  (gdb) p data_cells[1]
  $4 = 0 '\000'
  (gdb) list
  4
  5     cell 0 = 26
  6     ++++++++++++++++++++++++++
  7
  8     cell 1 = 65
  9     >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<
  10
  11    while cell#0 != 0
  12    [
  13     >


Other forms of ahead-of-time-compilation
****************************************

The above demonstrates compiling a :c:expr:`gcc_jit_context *` directly
to an executable.  It's also possible to compile it to an object file,
and to a dynamic library.  See the documentation of
:c:func:`gcc_jit_context_compile_to_file` for more information.

---

### Gcc Jit Docs Topics Asm (`gcc/jit/docs/topics/asm.rst`)

.. Copyright (C) 2020-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Using Assembly Language with libgccjit
======================================

libgccjit has some support for directly embedding assembler instructions.
This is based on GCC's support for inline ``asm`` in C code, and the
following assumes a familiarity with that functionality.  See
`How to Use Inline Assembly Language in C Code <https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html>`_
in GCC's documentation, the "Extended Asm" section in particular.

These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test
for their presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS

Adding assembler instructions within a function
***********************************************

.. type:: gcc_jit_extended_asm

   A `gcc_jit_extended_asm` represents an extended ``asm`` statement: a
   series of low-level instructions inside a function that convert inputs
   to outputs.

   To avoid having an API entrypoint with a very large number of
   parameters, an extended ``asm`` statement is made in stages:
   an initial call to create the :type:`gcc_jit_extended_asm`,
   followed by calls to add operands and set other properties of the
   statement.

   There are two API entrypoints for creating a :type:`gcc_jit_extended_asm`:

   * :func:`gcc_jit_block_add_extended_asm` for an ``asm`` statement with
     no control flow, and

   * :func:`gcc_jit_block_end_with_extended_asm_goto` for an ``asm goto``.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: // Quote from here in docs/topics/asm.rst: example 1: C
      :end-before: // Quote up to here in docs/topics/asm.rst: example 1: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: /* Quote from here in docs/topics/asm.rst: example 1: jit.  */
      :end-before: /* Quote up to here in docs/topics/asm.rst: example 1: jit.  */
      :language: c

   .. warning::  When considering the numbering of operands within an
		 extended ``asm`` statement (e.g. the ``%0`` and ``%1``
		 above), the equivalent to the C syntax is followed i.e. all
		 output operands, then all input operands, regardless of
		 what order the calls to
		 :func:`gcc_jit_extended_asm_add_output_operand` and
		 :func:`gcc_jit_extended_asm_add_input_operand` were made in.

   As in the C syntax, operands can be given symbolic names to avoid having
   to number them.  For example, to create the equivalent of:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: // Quote from here in docs/topics/asm.rst: example 2: C
      :end-before: // Quote up to here in docs/topics/asm.rst: example 2: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: /* Quote from here in docs/topics/asm.rst: example 2: jit.  */
      :end-before: /* Quote up to here in docs/topics/asm.rst: example 2: jit.  */
      :language: c

.. function:: gcc_jit_extended_asm *\
              gcc_jit_block_add_extended_asm (gcc_jit_block *block,\
                                              gcc_jit_location *loc,\
                                              const char *asm_template)

   Create a :type:`gcc_jit_extended_asm` for an extended ``asm`` statement
   with no control flow (i.e. without the ``goto`` qualifier).

   The parameter ``asm_template`` corresponds to the `AssemblerTemplate`
   within C's extended ``asm`` syntax.  It must be non-NULL.  The call takes
   a copy of the underlying string, so it is valid to pass in a pointer to
   an on-stack buffer.

.. function:: gcc_jit_extended_asm *\
              gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,\
                                                        gcc_jit_location *loc,\
                                                        const char *asm_template,\
                                                        int num_goto_blocks,\
                                                        gcc_jit_block **goto_blocks,\
                                                        gcc_jit_block *fallthrough_block)

   Create a :type:`gcc_jit_extended_asm` for an extended ``asm`` statement
   that may perform jumps, and use it to terminate the given block.
   This is equivalent to the ``goto`` qualifier in C's extended ``asm``
   syntax.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: // Quote from here in docs/topics/asm.rst: example 3b: C
      :end-before: // Quote up to here in docs/topics/asm.rst: example 3b: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: /* Quote from here in docs/topics/asm.rst: example 3: jit.  */
      :end-before: /* Quote up to here in docs/topics/asm.rst: example 3: jit.  */
      :language: c

   here referencing a :type:`gcc_jit_block` named "carry".

   ``num_goto_blocks`` must be >= 0.

   ``goto_blocks`` must be non-NULL.  This corresponds to the ``GotoLabels``
   parameter within C's extended ``asm`` syntax.  The block names can be
   referenced within the assembler template.

   ``fallthrough_block`` can be NULL.  If non-NULL, it specifies the block
   to fall through to after the statement.

   .. note:: This is needed since each :type:`gcc_jit_block` must have a
	     single exit point, as a basic block: you can't jump from the
	     middle of a block.  A "goto" is implicitly added after the
	     asm to handle the fallthrough case, which is equivalent to what
	     would have happened in the C case.

.. function:: void\
              gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,\
                                                      int flag)

   Set whether the :type:`gcc_jit_extended_asm` has side-effects, equivalent to the
   `volatile <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile>`_
   qualifier in C's extended asm syntax.

   For example, to create the equivalent of:

   .. code-block:: c

      asm volatile ("rdtsc\n\t"    // Returns the time in EDX:EAX.
                     "shl $32, %%rdx\n\t"  // Shift the upper bits left.
                     "or %%rdx, %0"        // 'Or' in the lower bits.
                     : "=a" (msr)
                     :
                     : "rdx");

   the following API calls could be used:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: /* Quote from here in docs/topics/asm.rst: example 4: jit.  */
      :end-before: /* Quote up to here in docs/topics/asm.rst: example 4: jit.  */
      :language: c

   where the :type:`gcc_jit_extended_asm` is flagged as volatile.

.. function:: void\
              gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,\
                                                    int flag)

   Set the equivalent of the
   `inline <https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm>`_
   qualifier in C's extended ``asm`` syntax.

.. function:: void\
              gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,\
                                                       const char *asm_symbolic_name,\
                                                       const char *constraint,\
                                                       gcc_jit_lvalue *dest)

   Add an output operand to the extended ``asm`` statement.  See the
   `Output Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>`_
   section of the documentation of the C syntax.

   ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of C's
   extended ``asm`` syntax.  It can be NULL.  If non-NULL it specifies the
   symbolic name for the operand.

   ``constraint`` corresponds to the ``constraint`` component of C's extended
   ``asm`` syntax.  It must be non-NULL.

   ``dest`` corresponds to the ``cvariablename`` component of C's extended
   ``asm`` syntax.  It must be non-NULL.

   .. code-block:: c

      // Example with a NULL symbolic name, the equivalent of:
      //   : "=r" (dst)
      gcc_jit_extended_asm_add_output_operand (ext_asm, NULL, "=r", dst);

      // Example with a symbolic name ("aIndex"), the equivalent of:
      //   : [aIndex] "=r" (index)
      gcc_jit_extended_asm_add_output_operand (ext_asm, "aIndex", "=r", index);

   This function can't be called on an ``asm goto`` as such instructions can't
   have outputs; see the
   `Goto Labels <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels>`_
   section of GCC's "Extended Asm" documentation.

.. function:: void\
              gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,\
                                                      const char *asm_symbolic_name,\
                                                      const char *constraint,\
                                                      gcc_jit_rvalue *src)

   Add an input operand to the extended ``asm`` statement.  See the
   `Input Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands>`_
   section of the documentation of the C syntax.

   ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of C's
   extended ``asm`` syntax.  It can be NULL.  If non-NULL it specifies the
   symbolic name for the operand.

   ``constraint`` corresponds to the ``constraint`` component of C's extended
   ``asm`` syntax.  It must be non-NULL.

   ``src`` corresponds to the ``cexpression`` component of C's extended
   ``asm`` syntax.  It must be non-NULL.

   .. code-block:: c

      // Example with a NULL symbolic name, the equivalent of:
      //   : "r" (src)
      gcc_jit_extended_asm_add_input_operand (ext_asm, NULL, "r",
                                              gcc_jit_lvalue_as_rvalue (src));

      // Example with a symbolic name ("aMask"), the equivalent of:
      //   : [aMask] "r" (Mask)
      gcc_jit_extended_asm_add_input_operand (ext_asm, "aMask", "r",
                                              gcc_jit_lvalue_as_rvalue (mask));

.. function:: void\
              gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,\
                                                const char *victim)

   Add `victim` to the list of registers clobbered by the extended ``asm``
   statement.  It must be non-NULL.  See the
   `Clobbers and Scratch Registers <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#>`_
   section of the documentation of the C syntax.

   Statements with multiple clobbers will require multiple calls, one per
   clobber.

   For example:

   .. code-block:: c

     gcc_jit_extended_asm_add_clobber (ext_asm, "r0");
     gcc_jit_extended_asm_add_clobber (ext_asm, "cc");
     gcc_jit_extended_asm_add_clobber (ext_asm, "memory");

A :type:`gcc_jit_extended_asm` is a :type:`gcc_jit_object` "owned" by
the block's context.  The following upcast is available:

.. function:: gcc_jit_object *\
              gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)

   Upcast from extended ``asm`` to object.


Adding top-level assembler statements
*************************************

In addition to creating extended ``asm`` instructions within a function,
there is support for creating "top-level" assembler statements, outside
of any function.

.. function:: void \
              gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,\
                                                 gcc_jit_location *loc,\
                                                 const char *asm_stmts)

   Create a set of top-level asm statements, analogous to those created
   by GCC's "basic" ``asm`` syntax in C at file scope.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: // Quote from here in docs/topics/asm.rst: example 5: C
      :end-before: // Quote up to here in docs/topics/asm.rst: example 5: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../testsuite/jit.dg/test-asm.c
      :start-after: /* Quote from here in docs/topics/asm.rst: example 5: jit.  */
      :end-before: /* Quote up to here in docs/topics/asm.rst: example 5: jit.  */
      :language: c

---

### Gcc Jit Docs Topics Compatibility (`gcc/jit/docs/topics/compatibility.rst`)

.. Copyright (C) 2015-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

ABI and API compatibility
=========================

The libgccjit developers strive for ABI and API backward-compatibility:
programs built against libgccjit.so stand a good chance of running
without recompilation against newer versions of libgccjit.so, and
ought to recompile without modification against newer versions of
libgccjit.h.

.. note:: The libgccjit++.h C++ API is more experimental, and less
          locked-down at this time.

API compatibility is achieved by extending the API rather than changing
it.  For ABI compatibility, we avoid bumping the SONAME, and instead use
symbol versioning to tag each symbol, so that a binary linked against
libgccjit.so is tagged according to the symbols that it uses.

For example, :func:`gcc_jit_context_add_command_line_option` was added in
``LIBGCCJIT_ABI_1``.  If a client program uses it, this can be detected
from metadata by using ``objdump``:

.. code-block:: bash

   $ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8

   Version References:
     required from libgccjit.so.0:
       0x00824161 0x00 04 LIBGCCJIT_ABI_1
       0x00824160 0x00 03 LIBGCCJIT_ABI_0
     required from libc.so.6:

You can see the symbol tags provided by libgccjit.so using ``objdump``:

.. code-block:: bash

   $ objdump -p libgccjit.so | less
   [...snip...]
   Version definitions:
   1 0x01 0x0ff81f20 libgccjit.so.0
   2 0x00 0x00824160 LIBGCCJIT_ABI_0
   3 0x00 0x00824161 LIBGCCJIT_ABI_1
           LIBGCCJIT_ABI_0
   [...snip...]

Programmatically checking version
*********************************

Client code can programmatically check libgccjit version using:

.. function::  int gcc_jit_version_major (void)

   Return libgccjit major version.  This is analogous to __GNUC__ in C code.

.. function::  int gcc_jit_version_minor (void)

   Return libgccjit minor version.  This is analogous to
   __GNUC_MINOR__ in C code.

.. function::  int gcc_jit_version_patchlevel (void)

   Return libgccjit patchlevel version.  This is analogous to
   __GNUC_PATCHLEVEL__ in C code.

.. note:: These entry points has been added with ``LIBGCCJIT_ABI_13``
          (see below).

ABI symbol tags
***************

The initial release of libgccjit (in gcc 5.1) did not use symbol versioning.

Newer releases use the following tags.

.. _LIBGCCJIT_ABI_0:

``LIBGCCJIT_ABI_0``
-------------------

All entrypoints in the initial release of libgccjit are tagged with
``LIBGCCJIT_ABI_0``, to signify the transition to symbol versioning.

Binaries built against older copies of ``libgccjit.so`` should
continue to work, with this being handled transparently by the linker
(see `this post
<https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html>`_)

.. _LIBGCCJIT_ABI_1:

``LIBGCCJIT_ABI_1``
-------------------
``LIBGCCJIT_ABI_1`` covers the addition of
:func:`gcc_jit_context_add_command_line_option`

.. _LIBGCCJIT_ABI_2:

``LIBGCCJIT_ABI_2``
-------------------
``LIBGCCJIT_ABI_2`` covers the addition of
:func:`gcc_jit_context_set_bool_allow_unreachable_blocks`

.. _LIBGCCJIT_ABI_3:

``LIBGCCJIT_ABI_3``
-------------------
``LIBGCCJIT_ABI_3`` covers the addition of switch statements via API
entrypoints:

  * :func:`gcc_jit_block_end_with_switch`

  * :func:`gcc_jit_case_as_object`

  * :func:`gcc_jit_context_new_case`

.. _LIBGCCJIT_ABI_4:

``LIBGCCJIT_ABI_4``
-------------------
``LIBGCCJIT_ABI_4`` covers the addition of timers via API
entrypoints:

  * :func:`gcc_jit_context_get_timer`

  * :func:`gcc_jit_context_set_timer`

  * :func:`gcc_jit_timer_new`

  * :func:`gcc_jit_timer_release`

  * :func:`gcc_jit_timer_push`

  * :func:`gcc_jit_timer_pop`

  * :func:`gcc_jit_timer_print`

.. _LIBGCCJIT_ABI_5:

``LIBGCCJIT_ABI_5``
-------------------
``LIBGCCJIT_ABI_5`` covers the addition of
:func:`gcc_jit_context_set_bool_use_external_driver`

.. _LIBGCCJIT_ABI_6:

``LIBGCCJIT_ABI_6``
-------------------
``LIBGCCJIT_ABI_6`` covers the addition of
:func:`gcc_jit_rvalue_set_bool_require_tail_call`

.. _LIBGCCJIT_ABI_7:

``LIBGCCJIT_ABI_7``
-------------------
``LIBGCCJIT_ABI_7`` covers the addition of
:func:`gcc_jit_type_get_aligned`

.. _LIBGCCJIT_ABI_8:

``LIBGCCJIT_ABI_8``
-------------------
``LIBGCCJIT_ABI_8`` covers the addition of
:func:`gcc_jit_type_get_vector`

.. _LIBGCCJIT_ABI_9:

``LIBGCCJIT_ABI_9``
-------------------
``LIBGCCJIT_ABI_9`` covers the addition of
:func:`gcc_jit_function_get_address`

.. _LIBGCCJIT_ABI_10:

``LIBGCCJIT_ABI_10``
--------------------
``LIBGCCJIT_ABI_10`` covers the addition of
:func:`gcc_jit_context_new_rvalue_from_vector`

.. _LIBGCCJIT_ABI_11:

``LIBGCCJIT_ABI_11``
--------------------
``LIBGCCJIT_ABI_11`` covers the addition of
:func:`gcc_jit_context_add_driver_option`

.. _LIBGCCJIT_ABI_12:

``LIBGCCJIT_ABI_12``
--------------------
``LIBGCCJIT_ABI_12`` covers the addition of
:func:`gcc_jit_context_new_bitfield`

.. _LIBGCCJIT_ABI_13:

``LIBGCCJIT_ABI_13``
--------------------
``LIBGCCJIT_ABI_13`` covers the addition of version functions via API
entrypoints:

  * :func:`gcc_jit_version_major`

  * :func:`gcc_jit_version_minor`

  * :func:`gcc_jit_version_patchlevel`

.. _LIBGCCJIT_ABI_14:

``LIBGCCJIT_ABI_14``
--------------------
``LIBGCCJIT_ABI_14`` covers the addition of
:func:`gcc_jit_global_set_initializer`

.. _LIBGCCJIT_ABI_15:

``LIBGCCJIT_ABI_15``
--------------------
``LIBGCCJIT_ABI_15`` covers the addition of API entrypoints for directly
embedding assembler instructions:

  * :func:`gcc_jit_block_add_extended_asm`
  * :func:`gcc_jit_block_end_with_extended_asm_goto`
  * :func:`gcc_jit_extended_asm_as_object`
  * :func:`gcc_jit_extended_asm_set_volatile_flag`
  * :func:`gcc_jit_extended_asm_set_inline_flag`
  * :func:`gcc_jit_extended_asm_add_output_operand`
  * :func:`gcc_jit_extended_asm_add_input_operand`
  * :func:`gcc_jit_extended_asm_add_clobber`
  * :func:`gcc_jit_context_add_top_level_asm`

.. _LIBGCCJIT_ABI_16:

``LIBGCCJIT_ABI_16``
--------------------
``LIBGCCJIT_ABI_16`` covers the addition of reflection functions via API
entrypoints:

  * :func:`gcc_jit_function_get_return_type`

  * :func:`gcc_jit_function_get_param_count`

  * :func:`gcc_jit_type_dyncast_array`

  * :func:`gcc_jit_type_is_bool`

  * :func:`gcc_jit_type_is_integral`

  * :func:`gcc_jit_type_is_pointer`

  * :func:`gcc_jit_type_is_struct`

  * :func:`gcc_jit_type_dyncast_vector`

  * :func:`gcc_jit_type_unqualified`

  * :func:`gcc_jit_type_dyncast_function_ptr_type`

  * :func:`gcc_jit_function_type_get_return_type`

  * :func:`gcc_jit_function_type_get_param_count`

  * :func:`gcc_jit_function_type_get_param_type`

  * :func:`gcc_jit_vector_type_get_num_units`

  * :func:`gcc_jit_vector_type_get_element_type`

  * :func:`gcc_jit_struct_get_field`

  * :func:`gcc_jit_struct_get_field_count`

.. _LIBGCCJIT_ABI_17:

``LIBGCCJIT_ABI_17``
-----------------------
``LIBGCCJIT_ABI_17`` covers the addition of an API entrypoint to set the
thread-local storage model of a variable:

  * :func:`gcc_jit_lvalue_set_tls_model`

.. _LIBGCCJIT_ABI_18:

``LIBGCCJIT_ABI_18``
-----------------------
``LIBGCCJIT_ABI_18`` covers the addition of an API entrypoint to set the link
section of a variable:

  * :func:`gcc_jit_lvalue_set_link_section`

.. _LIBGCCJIT_ABI_19:

``LIBGCCJIT_ABI_19``
-----------------------
``LIBGCCJIT_ABI_19`` covers the addition of API entrypoints to set the initial value
of a global with an rvalue and to use constructors:

  * :func:`gcc_jit_context_new_array_constructor`
  * :func:`gcc_jit_context_new_struct_constructor`
  * :func:`gcc_jit_context_new_union_constructor`
  * :func:`gcc_jit_global_set_initializer_rvalue`

.. _LIBGCCJIT_ABI_20:

``LIBGCCJIT_ABI_20``
-----------------------
``LIBGCCJIT_ABI_20`` covers the addition of sized integer types, including
128-bit integers and helper functions for types:

  * :func:`gcc_jit_compatible_types`
  * :func:`gcc_jit_type_get_size`
  * :c:macro:`GCC_JIT_TYPE_UINT8_T`
  * :c:macro:`GCC_JIT_TYPE_UINT16_T`
  * :c:macro:`GCC_JIT_TYPE_UINT32_T`
  * :c:macro:`GCC_JIT_TYPE_UINT64_T`
  * :c:macro:`GCC_JIT_TYPE_UINT128_T`
  * :c:macro:`GCC_JIT_TYPE_INT8_T`
  * :c:macro:`GCC_JIT_TYPE_INT16_T`
  * :c:macro:`GCC_JIT_TYPE_INT32_T`
  * :c:macro:`GCC_JIT_TYPE_INT64_T`
  * :c:macro:`GCC_JIT_TYPE_INT128_T`

.. _LIBGCCJIT_ABI_21:

``LIBGCCJIT_ABI_21``
--------------------
``LIBGCCJIT_ABI_21`` covers the addition of an API entrypoint to bitcast a
value from one type to another:

  * :func:`gcc_jit_context_new_bitcast`

.. _LIBGCCJIT_ABI_22:

``LIBGCCJIT_ABI_22``
--------------------
``LIBGCCJIT_ABI_22`` covers the addition of an API entrypoint to set the
register name of a variable:

  * :func:`gcc_jit_lvalue_set_register_name`

.. _LIBGCCJIT_ABI_23:

``LIBGCCJIT_ABI_23``
--------------------
``LIBGCCJIT_ABI_23`` covers the addition of an API entrypoint to hide stderr
logs:

  * :func:`gcc_jit_context_set_bool_print_errors_to_stderr`

.. _LIBGCCJIT_ABI_24:

``LIBGCCJIT_ABI_24``
--------------------
``LIBGCCJIT_ABI_24`` covers the addition of functions to get and set the
alignment of a variable:

  * :func:`gcc_jit_lvalue_set_alignment`
  * :func:`gcc_jit_lvalue_get_alignment`

.. _LIBGCCJIT_ABI_25:

``LIBGCCJIT_ABI_25``
--------------------
``LIBGCCJIT_ABI_25`` covers the addition of
:func:`gcc_jit_type_get_restrict`

.. _LIBGCCJIT_ABI_26:

``LIBGCCJIT_ABI_26``
--------------------
``LIBGCCJIT_ABI_26`` covers the addition of functions to set attributes
on functions and variables:

  * :func:`gcc_jit_function_add_attribute`
  * :func:`gcc_jit_function_add_string_attribute`
  * :func:`gcc_jit_function_add_integer_array_attribute`
  * :func:`gcc_jit_lvalue_add_string_attribute`

.. _LIBGCCJIT_ABI_27:

``LIBGCCJIT_ABI_27``
--------------------
``LIBGCCJIT_ABI_27`` covers the addition of
:func:`gcc_jit_context_new_sizeof`

.. _LIBGCCJIT_ABI_28:

``LIBGCCJIT_ABI_28``
--------------------
``LIBGCCJIT_ABI_28`` covers the addition of
:func:`gcc_jit_context_new_alignof`

.. _LIBGCCJIT_ABI_29:

``LIBGCCJIT_ABI_29``
--------------------
``LIBGCCJIT_ABI_29`` covers the addition of
:func:`gcc_jit_global_set_readonly`

.. _LIBGCCJIT_ABI_30:

``LIBGCCJIT_ABI_30``
--------------------
``LIBGCCJIT_ABI_30`` covers the addition of
:func:`gcc_jit_context_convert_vector`

.. _LIBGCCJIT_ABI_31:

``LIBGCCJIT_ABI_31``
--------------------
``LIBGCCJIT_ABI_31`` covers the addition of functions to manipulate vectors:

  * :func:`gcc_jit_context_new_rvalue_vector_perm`
  * :func:`gcc_jit_context_new_vector_access`

.. _LIBGCCJIT_ABI_32:

``LIBGCCJIT_ABI_32``
--------------------

``LIBGCCJIT_ABI_32`` covers the addition of a function to get target builtins:

  * :func:`gcc_jit_context_get_target_builtin_function`

.. _LIBGCCJIT_ABI_33:

``LIBGCCJIT_ABI_33``
--------------------
``LIBGCCJIT_ABI_33`` covers the addition of a function to create a new
temporary variable:

  * :func:`gcc_jit_function_new_temp`

.. _LIBGCCJIT_ABI_34:

``LIBGCCJIT_ABI_34``
--------------------
``LIBGCCJIT_ABI_34`` covers the addition of

 * :func:`gcc_jit_context_set_output_ident`

.. _LIBGCCJIT_ABI_35:

``LIBGCCJIT_ABI_35``
--------------------
``LIBGCCJIT_ABI_35`` covers the addition of functions to query the target
information:

  * :func:`gcc_jit_context_get_target_info`
  * :func:`gcc_jit_target_info_release`
  * :func:`gcc_jit_target_info_cpu_supports`
  * :func:`gcc_jit_target_info_arch`
  * :func:`gcc_jit_target_info_supports_target_dependent_type`

.. _LIBGCCJIT_ABI_36:

``LIBGCCJIT_ABI_36``
--------------------
``LIBGCCJIT_ABI_36`` covers the addition of

 * :func:`gcc_jit_context_set_abort_on_unsupported_target_builtin`

.. _LIBGCCJIT_ABI_37:

``LIBGCCJIT_ABI_37``
--------------------
``LIBGCCJIT_ABI_37`` covers the addition of
:func:`gcc_jit_context_new_array_type_u64`

.. _LIBGCCJIT_ABI_38:

``LIBGCCJIT_ABI_38``
--------------------
``LIBGCCJIT_ABI_38`` covers the addition of

 * :func:`gcc_jit_type_is_floating_point`

---

### Gcc Jit Docs Topics Compilation (`gcc/jit/docs/topics/compilation.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Compiling a context
===================

Once populated, a :c:expr:`gcc_jit_context *` can be compiled to
machine code, either in-memory via :c:func:`gcc_jit_context_compile` or
to disk via :c:func:`gcc_jit_context_compile_to_file`.

You can compile a context multiple times (using either form of
compilation), although any errors that occur on the context will
prevent any future compilation of that context.

In-memory compilation
*********************

.. function:: gcc_jit_result *\
              gcc_jit_context_compile (gcc_jit_context *ctxt)

   This calls into GCC and builds the code, returning a
   `gcc_jit_result *`.

   If the result is non-NULL, the caller becomes responsible for
   calling :func:`gcc_jit_result_release` on it once they're done
   with it.

.. type:: gcc_jit_result

  A `gcc_jit_result` encapsulates the result of compiling a context
  in-memory, and the lifetimes of any machine code functions or globals
  that are within the result.

.. function:: void *\
              gcc_jit_result_get_code (gcc_jit_result *result,\
                                       const char *funcname)

   Locate a given function within the built machine code.

   Functions are looked up by name.  For this to succeed, a function
   with a name matching `funcname` must have been created on
   `result`'s context (or a parent context) via a call to
   :func:`gcc_jit_context_new_function` with `kind`
   :macro:`GCC_JIT_FUNCTION_EXPORTED`:

   .. code-block:: c

     gcc_jit_context_new_function (ctxt,
                                   any_location, /* or NULL */
                                   /* Required for func to be visible to
                                      gcc_jit_result_get_code: */
                                   GCC_JIT_FUNCTION_EXPORTED,
                                   any_return_type,
                                   /* Must string-compare equal: */
                                   funcname,
                                   /* etc */);

   If such a function is not found (or `result` or `funcname` are
   ``NULL``), an error message will be emitted on stderr and
   ``NULL`` will be returned.

   If the function is found, the result will need to be cast to a
   function pointer of the correct type before it can be called.

   Note that the resulting machine code becomes invalid after
   :func:`gcc_jit_result_release` is called on the
   :expr:`gcc_jit_result *`; attempting to call it after that may lead
   to a segmentation fault.

.. function:: void *\
              gcc_jit_result_get_global (gcc_jit_result *result,\
                                         const char *name)

   Locate a given global within the built machine code.

   Globals are looked up by name.  For this to succeed, a global
   with a name matching `name` must have been created on
   `result`'s context (or a parent context) via a call to
   :func:`gcc_jit_context_new_global` with `kind`
   :macro:`GCC_JIT_GLOBAL_EXPORTED`.

   If the global is found, the result will need to be cast to a
   pointer of the correct type before it can be called.

   This is a *pointer* to the global, so e.g. for an :expr:`int` this is
   an :expr:`int *`.

   For example, given an ``int foo;`` created this way:

   .. code-block:: c

     gcc_jit_lvalue *exported_global =
       gcc_jit_context_new_global (ctxt,
       any_location, /* or NULL */
       GCC_JIT_GLOBAL_EXPORTED,
       int_type,
       "foo");

   we can access it like this:

   .. code-block:: c

      int *ptr_to_foo =
        (int *)gcc_jit_result_get_global (result, "foo");

   If such a global is not found (or `result` or `name` are
   ``NULL``), an error message will be emitted on stderr and
   ``NULL`` will be returned.

   Note that the resulting address becomes invalid after
   :func:`gcc_jit_result_release` is called on the
   :expr:`gcc_jit_result *`; attempting to use it after that may lead
   to a segmentation fault.

.. function:: void\
              gcc_jit_result_release (gcc_jit_result *result)

   Once we're done with the code, this unloads the built .so file.
   This cleans up the result; after calling this, it's no longer
   valid to use the result, or any code or globals that were obtained
   by calling :func:`gcc_jit_result_get_code` or
   :func:`gcc_jit_result_get_global` on it.


Ahead-of-time compilation
*************************

Although libgccjit is primarily aimed at just-in-time compilation, it
can also be used for implementing more traditional ahead-of-time
compilers, via the :c:func:`gcc_jit_context_compile_to_file`
API entrypoint.

For linking in object files, use :c:func:`gcc_jit_context_add_driver_option`.

.. function:: void \
              gcc_jit_context_compile_to_file (gcc_jit_context *ctxt, \
                                               enum gcc_jit_output_kind output_kind,\
                                               const char *output_path)

   Compile the :c:expr:`gcc_jit_context *` to a file of the given
   kind.

:c:func:`gcc_jit_context_compile_to_file` ignores the suffix of
``output_path``, and insteads uses the given
:c:enum:`gcc_jit_output_kind` to decide what to do.

.. note::

   This is different from the ``gcc`` program, which does make use of the
   suffix of the output file when determining what to do.

.. enum:: gcc_jit_output_kind

The available kinds of output are:

.. list-table::
   :header-rows: 1

   * - Output kind
     - Typical suffix

   * - :c:macro:`GCC_JIT_OUTPUT_KIND_ASSEMBLER`
     - .s
   * - :c:macro:`GCC_JIT_OUTPUT_KIND_OBJECT_FILE`
     - .o
   * - :c:macro:`GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY`
     - .so or .dll
   * - :c:macro:`GCC_JIT_OUTPUT_KIND_EXECUTABLE`
     - None, or .exe

.. c:macro:: GCC_JIT_OUTPUT_KIND_ASSEMBLER

   Compile the context to an assembler file.

.. c:macro:: GCC_JIT_OUTPUT_KIND_OBJECT_FILE

   Compile the context to an object file.

.. c:macro:: GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY

   Compile the context to a dynamic library.

.. c:macro:: GCC_JIT_OUTPUT_KIND_EXECUTABLE

   Compile the context to an executable.

Getting information about a target
**********************************

You can query the target information by using the following API:

.. function:: gcc_jit_target_info * \
              gcc_jit_context_get_target_info (gcc_jit_context *ctxt)

   Compute the information about a target.

   If the result is non-NULL, the caller becomes responsible for
   calling :func:`gcc_jit_target_info_release` on it once they're done
   with it.

.. function:: void \
              gcc_jit_target_info_release (gcc_jit_target_info *info)

   This function releases all resources associated with the given target info.

.. function:: int \
              gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
                                                const char *feature)

   Check if the specified target INFO supports the cpu FEATURE.

.. function:: const char * \
              gcc_jit_target_info_arch (gcc_jit_target_info *info)

   Get the architecture of the currently running CPU, e.g. the value of -march
   equivalent to -march=native. Ex.: znver3

   The underlying buffer is only valid until the gcc_jit_target_info is
   released.

.. function:: int \
              gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info,
                                                                  enum gcc_jit_types type)

   Check if the specified target INFO supports target-dependent types like
   128-bit integers.

   The API entrypoints relating to the target info:

      * :c:func:`gcc_jit_context_get_target_info`
      * :c:func:`gcc_jit_target_info_release`
      * :c:func:`gcc_jit_target_info_cpu_supports`
      * :c:func:`gcc_jit_target_info_arch`
      * :c:func:`gcc_jit_target_info_supports_target_dependent_type`

   were added in :ref:`LIBGCCJIT_ABI_35`; you can test for their presence
   using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API

---

### Gcc Jit Docs Topics Contexts (`gcc/jit/docs/topics/contexts.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Compilation contexts
====================

.. type:: gcc_jit_context

The top-level of the API is the :c:type:`gcc_jit_context` type.

A :c:type:`gcc_jit_context` instance encapsulates the state of a
compilation.

You can set up options on it, and add types, functions and code.
Invoking :c:func:`gcc_jit_context_compile` on it gives you a
:c:type:`gcc_jit_result`.

Lifetime-management
-------------------
Contexts are the unit of lifetime-management within the API: objects
have their lifetime bounded by the context they are created within, and
cleanup of such objects is done for you when the context is released.

.. function:: gcc_jit_context *gcc_jit_context_acquire (void)

  This function acquires a new :c:expr:`gcc_jit_context *` instance,
  which is independent of any others that may be present within this
  process.

.. function:: void gcc_jit_context_release (gcc_jit_context *ctxt)

  This function releases all resources associated with the given context.
  Both the context itself and all of its :c:expr:`gcc_jit_object *`
  instances are cleaned up.  It should be called exactly once on a given
  context.

  It is invalid to use the context or any of its "contextual" objects
  after calling this.

  .. code-block:: c

    gcc_jit_context_release (ctxt);

.. function:: gcc_jit_context * gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)

   Given an existing JIT context, create a child context.

   The child inherits a copy of all option-settings from the parent.

   The child can reference objects created within the parent, but not
   vice-versa.

   The lifetime of the child context must be bounded by that of the
   parent: you should release a child context before releasing the parent
   context.

   If you use a function from a parent context within a child context,
   you have to compile the parent context before you can compile the
   child context, and the gcc_jit_result of the parent context must
   outlive the gcc_jit_result of the child context.

   This allows caching of shared initializations.  For example, you could
   create types and declarations of global functions in a parent context
   once within a process, and then create child contexts whenever a
   function or loop becomes hot. Each such child context can be used for
   JIT-compiling just one function or loop, but can reference types
   and helper functions created within the parent context.

   Contexts can be arbitrarily nested, provided the above rules are
   followed, but it's probably not worth going above 2 or 3 levels, and
   there will likely be a performance hit for such nesting.


Thread-safety
-------------
Instances of :c:expr:`gcc_jit_context *` created via
:c:func:`gcc_jit_context_acquire` are independent from each other:
only one thread may use a given context at once, but multiple threads
could each have their own contexts without needing locks.

Contexts created via :c:func:`gcc_jit_context_new_child_context` are
related to their parent context.  They can be partitioned by their
ultimate ancestor into independent "family trees".   Only one thread
within a process may use a given "family tree" of such contexts at once,
and if you're using multiple threads you should provide your own locking
around entire such context partitions.

.. _error-handling:

Error-handling
--------------
Various kinds of errors are possible when using the API, such as
mismatched types in an assignment.  You can only compile and get code from
a context if no errors occur.

Errors are printed on stderr and can be queried using
:c:func:`gcc_jit_context_get_first_error`.

They typically contain the name of the API entrypoint where the error
occurred, and pertinent information on the problem:

.. code-block:: console

  ./buggy-program: error: gcc_jit_block_add_assignment: mismatching types: assignment to i (type: int) from "hello world" (type: const char *)

In general, if an error occurs when using an API entrypoint, the
entrypoint returns NULL.  You don't have to check everywhere for NULL
results, since the API handles a NULL being passed in for any
argument by issuing another error.  This typically leads to a cascade of
followup error messages, but is safe (albeit verbose).  The first error
message is usually the one to pay attention to, since it is likely to
be responsible for all of the rest:

.. function:: const char *\
              gcc_jit_context_get_first_error (gcc_jit_context *ctxt)

   Returns the first error message that occurred on the context.

   The returned string is valid for the rest of the lifetime of the
   context.

   If no errors occurred, this will be NULL.

If you are wrapping the C API for a higher-level language that supports
exception-handling, you may instead be interested in the last error that
occurred on the context, so that you can embed this in an exception:

.. function:: const char *\
              gcc_jit_context_get_last_error (gcc_jit_context *ctxt)

   Returns the last error message that occurred on the context.

   If no errors occurred, this will be NULL.

   If non-NULL, the returned string is only guaranteed to be valid until
   the next call to libgccjit relating to this context.

Debugging
---------

.. function:: void\
              gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,\
                                            const char *path,\
                                            int update_locations)

   To help with debugging: dump a C-like representation to the given path,
   describing what's been set up on the context.

   If "update_locations" is true, then also set up :type:`gcc_jit_location`
   information throughout the context, pointing at the dump file as if it
   were a source file.  This may be of use in conjunction with
   :macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to allow stepping through the
   code in a debugger.

.. function:: void\
              gcc_jit_context_set_logfile (gcc_jit_context *ctxt,\
                                           FILE *logfile,\
                                           int flags,\
                                           int verbosity)

   To help with debugging; enable ongoing logging of the context's
   activity to the given file.

   For example, the following will enable logging to stderr.

   .. code-block:: c

      gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);

   Examples of information logged include:

   * API calls

   * the various steps involved within compilation

   * activity on any :c:type:`gcc_jit_result` instances created by
     the context

   * activity within any child contexts

   An example of a log can be seen :ref:`here <example-of-log-file>`,
   though the precise format and kinds of information logged is subject
   to change.

   The caller remains responsible for closing `logfile`, and it must not
   be closed until all users are released.  In particular, note that
   child contexts and :c:type:`gcc_jit_result` instances created by
   the context will use the logfile.

   There may a performance cost for logging.

   You can turn off logging on `ctxt` by passing `NULL` for `logfile`.
   Doing so only affects the context; it does not affect child contexts
   or :c:type:`gcc_jit_result` instances already created by
   the context.

   The parameters "flags" and "verbosity" are reserved for future
   expansion, and must be zero for now.

To contrast the above: :c:func:`gcc_jit_context_dump_to_file` dumps the
current state of a context to the given path, whereas
:c:func:`gcc_jit_context_set_logfile` enables on-going logging of
future activities on a context to the given `FILE *`.


.. function:: void\
              gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,\
                                                       const char *path)

   Write C source code into `path` that can be compiled into a
   self-contained executable (i.e. with libgccjit as the only dependency).
   The generated code will attempt to replay the API calls that have been
   made into the given context.

   This may be useful when debugging the library or client code, for
   reducing a complicated recipe for reproducing a bug into a simpler
   form.  For example, consider client code that parses some source file
   into some internal representation, and then walks this IR, calling into
   libgccjit.  If this encounters a bug, a call to
   `gcc_jit_context_dump_reproducer_to_file` will write out C code for
   a much simpler executable that performs the equivalent calls into
   libgccjit, without needing the client code and its data.

   Typically you need to supply :option:`-Wno-unused-variable` when
   compiling the generated file (since the result of each API call is
   assigned to a unique variable within the generated C source, and not
   all are necessarily then used).

.. function:: void\
              gcc_jit_context_enable_dump (gcc_jit_context *ctxt,\
                                           const char *dumpname, \
                                           char **out_ptr)

   Enable the dumping of a specific set of internal state from the
   compilation, capturing the result in-memory as a buffer.

   Parameter "dumpname" corresponds to the equivalent gcc command-line
   option, without the "-fdump-" prefix.
   For example, to get the equivalent of :option:`-fdump-tree-vrp1`,
   supply ``"tree-vrp1"``:

   .. code-block:: c

      static char *dump_vrp1;

      void
      create_code (gcc_jit_context *ctxt)
      {
         gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
         /* (other API calls omitted for brevity) */
      }

   The context directly stores the dumpname as a ``(const char *)``, so
   the passed string must outlive the context.

   :func:`gcc_jit_context_compile` will capture the dump as a
   dynamically-allocated buffer, writing it to ``*out_ptr``.

   The caller becomes responsible for calling:

   .. code-block:: c

      free (*out_ptr)

   each time that :func:`gcc_jit_context_compile` is called.
   ``*out_ptr`` will be written to, either with the address of a buffer,
   or with ``NULL`` if an error occurred.

   .. warning::

      This API entrypoint is likely to be less stable than the others.
      In particular, both the precise dumpnames, and the format and content
      of the dumps are subject to change.

      It exists primarily for writing the library's own test suite.

Options
-------

Options present in the initial release of libgccjit were handled using
enums, whereas those added subsequently have their own per-option API
entrypoints.

Adding entrypoints for each new option means that client code that use
the new options can be identified directly from binary metadata, which
would not be possible if we instead extended the various
``enum gcc_jit_*_option``.

String Options
**************

.. function:: void gcc_jit_context_set_str_option(gcc_jit_context *ctxt, \
                                                  enum gcc_jit_str_option opt, \
                                                  const char *value)

   Set a string option of the context.

   .. enum:: gcc_jit_str_option

   The parameter ``value`` can be NULL.   If non-NULL, the call takes a
   copy of the underlying string, so it is valid to pass in a pointer to
   an on-stack buffer.

   .. macro:: GCC_JIT_STR_OPTION_PROGNAME

      The name of the program, for use as a prefix when printing error
      messages to stderr.  If `NULL`, or default, "libgccjit.so" is used.

  .. macro:: GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES

      Alphabetic ASCII characters and underscores are always valid. Numeric
      ASCII characters are always valid after the initial character of the
      string. Use this entrypoint to specify additional ASCII characters that
      are valid throughout function names (ex.: ".$").

Boolean options
***************

.. function:: void gcc_jit_context_set_bool_option(gcc_jit_context *ctxt, \
				                   enum gcc_jit_bool_option opt, \
				                   int value)

  Set a boolean option of the context.
  Zero is "false" (the default), non-zero is "true".

  .. enum:: gcc_jit_bool_option

  .. macro:: GCC_JIT_BOOL_OPTION_DEBUGINFO

     If true, :func:`gcc_jit_context_compile` will attempt to do the right
     thing so that if you attach a debugger to the process, it will
     be able to inspect variables and step through your code.

     Note that you can't step through code unless you set up source
     location information for the code (by creating and passing in
     :type:`gcc_jit_location` instances).

  .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE

     If true, :func:`gcc_jit_context_compile` will dump its initial
     "tree" representation of your code to stderr (before any
     optimizations).

     Here's some sample output (from the `square` example)::

        <statement_list 0x7f4875a62cc0
           type <void_type 0x7f4875a64bd0 VOID
               align 8 symtab 0 alias set -1 canonical type 0x7f4875a64bd0
               pointer_to_this <pointer_type 0x7f4875a64c78>>
           side-effects head 0x7f4875a761e0 tail 0x7f4875a761f8 stmts 0x7f4875a62d20 0x7f4875a62d00

           stmt <label_expr 0x7f4875a62d20 type <void_type 0x7f4875a64bd0>
               side-effects
               arg 0 <label_decl 0x7f4875a79080 entry type <void_type 0x7f4875a64bd0>
                   VOID file (null) line 0 col 0
                   align 1 context <function_decl 0x7f4875a77500 square>>>
           stmt <return_expr 0x7f4875a62d00
               type <integer_type 0x7f4875a645e8 public SI
                   size <integer_cst 0x7f4875a623a0 constant 32>
                   unit size <integer_cst 0x7f4875a623c0 constant 4>
                   align 32 symtab 0 alias set -1 canonical type 0x7f4875a645e8 precision 32 min <integer_cst 0x7f4875a62340 -2147483648> max <integer_cst 0x7f4875a62360 2147483647>
                   pointer_to_this <pointer_type 0x7f4875a6b348>>
               side-effects
               arg 0 <modify_expr 0x7f4875a72a78 type <integer_type 0x7f4875a645e8>
                   side-effects arg 0 <result_decl 0x7f4875a7a000 D.54>
                   arg 1 <mult_expr 0x7f4875a72a50 type <integer_type 0x7f4875a645e8>
                       arg 0 <parm_decl 0x7f4875a79000 i> arg 1 <parm_decl 0x7f4875a79000 i>>>>>

  .. macro:: GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE

     If true, :func:`gcc_jit_context_compile` will dump the "gimple"
     representation of your code to stderr, before any optimizations
     are performed.  The dump resembles C code:

     .. code-block:: c

       square (signed int i)
       {
         signed int D.56;

         entry:
         D.56 = i * i;
         return D.56;
       }

  .. macro:: GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE

     If true, :func:`gcc_jit_context_compile` will dump the final
     generated code to stderr, in the form of assembly language:

     .. code-block:: gas

           .file    "fake.c"
           .text
           .globl    square
           .type    square, @function
       square:
       .LFB0:
           .cfi_startproc
           pushq    %rbp
           .cfi_def_cfa_offset 16
           .cfi_offset 6, -16
           movq    %rsp, %rbp
           .cfi_def_cfa_register 6
           movl    %edi, -4(%rbp)
       .L2:
           movl    -4(%rbp), %eax
           imull    -4(%rbp), %eax
           popq    %rbp
           .cfi_def_cfa 7, 8
           ret
           .cfi_endproc
       .LFE0:
           .size    square, .-square
           .ident    "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
           .section    .note.GNU-stack,"",@progbits


  .. macro:: GCC_JIT_BOOL_OPTION_DUMP_SUMMARY

     If true, :func:`gcc_jit_context_compile` will print information to stderr
     on the actions it is performing.

  .. macro:: GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING

     If true, :func:`gcc_jit_context_compile` will dump copious
     amount of information on what it's doing to various
     files within a temporary directory.  Use
     :macro:`GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES` (see below) to
     see the results.  The files are intended to be human-readable,
     but the exact files and their formats are subject to change.

  .. macro:: GCC_JIT_BOOL_OPTION_SELFCHECK_GC

     If true, libgccjit will aggressively run its garbage collector, to
     shake out bugs (greatly slowing down the compile).  This is likely
     to only be of interest to developers *of* the library.  It is
     used when running the selftest suite.

  .. macro:: GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES

     If true, the :type:`gcc_jit_context` will not clean up intermediate files
     written to the filesystem, and will display their location on stderr.

.. function:: void \
              gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt, \
                                                                 int bool_value)

   By default, libgccjit will issue an error about unreachable blocks
   within a function.

   This entrypoint can be used to disable that error.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_2`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks

.. function:: void \
              gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt, \
                                                            int bool_value)

   libgccjit internally generates assembler, and uses "driver" code
   for converting it to other formats (e.g. shared libraries).

   By default, libgccjit will use an embedded copy of the driver
   code.

   This option can be used to instead invoke an external driver executable
   as a subprocess.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_5`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver

.. function:: void \
              gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context *ctxt, \
                                                                 int enabled)

   By default, libgccjit will print errors to stderr.

   This entrypoint can be used to disable the printing.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_23`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr

.. function:: void \
              gcc_jit_context_set_abort_on_unsupported_target_builtin (gcc_jit_context *ctxt)

   By default, libgccjit will silently ignore when a target builtin has an
   unsupported type.

   This entrypoint can be used to make it abort when the specified context
   encounters such a target builtin.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_abort_on_unsupported_target_builtin

Integer options
***************

.. function:: void gcc_jit_context_set_int_option (gcc_jit_context *ctxt, \
				                   enum gcc_jit_int_option opt, \
				                   int value)

  Set an integer option of the context.

  .. enum:: gcc_jit_int_option

  There is just one integer option specified this way:

  .. macro:: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL

     How much to optimize the code.

     Valid values are 0-3, corresponding to GCC's command-line options
     -O0 through -O3.

     The default value is 0 (unoptimized).

Additional command-line options
*******************************

.. function:: void gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,\
                                                            const char *optname)

   Add an arbitrary gcc command-line option to the context, for use
   by :func:`gcc_jit_context_compile` and
   :func:`gcc_jit_context_compile_to_file`.

   If you need to add more than one such option, each should be done via
   its own call to `gcc_jit_context_add_command_line_option`.

   The parameter ``optname`` must be non-NULL.  The underlying buffer is
   copied, so that it does not need to outlive the call.

   Extra options added by calls to `gcc_jit_context_add_command_line_option` are
   applied *after* the regular options above, potentially overriding them.
   Options from parent contexts are inherited by child contexts; options
   from the parent are applied *before* those from the child.

   For example:

   .. code-block:: c

      gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
      gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");

   Note that only some options are likely to be meaningful; there is no
   "frontend" within libgccjit, so typically only those affecting
   optimization and code-generation are likely to be useful.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_1`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option

.. function:: void gcc_jit_context_add_driver_option (gcc_jit_context *ctxt,\
						      const char *optname)

   Add an arbitrary gcc driver option to the context, for use by
   :func:`gcc_jit_context_compile` and
   :func:`gcc_jit_context_compile_to_file`.

   The parameter ``optname`` must be non-NULL.  The underlying buffer is
   copied, so that it does not need to outlive the call.

   If you need to add more than one such option, each should be done via
   its own call to `gcc_jit_context_add_driver_option`.

   Extra options added by calls to `gcc_jit_context_add_driver_option` are
   applied *after* all other options potentially overriding them.
   Options from parent contexts are inherited by child contexts; options
   from the parent are applied *before* those from the child.

   For example:

   .. code-block:: c

      gcc_jit_context_add_driver_option (ctxt, "-lm");
      gcc_jit_context_add_driver_option (ctxt, "-fuse-linker-plugin");

      gcc_jit_context_add_driver_option (ctxt, "obj.o");

      gcc_jit_context_add_driver_option (ctxt, "-L.");
      gcc_jit_context_add_driver_option (ctxt, "-lwhatever");

   Note that only some options are likely to be meaningful; there is no
   "frontend" within libgccjit, so typically only those affecting
   assembler and linker are likely to be useful.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_11`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_driver_option

Output options
**************

.. function:: void gcc_jit_context_set_output_ident (gcc_jit_context *ctxt,\
                                                     const char* output_ident)

   Set the identifier to write in the .comment section of the output file to
   ``output_ident``.

   The parameter ``output_ident`` must be non-NULL.

   This only works on some target, as you can see here:
   https://gcc.gnu.org/onlinedocs/cpp/Other-Directives.html

   Analogous to:

   .. code-block:: c

      #ident "My comment"

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_34`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_output_ident

---

### Gcc Jit Docs Topics Expressions (`gcc/jit/docs/topics/expressions.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Expressions
===========

Rvalues
-------
.. type:: gcc_jit_rvalue

A :c:type:`gcc_jit_rvalue` is an expression that can be computed.

It can be simple, e.g.:

  * an integer value e.g. `0` or `42`
  * a string literal e.g. `"Hello world"`
  * a variable e.g. `i`.  These are also lvalues (see below).

or compound e.g.:

  * a unary expression e.g. `!cond`
  * a binary expression e.g. `(a + b)`
  * a function call e.g. `get_distance (&player_ship, &target)`
  * etc.

Every rvalue has an associated type, and the API will check to ensure
that types match up correctly (otherwise the context will emit an error).

.. function:: gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)

  Get the type of this rvalue.

.. function:: gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)

  Upcast the given rvalue to be an object.


Simple expressions
******************

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt, \
                                                   gcc_jit_type *numeric_type, \
                                                   int value)

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`int` value.

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt, \
                                                    gcc_jit_type *numeric_type, \
                                                    long value)

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`long` value.

.. function::  gcc_jit_rvalue *gcc_jit_context_zero (gcc_jit_context *ctxt, \
                                                     gcc_jit_type *numeric_type)

   Given a numeric type (integer or floating point), get the rvalue for
   zero.  Essentially this is just a shortcut for:

   .. code-block:: c

      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0)

.. function::  gcc_jit_rvalue *gcc_jit_context_one (gcc_jit_context *ctxt, \
                                                    gcc_jit_type *numeric_type)

   Given a numeric type (integer or floating point), get the rvalue for
   one.  Essentially this is just a shortcut for:

   .. code-block:: c

      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)

.. function::  gcc_jit_rvalue *\
               gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt, \
                                                       gcc_jit_type *numeric_type, \
                                                       double value)

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`double` value.

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, \
                                                   gcc_jit_type *pointer_type, \
                                                   void *value)

   Given a pointer type, build an rvalue for the given address.

.. function:: gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context *ctxt, \
                                                    gcc_jit_type *pointer_type)

   Given a pointer type, build an rvalue for ``NULL``.  Essentially this
   is just a shortcut for:

   .. code-block:: c

      gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_string_literal (gcc_jit_context *ctxt, \
                                                  const char *value)

   Generate an rvalue for the given NIL-terminated string, of type
   :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR`.

   The parameter ``value`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_sizeof (gcc_jit_context *ctxt, \
                                          gcc_jit_type *type)

   Generate an rvalue that is equal to the size of ``type``.

   The parameter ``type`` must be non-NULL.

   This is equivalent to this C code:

   .. code-block:: c

     sizeof (type)

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_alignof (gcc_jit_context *ctxt, \
                                           gcc_jit_type *type)

   Generate an rvalue that is equal to the alignment of ``type``.

   The parameter ``type`` must be non-NULL.

   This is equivalent to this C code:

   .. code-block:: c

     _Alignof (type)

Constructor expressions
***********************

   The following functions make constructors for array, struct and union
   types.

   The constructor rvalue can be used for assignment to locals.
   It can be used to initialize global variables with
   :func:`gcc_jit_global_set_initializer_rvalue`. It can also be used as a
   temporary value for function calls and return values, but its address
   can't be taken.

   Note that arrays in libgccjit do not collapse to pointers like in
   C. I.e. if an array constructor is used as e.g. a return value, the whole
   array would be returned by value - array constructors can be assigned to
   array variables.

   The constructor can contain nested constructors.

   Note that a string literal rvalue can't be used to construct a char array;
   the latter needs one rvalue for each char.

   These entrypoints were added in :ref:`LIBGCCJIT_ABI_19`; you can test for
   their presence using:

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_CTORS

.. function:: gcc_jit_rvalue *\
	      gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,\
						     gcc_jit_location *loc,\
						     gcc_jit_type *type,\
						     size_t num_values,\
						     gcc_jit_rvalue **values)

   Create a constructor for an array as an rvalue.

   Returns NULL on error. ``values`` are copied and
   do not have to outlive the context.

   ``type`` specifies what the constructor will build and has to be
   an array.

   ``num_values`` specifies the number of elements in ``values`` and
   it can't have more elements than the array type.

   Each value in ``values`` sets the corresponding value in the array.
   If the array type itself has more elements than ``values``, the
   left-over elements will be zeroed.

   Each value in ``values`` need to be the same unqualified type as the
   array type's element type.

   If ``num_values`` is 0, the ``values`` parameter will be
   ignored and zero initialization will be used.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_19`; you can test for its
   presence using:

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_CTORS

.. function:: gcc_jit_rvalue *\
	      gcc_jit_context_new_struct_constructor (gcc_jit_context *ctxt,\
						      gcc_jit_location *loc,\
						      gcc_jit_type *type,\
						      size_t num_values,\
						      gcc_jit_field **fields,\
						      gcc_jit_rvalue **values)


   Create a constructor for a struct as an rvalue.

   Returns NULL on error. The two parameter arrays are copied and
   do not have to outlive the context.

   ``type`` specifies what the constructor will build and has to be
   a struct.

   ``num_values`` specifies the number of elements in ``values``.

   ``fields`` need to have the same length as ``values``, or be NULL.

   If ``fields`` is null, the values are applied in definition order.

   Otherwise, each field in ``fields`` specifies which field in the struct to
   set to the corresponding value in ``values``. ``fields`` and ``values``
   are paired by index.

   The fields in ``fields`` have to be in definition order, but there
   can be gaps. Any field in the struct that is not specified in
   ``fields`` will be zeroed.

   The fields in ``fields`` need to be the same objects that were used
   to create the struct.

   Each value has to have the same unqualified type as the field
   it is applied to.

   A NULL value element  in ``values`` is a shorthand for zero initialization
   of the corresponding field.

   If ``num_values`` is 0, the array parameters will be
   ignored and zero initialization will be used.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_19`; you can test for its
   presence using:

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_CTORS

.. function:: gcc_jit_rvalue *\
	      gcc_jit_context_new_union_constructor (gcc_jit_context *ctxt,\
						     gcc_jit_location *loc,\
						     gcc_jit_type *type,\
						     gcc_jit_field *field,\
						     gcc_jit_rvalue *value)

   Create a constructor for a union as an rvalue.

   Returns NULL on error.

   ``type`` specifies what the constructor will build and has to be
   an union.

   ``field`` specifies which field to set. If it is NULL, the first
   field in the union will be set.``field`` need to be the same object
   that were used to create the union.

   ``value`` specifies what value to set the corresponding field to.
   If ``value`` is NULL, zero initialization will be used.

   Each value has to have have the same unqualified type as the field
   it is applied to.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_19`; you can test for its
   presence using:

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_CTORS

Vector expressions
******************

.. function:: gcc_jit_rvalue * \
              gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt, \
                                                      gcc_jit_location *loc, \
                                                      gcc_jit_type *vec_type, \
                                                      size_t num_elements, \
                                                      gcc_jit_rvalue **elements)

   Build a vector rvalue from an array of elements.

   "vec_type" should be a vector type, created using
   :func:`gcc_jit_type_get_vector`.

   "num_elements" should match that of the vector type.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_10`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector

.. function:: gcc_jit_rvalue * \
              gcc_jit_context_new_rvalue_vector_perm (gcc_jit_context *ctxt, \
                                                      gcc_jit_location *loc, \
                                                      gcc_jit_rvalue *elements1, \
                                                      gcc_jit_rvalue *elements2, \
                                                      gcc_jit_rvalue *mask);

   Build a permutation of two vectors.

   "elements1" and "elements2" should have the same type.
   The length of "mask" and "elements1" should be the same.
   The element type of "mask" should be integral.
   The size of the element type of "mask" and "elements1" should be the same.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_31`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_VECTOR_OPERATIONS

    Analogous to:

    .. code-block:: c

       __builtin_shuffle (elements1, elements2, mask)

    in C.

Unary Operations
****************

.. function:: gcc_jit_rvalue * \
              gcc_jit_context_new_unary_op (gcc_jit_context *ctxt, \
                                            gcc_jit_location *loc, \
                                            enum gcc_jit_unary_op op, \
                                            gcc_jit_type *result_type, \
                                            gcc_jit_rvalue *rvalue)

   Build a unary operation out of an input rvalue.

   The parameter ``result_type`` must be a numeric type.

.. enum:: gcc_jit_unary_op

The available unary operations are:

.. list-table::
   :header-rows: 1

   * - Unary Operation
     - C equivalent

   * - :c:macro:`GCC_JIT_UNARY_OP_MINUS`
     - `-(EXPR)`
   * - :c:macro:`GCC_JIT_UNARY_OP_BITWISE_NEGATE`
     - `~(EXPR)`
   * - :c:macro:`GCC_JIT_UNARY_OP_LOGICAL_NEGATE`
     - `!(EXPR)`
   * - :c:macro:`GCC_JIT_UNARY_OP_ABS`
     - `abs (EXPR)`

.. c:macro:: GCC_JIT_UNARY_OP_MINUS

    Negate an arithmetic value; analogous to:

    .. code-block:: c

       -(EXPR)

    in C.

.. c:macro:: GCC_JIT_UNARY_OP_BITWISE_NEGATE

    Bitwise negation of an integer value (one's complement); analogous
    to:

    .. code-block:: c

       ~(EXPR)

    in C.

.. c:macro:: GCC_JIT_UNARY_OP_LOGICAL_NEGATE

    Logical negation of an arithmetic or pointer value; analogous to:

    .. code-block:: c

       !(EXPR)

    in C.

.. c:macro:: GCC_JIT_UNARY_OP_ABS

    Absolute value of an arithmetic expression; analogous to:

    .. code-block:: c

        abs (EXPR)

    in C.

Binary Operations
*****************

.. function:: gcc_jit_rvalue *gcc_jit_context_new_binary_op (gcc_jit_context *ctxt, \
                                                             gcc_jit_location *loc, \
                                                             enum gcc_jit_binary_op op, \
                                                             gcc_jit_type *result_type, \
                                                             gcc_jit_rvalue *a, gcc_jit_rvalue *b)

   Build a binary operation out of two constituent rvalues.

   The parameter ``result_type`` must be a numeric type.

.. enum:: gcc_jit_binary_op

The available binary operations are:

.. list-table::
   :header-rows: 1

   * - Binary Operation
     - C equivalent

   * - :c:macro:`GCC_JIT_BINARY_OP_PLUS`
     - `x + y`
   * - :c:macro:`GCC_JIT_BINARY_OP_MINUS`
     - `x - y`
   * - :c:macro:`GCC_JIT_BINARY_OP_MULT`
     - `x * y`
   * - :c:macro:`GCC_JIT_BINARY_OP_DIVIDE`
     - `x / y`
   * - :c:macro:`GCC_JIT_BINARY_OP_MODULO`
     - `x % y`
   * - :c:macro:`GCC_JIT_BINARY_OP_BITWISE_AND`
     - `x & y`
   * - :c:macro:`GCC_JIT_BINARY_OP_BITWISE_XOR`
     - `x ^ y`
   * - :c:macro:`GCC_JIT_BINARY_OP_BITWISE_OR`
     - `x | y`
   * - :c:macro:`GCC_JIT_BINARY_OP_LOGICAL_AND`
     - `x && y`
   * - :c:macro:`GCC_JIT_BINARY_OP_LOGICAL_OR`
     - `x || y`
   * - :c:macro:`GCC_JIT_BINARY_OP_LSHIFT`
     - `x << y`
   * - :c:macro:`GCC_JIT_BINARY_OP_RSHIFT`
     - `x >> y`

.. c:macro:: GCC_JIT_BINARY_OP_PLUS

   Addition of arithmetic values; analogous to:

   .. code-block:: c

     (EXPR_A) + (EXPR_B)

   in C.

   For pointer addition, use :c:func:`gcc_jit_context_new_array_access`.

.. c:macro:: GCC_JIT_BINARY_OP_MINUS

   Subtraction of arithmetic values; analogous to:

   .. code-block:: c

     (EXPR_A) - (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_MULT

   Multiplication of a pair of arithmetic values; analogous to:

   .. code-block:: c

     (EXPR_A) * (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_DIVIDE

   Quotient of division of arithmetic values; analogous to:

   .. code-block:: c

     (EXPR_A) / (EXPR_B)

   in C.

   The result type affects the kind of division: if the result type is
   integer-based, then the result is truncated towards zero, whereas
   a floating-point result type indicates floating-point division.

.. c:macro:: GCC_JIT_BINARY_OP_MODULO

   Remainder of division of arithmetic values; analogous to:

   .. code-block:: c

     (EXPR_A) % (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_AND

   Bitwise AND; analogous to:

   .. code-block:: c

     (EXPR_A) & (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_XOR

   Bitwise exclusive OR; analogous to:

   .. code-block:: c

      (EXPR_A) ^ (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_OR

   Bitwise inclusive OR; analogous to:

   .. code-block:: c

     (EXPR_A) | (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_AND

   Logical AND; analogous to:

   .. code-block:: c

     (EXPR_A) && (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_OR

   Logical OR; analogous to:

   .. code-block:: c

     (EXPR_A) || (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_LSHIFT

   Left shift; analogous to:

   .. code-block:: c

     (EXPR_A) << (EXPR_B)

   in C.

.. c:macro:: GCC_JIT_BINARY_OP_RSHIFT

   Right shift; analogous to:

   .. code-block:: c

     (EXPR_A) >> (EXPR_B)

   in C.

Comparisons
***********

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_comparison (gcc_jit_context *ctxt,\
                                              gcc_jit_location *loc,\
                                              enum gcc_jit_comparison op,\
                                              gcc_jit_rvalue *a, gcc_jit_rvalue *b)

   Build a boolean rvalue out of the comparison of two other rvalues.

.. enum:: gcc_jit_comparison

.. list-table::
   :header-rows: 1

   * - Comparison
     - C equivalent

   * - :c:macro:`GCC_JIT_COMPARISON_EQ`
     - `x == y`
   * - :c:macro:`GCC_JIT_COMPARISON_NE`
     - `x != y`
   * - :c:macro:`GCC_JIT_COMPARISON_LT`
     - `x < y`
   * - :c:macro:`GCC_JIT_COMPARISON_LE`
     - `x <= y`
   * - :c:macro:`GCC_JIT_COMPARISON_GT`
     - `x > y`
   * - :c:macro:`GCC_JIT_COMPARISON_GE`
     - `x >= y`

Function calls
**************
.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_call (gcc_jit_context *ctxt,\
                                        gcc_jit_location *loc,\
                                        gcc_jit_function *func,\
                                        int numargs , gcc_jit_rvalue **args)

   Given a function and the given table of argument rvalues, construct a
   call to the function, with the result as an rvalue.

   .. note::

      :c:func:`gcc_jit_context_new_call` merely builds a
      :c:type:`gcc_jit_rvalue` i.e. an expression that can be evaluated,
      perhaps as part of a more complicated expression.
      The call *won't* happen unless you add a statement to a function
      that evaluates the expression.

      For example, if you want to call a function and discard the result
      (or to call a function with ``void`` return type), use
      :c:func:`gcc_jit_block_add_eval`:

      .. code-block:: c

         /* Add "(void)printf (arg0, arg1);".  */
         gcc_jit_block_add_eval (
           block, NULL,
           gcc_jit_context_new_call (
             ctxt,
             NULL,
             printf_func,
             2, args));

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,\
                                                    gcc_jit_location *loc,\
                                                    gcc_jit_rvalue *fn_ptr,\
                                                    int numargs, \
                                                    gcc_jit_rvalue **args)

   Given an rvalue of function pointer type (e.g. from
   :c:func:`gcc_jit_context_new_function_ptr_type`), and the given table of
   argument rvalues, construct a call to the function pointer, with the
   result as an rvalue.

   .. note::

      The same caveat as for :c:func:`gcc_jit_context_new_call` applies.

.. function:: void\
              gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call,\
                                                         int require_tail_call)

   Given an :c:type:`gcc_jit_rvalue` for a call created through
   :c:func:`gcc_jit_context_new_call` or
   :c:func:`gcc_jit_context_new_call_through_ptr`, mark/clear the
   call as needing tail-call optimization.  The optimizer will
   attempt to optimize the call into a jump instruction; if it is
   unable to do do, an error will be emitted.

   This may be useful when implementing functions that use the
   continuation-passing style (e.g. for functional programming
   languages), in which every function "returns" by calling a
   "continuation" function pointer.  This call must be
   guaranteed to be implemented as a jump, otherwise the program
   could consume an arbitrary amount of stack space as it executed.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_6`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call

Function pointers
*****************

Function pointers can be obtained:

  * from a :c:type:`gcc_jit_function` using
    :c:func:`gcc_jit_function_get_address`, or

  * from an existing function using
    :c:func:`gcc_jit_context_new_rvalue_from_ptr`,
    using a function pointer type obtained using
    :c:func:`gcc_jit_context_new_function_ptr_type`.

Type-coercion
*************

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_cast (gcc_jit_context *ctxt,\
                                        gcc_jit_location *loc,\
                                        gcc_jit_rvalue *rvalue,\
                                        gcc_jit_type *type)

   Given an rvalue of T, construct another rvalue of another type.

   Currently only a limited set of conversions are possible:

     * int <-> float
     * int <-> bool
     * P*  <-> Q*, for pointer types P and Q

.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_bitcast (gcc_jit_context *ctxt,\
                                           gcc_jit_location *loc,\
                                           gcc_jit_rvalue *rvalue,\
                                           gcc_jit_type *type)

   Given an rvalue of T, bitcast it to another type, meaning that this will
   generate a new rvalue by interpreting the bits of ``rvalue`` to the layout
   of ``type``.

   The type of rvalue must be the same size as the size of ``type``.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_21`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast

.. function:: gcc_jit_rvalue *
              gcc_jit_context_convert_vector (gcc_jit_context *ctxt, \
                                              gcc_jit_location *loc, \
                                              gcc_jit_rvalue *vector, \
                                              gcc_jit_type *type)

   Given a vector rvalue, cast it to the type ``type``, doing an element-wise
   conversion.

   The number of elements in ``vector`` and ``type`` must match.
   The ``type`` must be a vector type.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_30`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_convert_vector

Lvalues
-------

.. type:: gcc_jit_lvalue

An lvalue is something that can of the *left*-hand side of an assignment:
a storage area (such as a variable).  It is also usable as an rvalue,
where the rvalue is computed by reading from the storage area.

.. function:: gcc_jit_object *\
              gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)

   Upcast an lvalue to be an object.

.. function:: gcc_jit_rvalue *\
              gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)

   Upcast an lvalue to be an rvalue.

.. function:: gcc_jit_rvalue *\
              gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,\
                                          gcc_jit_location *loc)

   Take the address of an lvalue; analogous to:

   .. code-block:: c

     &(EXPR)

   in C.

.. function:: void\
              gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,\
                                            enum gcc_jit_tls_model model)

   Make a variable a thread-local variable.

   The "model" parameter determines the thread-local storage model of the "lvalue":

   .. enum:: gcc_jit_tls_model

   .. c:macro:: GCC_JIT_TLS_MODEL_NONE

      Don't set the TLS model.

   .. c:macro:: GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC

   .. c:macro:: GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC

   .. c:macro:: GCC_JIT_TLS_MODEL_INITIAL_EXEC

   .. c:macro:: GCC_JIT_TLS_MODEL_LOCAL_EXEC

   This is analogous to:

   .. code-block:: c

     _Thread_local int foo __attribute__ ((tls_model("MODEL")));

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_17`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_tls_model

.. function:: void\
              gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,\
                                               const char *section_name)

   Set the link section of a variable.
   The parameter ``section_name`` must be non-NULL and must contain the
   leading dot. Analogous to:

   .. code-block:: c

     int variable __attribute__((section(".section")));

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_18`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section

.. function:: void\
              gcc_jit_lvalue_set_register_name (gcc_jit_lvalue *lvalue,\
                                                const char *reg_name);

   Set the register name of a variable.
   The parameter ``reg_name`` must be non-NULL. Analogous to:

   .. code-block:: c

     register int variable asm ("r12");

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_22`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_register_name

.. function:: void\
              gcc_jit_lvalue_set_alignment (gcc_jit_lvalue *lvalue,\
                                            unsigned bytes)

   Set the alignment of a variable, in bytes.
   Analogous to:

   .. code-block:: c

     int variable __attribute__((aligned (16)));

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_24`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ALIGNMENT

.. function:: unsigned\
              gcc_jit_lvalue_get_alignment (gcc_jit_lvalue *lvalue)

   Return the alignment of a variable set by ``gcc_jit_lvalue_set_alignment``.
   Return 0 if the alignment was not set. Analogous to:

   .. code-block:: c

     _Alignof (variable)

   in C.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_24`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ALIGNMENT

Global variables
****************

.. function:: gcc_jit_lvalue *\
              gcc_jit_context_new_global (gcc_jit_context *ctxt,\
                                          gcc_jit_location *loc,\
                                          enum gcc_jit_global_kind kind,\
                                          gcc_jit_type *type,\
                                          const char *name)

   Add a new global variable of the given type and name to the context.

   The parameter ``type`` must be non-`void`.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

   The "kind" parameter determines the visibility of the "global" outside
   of the :c:type:`gcc_jit_result`:

   .. enum:: gcc_jit_global_kind

   .. c:macro:: GCC_JIT_GLOBAL_EXPORTED

      Global is defined by the client code and is visible
      by name outside of this JIT context via
      :c:func:`gcc_jit_result_get_global` (and this value is required for
      the global to be accessible via that entrypoint).

   .. c:macro:: GCC_JIT_GLOBAL_INTERNAL

      Global is defined by the client code, but is invisible
      outside of it.  Analogous to a "static" global within a .c file.
      Specifically, the variable will only be visible within this
      context and within child contexts.

   .. c:macro:: GCC_JIT_GLOBAL_IMPORTED

      Global is not defined by the client code; we're merely
      referring to it.  Analogous to using an "extern" global from a
      header file.

.. function:: gcc_jit_lvalue *\
              gcc_jit_global_set_initializer (gcc_jit_lvalue *global,\
                                              const void *blob,\
                                              size_t num_bytes)

   Set an initializer for ``global`` using the memory content pointed
   by ``blob`` for ``num_bytes``.  ``global`` must be an array of an
   integral type.  Return the global itself.

   The parameter ``blob`` must be non-NULL. The call copies the memory
   pointed by ``blob`` for ``num_bytes`` bytes, so it is valid to pass
   in a pointer to an on-stack buffer.  The content will be stored in
   the compilation unit and used as initialization value of the array.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_14`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer

.. function:: gcc_jit_lvalue *\
	      gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global,\
	                                             gcc_jit_rvalue *init_value)

   Set the initial value of a global with an rvalue.

   The rvalue needs to be a constant expression, e.g. no function calls.

   The global can't have the ``kind`` :c:macro:`GCC_JIT_GLOBAL_IMPORTED`.

   As a non-comprehensive example it is OK to do the equivalent of:

   .. code-block:: c

       int foo = 3 * 2; /* rvalue from gcc_jit_context_new_binary_op.  */
       int arr[] = {1,2,3,4}; /* rvalue from gcc_jit_context_new_constructor.  */
       int *bar = &arr[2] + 1; /* rvalue from nested "get address" of "array access".  */
       const int baz = 3; /* rvalue from gcc_jit_context_rvalue_from_int.  */
       int boz = baz; /* rvalue from gcc_jit_lvalue_as_rvalue.  */

   Use together with :c:func:`gcc_jit_context_new_struct_constructor`,
   :c:func:`gcc_jit_context_new_union_constructor`, :c:func:`gcc_jit_context_new_array_constructor`
   to initialize structs, unions and arrays.

   On success, returns the ``global`` parameter unchanged. Otherwise, ``NULL``.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_19`; you can test for its
   presence using:

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_CTORS

Variables
*********

.. function::  void\
               gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
                                                    enum gcc_jit_variable_attribute attribute,
                                                    const char *value)

     Add an attribute ``attribute`` with value ``value`` to a variable ``variable``.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ATTRIBUTES

.. function:: void\
              gcc_jit_global_set_readonly (gcc_jit_lvalue *global)

   Set the global variable as read-only, meaning you cannot assign to this variable.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_29`; you can test for its
   presence using:

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_readonly

Working with pointers, structs and unions
-----------------------------------------

.. function:: gcc_jit_lvalue *\
              gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,\
                                          gcc_jit_location *loc)

   Given an rvalue of pointer type ``T *``, dereferencing the pointer,
   getting an lvalue of type ``T``.  Analogous to:

   .. code-block:: c

     *(EXPR)

   in C.

Field access is provided separately for both lvalues and rvalues.

.. function:: gcc_jit_lvalue *\
              gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,\
                                           gcc_jit_location *loc,\
                                           gcc_jit_field *field)

   Given an lvalue of struct or union type, access the given field,
   getting an lvalue of the field's type.  Analogous to:

   .. code-block:: c

      (EXPR).field = ...;

   in C.

.. function:: gcc_jit_rvalue *\
              gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,\
                                           gcc_jit_location *loc,\
                                           gcc_jit_field *field)

   Given an rvalue of struct or union type, access the given field
   as an rvalue.  Analogous to:

   .. code-block:: c

      (EXPR).field

   in C.

.. function:: gcc_jit_lvalue *\
              gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,\
                                                gcc_jit_location *loc,\
                                                gcc_jit_field *field)

   Given an rvalue of pointer type ``T *`` where T is of struct or union
   type, access the given field as an lvalue.  Analogous to:

   .. code-block:: c

      (EXPR)->field

   in C, itself equivalent to ``(*EXPR).FIELD``.

.. function:: gcc_jit_lvalue *\
              gcc_jit_context_new_array_access (gcc_jit_context *ctxt,\
                                                gcc_jit_location *loc,\
                                                gcc_jit_rvalue *ptr,\
                                                gcc_jit_rvalue *index)

   Given an rvalue of pointer type ``T *``, get at the element `T` at
   the given index, using standard C array indexing rules i.e. each
   increment of ``index`` corresponds to ``sizeof(T)`` bytes.
   Analogous to:

   .. code-block:: c

      PTR[INDEX]

   in C (or, indeed, to ``PTR + INDEX``).

.. function:: gcc_jit_lvalue *\
              gcc_jit_context_new_vector_access (gcc_jit_context *ctxt,\
                                                 gcc_jit_location *loc,\
                                                 gcc_jit_rvalue *vector,\
                                                 gcc_jit_rvalue *index)

   Given an rvalue of vector type ``T __attribute__ ((__vector_size__ (SIZE)))``,
   get the element `T` at the given index.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_31`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_VECTOR_OPERATIONS

   Analogous to:

   .. code-block:: c

      VECTOR[INDEX]

   in C.

---

### Gcc Jit Docs Topics Function Pointers (`gcc/jit/docs/topics/function-pointers.rst`)

.. Copyright (C) 2017-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Function pointers
=================

You can generate calls that use a function pointer via
:c:func:`gcc_jit_context_new_call_through_ptr`.

To do requires a :c:type:`gcc_jit_rvalue` of the correct function pointer type.

Function pointers for a :c:type:`gcc_jit_function` can be obtained
via :c:func:`gcc_jit_function_get_address`.

.. function:: gcc_jit_rvalue *\
	      gcc_jit_function_get_address (gcc_jit_function *fn,\
                                            gcc_jit_location *loc)

   Get the address of a function as an rvalue, of function pointer
   type.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_9`; you can test
   for its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_function_get_address

Alternatively, given an existing function, you can obtain a pointer
to it in :c:type:`gcc_jit_rvalue` form using
:c:func:`gcc_jit_context_new_rvalue_from_ptr`, using a function pointer
type obtained using :c:func:`gcc_jit_context_new_function_ptr_type`.

Here's an example of creating a function pointer type corresponding to C's
:expr:`void (*) (int, int, int)`:

.. code-block:: c

  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Build the function ptr type.  */
  gcc_jit_type *param_types[3];
  param_types[0] = int_type;
  param_types[1] = int_type;
  param_types[2] = int_type;

  gcc_jit_type *fn_ptr_type =
    gcc_jit_context_new_function_ptr_type (ctxt, NULL,
					   void_type,
					   3, param_types, 0);

.. function:: gcc_jit_type *\
	      gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,\
				       gcc_jit_location *loc,\
				       gcc_jit_type *return_type,\
				       int num_params,\
				       gcc_jit_type **param_types,\
				       int is_variadic)

   Generate a :c:type:`gcc_jit_type` for a function pointer with the
   given return type and parameters.

   Each of `param_types` must be non-`void`; `return_type` may be `void`.

---

### Gcc Jit Docs Topics Functions (`gcc/jit/docs/topics/functions.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Creating and using functions
============================

Params
------
.. type:: gcc_jit_param

   A `gcc_jit_param` represents a parameter to a function.

.. function:: gcc_jit_param *\
              gcc_jit_context_new_param (gcc_jit_context *ctxt,\
                                         gcc_jit_location *loc,\
                                         gcc_jit_type *type,\
                                         const char *name)

   In preparation for creating a function, create a new parameter of the
   given type and name.

   The parameter ``type`` must be non-`void`.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

Parameters are lvalues, and thus are also rvalues (and objects), so the
following upcasts are available:

.. function::  gcc_jit_lvalue *\
               gcc_jit_param_as_lvalue (gcc_jit_param *param)

   Upcasting from param to lvalue.

.. function::  gcc_jit_rvalue *\
               gcc_jit_param_as_rvalue (gcc_jit_param *param)

   Upcasting from param to rvalue.

.. function::  gcc_jit_object *\
               gcc_jit_param_as_object (gcc_jit_param *param)

   Upcasting from param to object.


Functions
---------

.. type:: gcc_jit_function

   A `gcc_jit_function` represents a function - either one that we're
   creating ourselves, or one that we're referencing.

.. function::  gcc_jit_function *\
               gcc_jit_context_new_function (gcc_jit_context *ctxt,\
                                             gcc_jit_location *loc,\
                                             enum gcc_jit_function_kind kind,\
                                             gcc_jit_type *return_type,\
                                             const char *name,\
                                             int num_params,\
                                             gcc_jit_param **params,\
                                             int is_variadic)

   Create a gcc_jit_function with the given name and parameters.

   .. enum:: gcc_jit_function_kind

   This enum controls the kind of function created, and has the following
   values:

      .. macro:: GCC_JIT_FUNCTION_EXPORTED

         Function is defined by the client code and visible
         by name outside of the JIT.

         This value is required if you want to extract machine code
         for this function from a :type:`gcc_jit_result` via
         :func:`gcc_jit_result_get_code`.

      .. macro::   GCC_JIT_FUNCTION_INTERNAL

         Function is defined by the client code, but is invisible
         outside of the JIT.  Analogous to a "static" function.

      .. macro::   GCC_JIT_FUNCTION_IMPORTED

         Function is not defined by the client code; we're merely
         referring to it.  Analogous to using an "extern" function from a
         header file.

      .. macro::   GCC_JIT_FUNCTION_ALWAYS_INLINE

         Function is only ever inlined into other functions, and is
         invisible outside of the JIT.

         Analogous to prefixing with ``inline`` and adding
         ``__attribute__((always_inline))``

         Inlining will only occur when the optimization level is
         above 0; when optimization is off, this is essentially the
         same as GCC_JIT_FUNCTION_INTERNAL.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

.. function::  gcc_jit_function *\
               gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,\
                                                     const char *name)

   Get the :type:`gcc_jit_function` for the built-in function with the
   given name.  For example:

   .. code-block:: c

      gcc_jit_function *fn
        = gcc_jit_context_get_builtin_function (ctxt, "__builtin_memcpy");

   .. note:: Due to technical limitations with how libgccjit interacts with
      the insides of GCC, not all built-in functions are supported.  More
      precisely, not all types are supported for parameters of built-in
      functions from libgccjit.  Attempts to get a built-in function that
      uses such a parameter will lead to an error being emitted within
      the context.

.. function::  gcc_jit_function *\
               gcc_jit_context_get_target_builtin_function (gcc_jit_context *ctxt,\
                                                            const char *name)

   Get the :type:`gcc_jit_function` for the built-in function (sometimes called
   intrinsic functions) with the given name.  For example:

   .. code-block:: c

      gcc_jit_function *fn
        = gcc_jit_context_get_target_builtin_function (ctxt, "__builtin_ia32_pmuldq512_mask");

   .. note:: Due to technical limitations with how libgccjit interacts with
      the insides of GCC, not all built-in functions are supported.  More
      precisely, not all types are supported for parameters of built-in
      functions from libgccjit.  Attempts to get a built-in function that
      uses such a parameter will lead to an error being emitted within
      the context.

.. function::  gcc_jit_object *\
               gcc_jit_function_as_object (gcc_jit_function *func)

    Upcasting from function to object.

.. function::  gcc_jit_param *\
               gcc_jit_function_get_param (gcc_jit_function *func, int index)

   Get the param of the given index (0-based).

.. function::  void \
               gcc_jit_function_dump_to_dot (gcc_jit_function *func,\
                                             const char *path)

   Emit the function in graphviz format to the given path.

.. function:: gcc_jit_lvalue *\
              gcc_jit_function_new_local (gcc_jit_function *func,\
                                          gcc_jit_location *loc,\
                                          gcc_jit_type *type,\
                                          const char *name)

   Create a new local variable within the function, of the given type and
   name.

   The parameter ``type`` must be non-`void`.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

.. function:: gcc_jit_lvalue *\
              gcc_jit_function_new_temp (gcc_jit_function *func,\
                                         gcc_jit_location *loc,\
                                         gcc_jit_type *type)

   Create a new local variable within the function, of the given type.
   This function is similar to :func:`gcc_jit_function_new_local`, but
   it is to be used for compiler-generated variables (as opposed to
   user-defined variables in the language to be compiled) and these
   variables won't show up in the debug info.

   The parameter ``type`` must be non-`void`.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_33`; you can test
   for its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_function_new_temp

.. function::  size_t \
               gcc_jit_function_get_param_count (gcc_jit_function *func)

   Get the number of parameters of the function.

.. function::  gcc_jit_type *\
               gcc_jit_function_get_return_type (gcc_jit_function *func)

   Get the return type of the function.

   The API entrypoints relating to getting info about parameters and return
   types:

      * :c:func:`gcc_jit_function_get_return_type`

      * :c:func:`gcc_jit_function_get_param_count`

   were added in :ref:`LIBGCCJIT_ABI_16`; you can test for their presence
   using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_REFLECTION

   .. type:: gcc_jit_case

.. function::  void\
               gcc_jit_function_add_attribute (gcc_jit_function *func,
                                               enum gcc_jit_fn_attribute attribute)

     Add an attribute ``attribute`` to a function ``func``.

     This is equivalent to the following code:

  .. code-block:: c

    __attribute__((always_inline))

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ATTRIBUTES

.. function::  void\
               gcc_jit_function_add_string_attribute (gcc_jit_function *func,
                                                      enum gcc_jit_fn_attribute attribute,
                                                      const char *value)

     Add a string attribute ``attribute`` with value ``value`` to a function
     ``func``.

     This is equivalent to the following code:

  .. code-block:: c

    __attribute__ ((alias ("xxx")))

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ATTRIBUTES

.. function::  void\
               gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func,
                                                             enum gcc_jit_fn_attribute attribute,
                                                             const int *value,
                                                             size_t length)

     Add an attribute ``attribute`` with ``length`` integer values ``value`` to a
     function ``func``. The integer values must be the same as you would write
     them in a C code.

     This is equivalent to the following code:

  .. code-block:: c

    __attribute__ ((nonnull (1, 2)))

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_26`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ATTRIBUTES

Blocks
------
.. type:: gcc_jit_block

   A `gcc_jit_block` represents a basic block within a function  i.e. a
   sequence of statements with a single entry point and a single exit
   point.

   The first basic block that you create within a function will
   be the entrypoint.

   Each basic block that you create within a function must be
   terminated, either with a conditional, a jump, a return, or a
   switch.

   It's legal to have multiple basic blocks that return within
   one function.

.. function::  gcc_jit_block *\
               gcc_jit_function_new_block (gcc_jit_function *func,\
                                           const char *name)

   Create a basic block of the given name.  The name may be NULL, but
   providing meaningful names is often helpful when debugging: it may
   show up in dumps of the internal representation, and in error
   messages.  It is copied, so the input buffer does not need to outlive
   the call; you can pass in a pointer to an on-stack buffer, e.g.:

   .. code-block:: c

     for (pc = 0; pc < fn->fn_num_ops; pc++)
      {
        char buf[16];
        sprintf (buf, "instr%i", pc);
        state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
      }

.. function::  gcc_jit_object *\
               gcc_jit_block_as_object (gcc_jit_block *block)

   Upcast from block to object.

.. function::  gcc_jit_function *\
               gcc_jit_block_get_function (gcc_jit_block *block)

   Which function is this block within?


Statements
----------

.. function:: void\
              gcc_jit_block_add_eval (gcc_jit_block *block,\
                                      gcc_jit_location *loc,\
                                      gcc_jit_rvalue *rvalue)

   Add evaluation of an rvalue, discarding the result
   (e.g. a function call that "returns" void).

   This is equivalent to this C code:

   .. code-block:: c

     (void)expression;

.. function:: void\
              gcc_jit_block_add_assignment (gcc_jit_block *block,\
                                            gcc_jit_location *loc,\
                                            gcc_jit_lvalue *lvalue,\
                                            gcc_jit_rvalue *rvalue)

   Add evaluation of an rvalue, assigning the result to the given
   lvalue.

   This is roughly equivalent to this C code:

   .. code-block:: c

     lvalue = rvalue;

.. function:: void\
              gcc_jit_block_add_assignment_op (gcc_jit_block *block,\
                                 gcc_jit_location *loc,\
                                 gcc_jit_lvalue *lvalue,\
                                 enum gcc_jit_binary_op op,\
                                 gcc_jit_rvalue *rvalue)

   Add evaluation of an rvalue, using the result to modify an
   lvalue.

   This is analogous to "+=" and friends:

   .. code-block:: c

     lvalue += rvalue;
     lvalue *= rvalue;
     lvalue /= rvalue;

   etc.  For example:

   .. code-block:: c

     /* "i++" */
     gcc_jit_block_add_assignment_op (
       loop_body, NULL,
       i,
       GCC_JIT_BINARY_OP_PLUS,
       gcc_jit_context_one (ctxt, int_type));

.. function:: void\
              gcc_jit_block_add_comment (gcc_jit_block *block,\
                                         gcc_jit_location *loc,\
                                         const char *text)

   Add a no-op textual comment to the internal representation of the
   code.  It will be optimized away, but will be visible in the dumps
   seen via :macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE`
   and :macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE`,
   and thus may be of use when debugging how your project's internal
   representation gets converted to the libgccjit IR.

   The parameter ``text`` must be non-NULL.  It is copied, so the input
   buffer does not need to outlive the call.  For example:

   .. code-block:: c

     char buf[100];
     snprintf (buf, sizeof (buf),
               "op%i: %s",
               pc, opcode_names[op->op_opcode]);
     gcc_jit_block_add_comment (block, loc, buf);

.. function:: void\
              gcc_jit_block_end_with_conditional (gcc_jit_block *block,\
                                                  gcc_jit_location *loc,\
                                                  gcc_jit_rvalue *boolval,\
                                                  gcc_jit_block *on_true,\
                                                  gcc_jit_block *on_false)

   Terminate a block by adding evaluation of an rvalue, branching on the
   result to the appropriate successor block.

   This is roughly equivalent to this C code:

   .. code-block:: c

     if (boolval)
       goto on_true;
     else
       goto on_false;

   block, boolval, on_true, and on_false must be non-NULL.

.. function:: void\
              gcc_jit_block_end_with_jump (gcc_jit_block *block,\
                                           gcc_jit_location *loc,\
                                           gcc_jit_block *target)


   Terminate a block by adding a jump to the given target block.

   This is roughly equivalent to this C code:

   .. code-block:: c

      goto target;

.. function:: void\
              gcc_jit_block_end_with_return (gcc_jit_block *block,\
                                             gcc_jit_location *loc,\
                                             gcc_jit_rvalue *rvalue)


   Terminate a block by adding evaluation of an rvalue, returning the value.

   This is roughly equivalent to this C code:

   .. code-block:: c

      return expression;

.. function:: void\
              gcc_jit_block_end_with_void_return (gcc_jit_block *block,\
                                                  gcc_jit_location *loc)


   Terminate a block by adding a valueless return, for use within a function
   with "void" return type.

   This is equivalent to this C code:

   .. code-block:: c

      return;

.. function:: void\
              gcc_jit_block_end_with_switch (gcc_jit_block *block,\
                                             gcc_jit_location *loc,\
                                             gcc_jit_rvalue *expr,\
                                             gcc_jit_block *default_block,\
                                             int num_cases,\
                                             gcc_jit_case **cases)

   Terminate a block by adding evaluation of an rvalue, then performing
   a multiway branch.

   This is roughly equivalent to this C code:

   .. code-block:: c

     switch (expr)
       {
       default:
         goto default_block;

       case C0.min_value ... C0.max_value:
         goto C0.dest_block;

       case C1.min_value ... C1.max_value:
         goto C1.dest_block;

       ...etc...

       case C[N - 1].min_value ... C[N - 1].max_value:
         goto C[N - 1].dest_block;
     }

   ``block``, ``expr``, ``default_block`` and ``cases`` must all be
   non-NULL.

   ``expr`` must be of the same integer type as all of the ``min_value``
   and ``max_value`` within the cases.

   ``num_cases`` must be >= 0.

   The ranges of the cases must not overlap (or have duplicate
   values).

   The API entrypoints relating to switch statements and cases:

      * :c:func:`gcc_jit_block_end_with_switch`

      * :c:func:`gcc_jit_case_as_object`

      * :c:func:`gcc_jit_context_new_case`

   were added in :ref:`LIBGCCJIT_ABI_3`; you can test for their presence
   using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS

   .. type:: gcc_jit_case

   A `gcc_jit_case` represents a case within a switch statement, and
   is created within a particular :c:type:`gcc_jit_context` using
   :c:func:`gcc_jit_context_new_case`.

   Each case expresses a multivalued range of integer values.  You
   can express single-valued cases by passing in the same value for
   both `min_value` and `max_value`.

   .. function:: gcc_jit_case *\
                 gcc_jit_context_new_case (gcc_jit_context *ctxt,\
                                           gcc_jit_rvalue *min_value,\
                                           gcc_jit_rvalue *max_value,\
                                           gcc_jit_block *dest_block)

      Create a new gcc_jit_case instance for use in a switch statement.
      `min_value` and `max_value` must be constants of an integer type,
      which must match that of the expression of the switch statement.

      `dest_block` must be within the same function as the switch
      statement.

   .. function:: gcc_jit_object *\
                 gcc_jit_case_as_object (gcc_jit_case *case_)

      Upcast from a case to an object.

   Here's an example of creating a switch statement:

     .. literalinclude:: ../../../testsuite/jit.dg/test-switch.c
       :start-after: /* Quote from here in docs/topics/functions.rst.  */
       :end-before: /* Quote up to here in docs/topics/functions.rst.  */
       :language: c

See also :type:`gcc_jit_extended_asm` for entrypoints for adding inline
assembler statements to a function.

---

### Gcc Jit Docs Topics Index (`gcc/jit/docs/topics/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Topic Reference
===============

.. toctree::
   :maxdepth: 2

   contexts.rst
   objects.rst
   types.rst
   expressions.rst
   functions.rst
   function-pointers.rst
   locations.rst
   compilation.rst
   compatibility.rst
   performance.rst
   asm.rst

---

### Gcc Jit Docs Topics Locations (`gcc/jit/docs/topics/locations.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Source Locations
================

.. type:: gcc_jit_location

   A `gcc_jit_location` encapsulates a source code location, so that
   you can (optionally) associate locations in your language with
   statements in the JIT-compiled code, allowing the debugger to
   single-step through your language.

   `gcc_jit_location` instances are optional: you can always pass NULL to
   any API entrypoint accepting one.

   You can construct them using :c:func:`gcc_jit_context_new_location`.

   You need to enable :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` on the
   :c:type:`gcc_jit_context` for these locations to actually be usable by
   the debugger:

   .. code-block:: c

     gcc_jit_context_set_bool_option (
       ctxt,
       GCC_JIT_BOOL_OPTION_DEBUGINFO,
       1);

.. function:: gcc_jit_location *\
              gcc_jit_context_new_location (gcc_jit_context *ctxt,\
                                            const char *filename,\
                                            int line,\
                                            int column)

   Create a `gcc_jit_location` instance representing the given source
   location.

   The parameter ``filename`` must be non-NULL.  The call takes a copy of
   the underlying string, so it is valid to pass in a pointer to an
   on-stack buffer.

Faking it
---------
If you don't have source code for your internal representation, but need
to debug, you can generate a C-like representation of the functions in
your context using :c:func:`gcc_jit_context_dump_to_file()`:

.. code-block:: c

  gcc_jit_context_dump_to_file (ctxt, "/tmp/something.c",
                                1 /* update_locations */);

This will dump C-like code to the given path.  If the `update_locations`
argument is true, this will also set up `gcc_jit_location` information
throughout the context, pointing at the dump file as if it were a source
file, giving you *something* you can step through in the debugger.

---

### Gcc Jit Docs Topics Objects (`gcc/jit/docs/topics/objects.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Objects
=======

.. type:: gcc_jit_object

Almost every entity in the API (with the exception of
:c:expr:`gcc_jit_context *` and :c:expr:`gcc_jit_result *`) is a
"contextual" object, a :c:expr:`gcc_jit_object *`

A JIT object:

  * is associated with a :c:expr:`gcc_jit_context *`.

  * is automatically cleaned up for you when its context is released so
    you don't need to manually track and cleanup all objects, just the
    contexts.

Although the API is C-based, there is a form of class hierarchy, which
looks like this::

  +- gcc_jit_object
      +- gcc_jit_location
      +- gcc_jit_type
         +- gcc_jit_struct
      +- gcc_jit_field
      +- gcc_jit_function
      +- gcc_jit_block
      +- gcc_jit_rvalue
          +- gcc_jit_lvalue
             +- gcc_jit_param
      +- gcc_jit_case
      +- gcc_jit_extended_asm

There are casting methods for upcasting from subclasses to parent classes.
For example, :c:func:`gcc_jit_type_as_object`:

.. code-block:: c

   gcc_jit_object *obj = gcc_jit_type_as_object (int_type);

The object "base class" has the following operations:

.. function:: gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object *obj)

  Which context is "obj" within?


.. function:: const char *gcc_jit_object_get_debug_string (gcc_jit_object *obj)

  Generate a human-readable description for the given object.

  For example,

  .. code-block:: c

     printf ("obj: %s\n", gcc_jit_object_get_debug_string (obj));

  might give this text on stdout:

  .. code-block:: bash

     obj: 4.0 * (float)i

  .. note::

     If you call this on an object, the `const char *` buffer is allocated
     and generated on the first call for that object, and the buffer will
     have the same lifetime as the object  i.e. it will exist until the
     object's context is released.

---

### Gcc Jit Docs Topics Performance (`gcc/jit/docs/topics/performance.rst`)

.. Copyright (C) 2015-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Performance
===========

The timing API
--------------

As of GCC 6, libgccjit exposes a timing API, for printing reports on
how long was spent in different parts of code.

You can create a :c:type:`gcc_jit_timer` instance, which will
measure time spent since its creation.  The timer maintains a stack
of "timer items": as control flow moves through your code, you can push
and pop named items relating to your code onto the stack, and the timer
will account the time spent accordingly.

You can also associate a timer with a :c:type:`gcc_jit_context`, in
which case the time spent inside compilation will be subdivided.

For example, the following code uses a timer, recording client items
"create_code", "compile", and "running code":

.. code-block:: c

  /* Create a timer.  */
  gcc_jit_timer *timer = gcc_jit_timer_new ();
  if (!timer)
    {
       error ("gcc_jit_timer_new failed");
       return -1;
    }

  /* Let's repeatedly compile and run some code, accumulating it
     all into the timer.  */
  for (int i = 0; i < num_iterations; i++)
    {
      /* Create a context and associate it with the timer.  */
      gcc_jit_context *ctxt = gcc_jit_context_acquire ();
      if (!ctxt)
        {
          error ("gcc_jit_context_acquire failed");
          return -1;
        }
      gcc_jit_context_set_timer (ctxt, timer);

      /* Populate the context, timing it as client item "create_code".  */
      gcc_jit_timer_push (timer, "create_code");
      create_code (ctxt);
      gcc_jit_timer_pop (timer, "create_code");

      /* Compile the context, timing it as client item "compile".  */
      gcc_jit_timer_push (timer, "compile");
      result = gcc_jit_context_compile (ctxt);
      gcc_jit_timer_pop (timer, "compile");

      /* Run the generated code, timing it as client item "running code".  */
      gcc_jit_timer_push (timer, "running code");
      run_the_code (ctxt, result);
      gcc_jit_timer_pop (timer, "running code");

      /* Clean up.  */
      gcc_jit_context_release (ctxt);
      gcc_jit_result_release (result);
  }

  /* Print the accumulated timings.  */
  gcc_jit_timer_print (timer, stderr);
  gcc_jit_timer_release (timer);

giving output like this, showing the internal GCC items at the top, then
client items, then the total::

  Execution times (seconds)
  GCC items:
   phase setup             :   0.29 (14%) usr   0.00 ( 0%) sys   0.32 ( 5%) wall   10661 kB (50%) ggc
   phase parsing           :   0.02 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     653 kB ( 3%) ggc
   phase finalize          :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   dump files              :   0.02 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
   callgraph construction  :   0.02 ( 1%) usr   0.01 ( 6%) sys   0.01 ( 0%) wall     242 kB ( 1%) ggc
   callgraph optimization  :   0.03 ( 2%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     142 kB ( 1%) ggc
   trivially dead code     :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   df scan insns           :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       9 kB ( 0%) ggc
   df live regs            :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
   inline parameters       :   0.02 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall      82 kB ( 0%) ggc
   tree CFG cleanup        :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   tree PHI insertion      :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall      64 kB ( 0%) ggc
   tree SSA other          :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall      18 kB ( 0%) ggc
   expand                  :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     398 kB ( 2%) ggc
   jump                    :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   loop init               :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall      67 kB ( 0%) ggc
   integrated RA           :   0.02 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall    2468 kB (12%) ggc
   thread pro- & epilogue  :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     162 kB ( 1%) ggc
   final                   :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     216 kB ( 1%) ggc
   rest of compilation     :   1.37 (69%) usr   0.00 ( 0%) sys   1.13 (18%) wall    1391 kB ( 6%) ggc
   assemble JIT code       :   0.01 ( 1%) usr   0.00 ( 0%) sys   4.04 (66%) wall       0 kB ( 0%) ggc
   load JIT result         :   0.02 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   JIT client code         :   0.00 ( 0%) usr   0.01 ( 6%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
  Client items:
   create_code             :   0.00 ( 0%) usr   0.01 ( 6%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   compile                 :   0.36 (18%) usr   0.15 (83%) sys   0.86 (14%) wall   14939 kB (70%) ggc
   running code            :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
   TOTAL                   :   2.00             0.18             6.12              21444 kB

The exact format is intended to be human-readable, and is subject to change.

.. macro:: LIBGCCJIT_HAVE_TIMING_API

   The timer API was added to libgccjit in GCC 6.
   This macro is only defined in versions of libgccjit.h which have the
   timer API, and so can be used to guard code that may need to compile
   against earlier releases::

     #ifdef LIBGCCJIT_HAVE_TIMING_API
     gcc_jit_timer *t = gcc_jit_timer_new ();
     gcc_jit_context_set_timer (ctxt, t);
     #endif

.. type:: gcc_jit_timer

.. function:: gcc_jit_timer * gcc_jit_timer_new(void)

   Create a :c:type:`gcc_jit_timer` instance, and start timing::

     gcc_jit_timer *t = gcc_jit_timer_new ();

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: void gcc_jit_timer_release(gcc_jit_timer *timer)

   Release a :c:type:`gcc_jit_timer` instance::

     gcc_jit_timer_release (t);

   This should be called exactly once on a timer.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: void gcc_jit_context_set_timer(gcc_jit_context *ctxt, \
                                             gcc_jit_timer *timer)

   Associate a :c:type:`gcc_jit_timer` instance with a context::

      gcc_jit_context_set_timer (ctxt, t);

   A timer instance can be shared between multiple
   :c:type:`gcc_jit_context` instances.

   Timers have no locking, so if you have a multithreaded program, you
   must provide your own locks if more than one thread could be working
   with the same timer via timer-associated contexts.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: gcc_jit_timer *gcc_jit_context_get_timer(gcc_jit_context *ctxt)

   Get the timer associated with a context (if any).

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: void gcc_jit_timer_push(gcc_jit_timer *timer, \
                                      const char *item_name)

   Push the given item onto the timer's stack::

      gcc_jit_timer_push (t, "running code");
      run_the_code (ctxt, result);
      gcc_jit_timer_pop (t, "running code");

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: void gcc_jit_timer_pop(gcc_jit_timer *timer, \
                                     const char *item_name)

   Pop the top item from the timer's stack.

   If "item_name" is provided, it must match that of the top item.
   Alternatively, ``NULL`` can be passed in, to suppress checking.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

.. function:: void gcc_jit_timer_print(gcc_jit_timer *timer, \
                                       FILE *f_out)

   Print timing information to the given stream about activity since
   the timer was started.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_4`; you can test
   for its presence using

   .. code-block:: c

     #ifdef LIBGCCJIT_HAVE_TIMING_API

---

### Gcc Jit Docs Topics Types (`gcc/jit/docs/topics/types.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: c

Types
=====

.. c:type:: gcc_jit_type

   gcc_jit_type represents a type within the library.

.. function:: gcc_jit_object *gcc_jit_type_as_object (gcc_jit_type *type)

   Upcast a type to an object.

Types can be created in several ways:

* fundamental types can be accessed using
  :func:`gcc_jit_context_get_type`:

  .. code-block:: c

      gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  See :func:`gcc_jit_context_get_type` for the available types.

* derived types can be accessed by using functions such as
  :func:`gcc_jit_type_get_pointer` and :func:`gcc_jit_type_get_const`:

  .. code-block:: c

    gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type));
    gcc_jit_type *int_const_star = gcc_jit_type_get_const (gcc_jit_type_get_pointer (int_type));

* by creating structures (see below).

Standard types
--------------

.. function:: gcc_jit_type *gcc_jit_context_get_type (gcc_jit_context *ctxt, \
                                                      enum gcc_jit_types type_)

   Access a specific type.  The available types are:

  .. list-table::
     :header-rows: 1

     * - `enum gcc_jit_types` value
       - Meaning

     * - :c:data:`GCC_JIT_TYPE_VOID`
       - C's ``void`` type.
     * - :c:data:`GCC_JIT_TYPE_VOID_PTR`
       - C's ``void *``.
     * - :c:data:`GCC_JIT_TYPE_BOOL`
       - C++'s ``bool`` type; also C99's ``_Bool`` type, aka ``bool`` if using stdbool.h.
     * - :c:data:`GCC_JIT_TYPE_CHAR`
       - C's ``char`` (of some signedness)
     * - :c:data:`GCC_JIT_TYPE_SIGNED_CHAR`
       - C's ``signed char``
     * - :c:data:`GCC_JIT_TYPE_UNSIGNED_CHAR`
       - C's ``unsigned char``
     * - :c:data:`GCC_JIT_TYPE_SHORT`
       - C's ``short`` (signed)
     * - :c:data:`GCC_JIT_TYPE_UNSIGNED_SHORT`
       - C's ``unsigned short``
     * - :c:data:`GCC_JIT_TYPE_INT`
       - C's ``int`` (signed)
     * - :c:data:`GCC_JIT_TYPE_UNSIGNED_INT`
       - C's ``unsigned int``
     * - :c:data:`GCC_JIT_TYPE_LONG`
       - C's ``long`` (signed)
     * - :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG`
       - C's ``unsigned long``
     * - :c:data:`GCC_JIT_TYPE_LONG_LONG`
       - C99's ``long long`` (signed)
     * - :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG`
       - C99's ``unsigned long long``
     * - :c:data:`GCC_JIT_TYPE_UINT8_T`
       - C99's ``uint8_t``
     * - :c:data:`GCC_JIT_TYPE_UINT16_T`
       - C99's ``uint16_t``
     * - :c:data:`GCC_JIT_TYPE_UINT32_T`
       - C99's ``uint32_t``
     * - :c:data:`GCC_JIT_TYPE_UINT64_T`
       - C99's ``uint64_t``
     * - :c:data:`GCC_JIT_TYPE_UINT128_T`
       - C99's ``__uint128_t``
     * - :c:data:`GCC_JIT_TYPE_INT8_T`
       - C99's ``int8_t``
     * - :c:data:`GCC_JIT_TYPE_INT16_T`
       - C99's ``int16_t``
     * - :c:data:`GCC_JIT_TYPE_INT32_T`
       - C99's ``int32_t``
     * - :c:data:`GCC_JIT_TYPE_INT64_T`
       - C99's ``int64_t``
     * - :c:data:`GCC_JIT_TYPE_INT128_T`
       - C99's ``__int128_t``
     * - :c:data:`GCC_JIT_TYPE_FLOAT`
       -
     * - :c:data:`GCC_JIT_TYPE_BFLOAT16`
       - C's ``__bfloat16``
     * - :c:data:`GCC_JIT_TYPE_DOUBLE`
       -
     * - :c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
       -
     * - :c:data:`GCC_JIT_TYPE_FLOAT16`
       -
     * - :c:data:`GCC_JIT_TYPE_FLOAT32`
       -
     * - :c:data:`GCC_JIT_TYPE_FLOAT64`
       -
     * - :c:data:`GCC_JIT_TYPE_FLOAT128`
       -
     * - :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR`
       - C type: ``(const char *)``
     * - :c:data:`GCC_JIT_TYPE_SIZE_T`
       - C's ``size_t`` type
     * - :c:data:`GCC_JIT_TYPE_FILE_PTR`
       - C type: ``(FILE *)``
     * - :c:data:`GCC_JIT_TYPE_COMPLEX_FLOAT`
       - C99's ``_Complex float``
     * - :c:data:`GCC_JIT_TYPE_COMPLEX_DOUBLE`
       - C99's ``_Complex double``
     * - :c:data:`GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE`
       - C99's ``_Complex long double``

.. function:: gcc_jit_type *\
              gcc_jit_context_get_int_type (gcc_jit_context *ctxt, \
                                            int num_bytes, int is_signed)

   Access the integer type of the given size.


Pointers, `const`, and `volatile`
---------------------------------

.. function::  gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type *type)

   Given type "T", get type "T*".

.. function::  gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type *type)

   Given type "T", get type "const T".

.. function::  gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type *type)

   Given type "T", get type "volatile T".

.. function::  gcc_jit_type *\
               gcc_jit_context_new_array_type (gcc_jit_context *ctxt, \
                                               gcc_jit_location *loc, \
                                               gcc_jit_type *element_type, \
                                               int num_elements)

   Given non-`void` type "T", get type "T[N]" (for a constant N).

.. function::  gcc_jit_type *\
               gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, \
                                                   gcc_jit_location *loc, \
                                                   gcc_jit_type *element_type, \
                                                   uint64_t num_elements)

   Given non-`void` type "T", get type "T[N]" (for a constant N).

   This is the same as gcc_jit_context_new_array_type, but the type of
   ``num_elements` different and thus allows creating bigger array types.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_37`; you can test
   for its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64

.. function::  gcc_jit_type *\
               gcc_jit_type_get_aligned (gcc_jit_type *type, \
                                         size_t alignment_in_bytes)

   Given non-`void` type "T", get type:

   .. code-block:: c

      T __attribute__ ((aligned (ALIGNMENT_IN_BYTES)))

   The alignment must be a power of two.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_7`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_aligned

Vector types
------------

.. function::  gcc_jit_type *\
               gcc_jit_type_get_vector (gcc_jit_type *type, \
                                        size_t num_units)

   Given type "T", get type:

   .. code-block:: c

      T  __attribute__ ((vector_size (sizeof(T) * num_units))

   T must be integral or floating point; num_units must be a power of two.

   This can be used to construct a vector type in which operations
   are applied element-wise.  The compiler will automatically
   use SIMD instructions where possible.  See:
   https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html

   For example, assuming 4-byte ``ints``, then:

   .. code-block:: c

      typedef int v4si __attribute__ ((vector_size (16)));

   can be obtained using:

   .. code-block:: c

      gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
                                                         GCC_JIT_TYPE_INT);
      gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4);

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_8`; you can test
   for its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_vector

   Vector rvalues can be generated using
   :func:`gcc_jit_context_new_rvalue_from_vector`.


Structures and unions
---------------------

.. c:type:: gcc_jit_struct

A compound type analogous to a C `struct`.

.. c:type:: gcc_jit_field

A field within a :c:type:`gcc_jit_struct`.

You can model C `struct` types by creating :c:type:`gcc_jit_struct` and
:c:type:`gcc_jit_field` instances, in either order:

* by creating the fields, then the structure.  For example, to model:

  .. code-block:: c

    struct coord {double x; double y; };

  you could call:

  .. code-block:: c

    gcc_jit_field *field_x =
      gcc_jit_context_new_field (ctxt, NULL, double_type, "x");
    gcc_jit_field *field_y =
      gcc_jit_context_new_field (ctxt, NULL, double_type, "y");
    gcc_jit_field *fields[2] = {field_x, field_y};
    gcc_jit_struct *coord =
      gcc_jit_context_new_struct_type (ctxt, NULL, "coord", 2, fields);

* by creating the structure, then populating it with fields, typically
  to allow modelling self-referential structs such as:

  .. code-block:: c

    struct node { int m_hash; struct node *m_next; };

  like this:

  .. code-block:: c

    gcc_jit_type *node =
      gcc_jit_context_new_opaque_struct (ctxt, NULL, "node");
    gcc_jit_type *node_ptr =
      gcc_jit_type_get_pointer (node);
    gcc_jit_field *field_hash =
      gcc_jit_context_new_field (ctxt, NULL, int_type, "m_hash");
    gcc_jit_field *field_next =
      gcc_jit_context_new_field (ctxt, NULL, node_ptr, "m_next");
    gcc_jit_field *fields[2] = {field_hash, field_next};
    gcc_jit_struct_set_fields (node, NULL, 2, fields);

.. function:: gcc_jit_field *\
              gcc_jit_context_new_field (gcc_jit_context *ctxt,\
                                         gcc_jit_location *loc,\
                                         gcc_jit_type *type,\
                                         const char *name)

   Construct a new field, with the given type and name.

   The parameter ``type`` must be non-`void`.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

.. function:: gcc_jit_field *\
              gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,\
                                            gcc_jit_location *loc,\
                                            gcc_jit_type *type,\
                                            int width,\
                                            const char *name)

   Construct a new bit field, with the given type width and name.

   The parameter ``name`` must be non-NULL.  The call takes a copy of the
   underlying string, so it is valid to pass in a pointer to an on-stack
   buffer.

   The parameter ``type`` must be an integer type.

   The parameter ``width`` must be a positive integer that does not exceed the
   size of ``type``.

   This API entrypoint was added in :ref:`LIBGCCJIT_ABI_12`; you can test
   for its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield

.. function:: gcc_jit_object *\
              gcc_jit_field_as_object (gcc_jit_field *field)

   Upcast from field to object.

.. function:: gcc_jit_struct *\
   gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,\
                                    gcc_jit_location *loc,\
                                    const char *name,\
                                    int num_fields,\
                                    gcc_jit_field **fields)

     Construct a new struct type, with the given name and fields.

     The parameter ``name`` must be non-NULL.  The call takes a copy of
     the underlying string, so it is valid to pass in a pointer to an
     on-stack buffer.

.. function:: gcc_jit_struct *\
              gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,\
                                                 gcc_jit_location *loc,\
                                                 const char *name)

     Construct a new struct type, with the given name, but without
     specifying the fields.   The fields can be omitted (in which case the
     size of the struct is not known), or later specified using
     :c:func:`gcc_jit_struct_set_fields`.

     The parameter ``name`` must be non-NULL.  The call takes a copy of
     the underlying string, so it is valid to pass in a pointer to an
     on-stack buffer.

.. function:: gcc_jit_type *\
              gcc_jit_struct_as_type (gcc_jit_struct *struct_type)

   Upcast from struct to type.

.. function:: void\
              gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,\
                                         gcc_jit_location *loc,\
                                         int num_fields,\
                                         gcc_jit_field **fields)

   Populate the fields of a formerly-opaque struct type.

   This can only be called once on a given struct type.

.. function:: gcc_jit_type *\
              gcc_jit_context_new_union_type (gcc_jit_context *ctxt,\
                                              gcc_jit_location *loc,\
                                              const char *name,\
                                              int num_fields,\
                                              gcc_jit_field **fields)

     Construct a new union type, with the given name and fields.

     The parameter ``name`` must be non-NULL.  It is copied, so the input
     buffer does not need to outlive the call.

     Example of use:

     .. literalinclude:: ../../../testsuite/jit.dg/test-accessing-union.c
       :start-after: /* Quote from here in docs/topics/types.rst.  */
       :end-before: /* Quote up to here in docs/topics/types.rst.  */
       :language: c

Function pointer types
----------------------

Function pointer types can be created using
:c:func:`gcc_jit_context_new_function_ptr_type`.

Reflection API
--------------

.. function::  gcc_jit_type *\
               gcc_jit_type_dyncast_array (gcc_jit_type *type)

     Get the element type of an array type or NULL if it's not an array.

.. function::  int\
               gcc_jit_type_is_bool (gcc_jit_type *type)

     Return non-zero if the type is a bool.

.. function::  gcc_jit_function_type *\
               gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type *type)

     Return the function type if it is one or NULL.

.. function::  gcc_jit_type *\
               gcc_jit_function_type_get_return_type (gcc_jit_function_type *function_type)

     Given a function type, return its return type.

.. function::  size_t\
               gcc_jit_function_type_get_param_count (gcc_jit_function_type *function_type)

     Given a function type, return its number of parameters.

.. function::  gcc_jit_type *\
               gcc_jit_function_type_get_param_type (gcc_jit_function_type *function_type,\
                                                     size_t index)

     Given a function type, return the type of the specified parameter.

.. function::  int\
               gcc_jit_type_is_integral (gcc_jit_type *type)

     Return non-zero if the type is an integral.

.. function::  int\
               gcc_jit_type_is_floating_point (gcc_jit_type *type)

     Return non-zero if the type is floating point.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_38`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_type_is_floating_point

.. function::  gcc_jit_type *\
               gcc_jit_type_is_pointer (gcc_jit_type *type)

     Return the type pointed by the pointer type or NULL if it's not a pointer.

.. function::  gcc_jit_vector_type *\
               gcc_jit_type_dyncast_vector (gcc_jit_type *type)

     Given a type, return a dynamic cast to a vector type or NULL.

.. function::  gcc_jit_struct *\
               gcc_jit_type_is_struct (gcc_jit_type *type)

     Given a type, return a dynamic cast to a struct type or NULL.

.. function::  size_t\
               gcc_jit_vector_type_get_num_units (gcc_jit_vector_type *vector_type)

     Given a vector type, return the number of units it contains.

.. function::  gcc_jit_type *\
               gcc_jit_vector_type_get_element_type (gcc_jit_vector_type * vector_type)

     Given a vector type, return the type of its elements.

.. function::  gcc_jit_type *\
               gcc_jit_type_unqualified (gcc_jit_type *type)

     Given a type, return the unqualified type, removing "const", "volatile" and
     alignment qualifiers.

.. function::  gcc_jit_field *\
               gcc_jit_struct_get_field (gcc_jit_struct *struct_type,\
                                         size_t index)

     Get a struct field by index.

.. function::  size_t\
               gcc_jit_struct_get_field_count (gcc_jit_struct *struct_type)

     Get the number of fields in the struct.

   The API entrypoints related to the reflection API:

      * :c:func:`gcc_jit_function_type_get_return_type`

      * :c:func:`gcc_jit_function_type_get_param_count`

      * :c:func:`gcc_jit_function_type_get_param_type`

      * :c:func:`gcc_jit_type_unqualified`

      * :c:func:`gcc_jit_type_dyncast_array`

      * :c:func:`gcc_jit_type_is_bool`

      * :c:func:`gcc_jit_type_dyncast_function_ptr_type`

      * :c:func:`gcc_jit_type_is_integral`

      * :c:func:`gcc_jit_type_is_pointer`

      * :c:func:`gcc_jit_type_dyncast_vector`

      * :c:func:`gcc_jit_vector_type_get_element_type`

      * :c:func:`gcc_jit_vector_type_get_num_units`

      * :c:func:`gcc_jit_struct_get_field`

      * :c:func:`gcc_jit_type_is_struct`

      * :c:func:`gcc_jit_struct_get_field_count`

   were added in :ref:`LIBGCCJIT_ABI_16`; you can test for their presence
   using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_REFLECTION

   .. type:: gcc_jit_case

.. function::  int\
               gcc_jit_compatible_types (gcc_jit_type *ltype,\
                                         gcc_jit_type *rtype)

     Return non-zero if the two types are compatible. For instance,
     if :c:data:`GCC_JIT_TYPE_UINT64_T` and :c:data:`GCC_JIT_TYPE_UNSIGNED_LONG`
     are the same size on the target, this will return non-zero.
     The parameters ``ltype`` and ``rtype`` must be non-NULL.
     Return 0 on errors.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS

.. function::  ssize_t\
               gcc_jit_type_get_size (gcc_jit_type *type)

     Return the size of a type, in bytes. It only works on integer types for now.
     The parameter ``type`` must be non-NULL.
     Return -1 on errors.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_20`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS

.. function::  gcc_jit_type *\
               gcc_jit_type_get_restrict (gcc_jit_type *type)

     Given type "T", get type "restrict T".

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_25`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_type_get_restrict

---

### Gcc Jit Docs Cp Intro Index (`gcc/jit/docs/cp/intro/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Tutorial
========

.. toctree::
   :maxdepth: 2

   tutorial01.rst
   tutorial02.rst
   tutorial03.rst
   tutorial04.rst

---

### Gcc Jit Docs Cp Intro Tutorial01 (`gcc/jit/docs/cp/intro/tutorial01.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Tutorial part 1: "Hello world"
==============================

Before we look at the details of the API, let's look at building and
running programs that use the library.

Here's a toy "hello world" program that uses the library's C++ API to
synthesize a call to `printf` and uses it to write a message to stdout.

Don't worry about the content of the program for now; we'll cover
the details in later parts of this tutorial.

   .. literalinclude:: ../../examples/tut01-hello-world.cc
    :language: c++

Copy the above to `tut01-hello-world.cc`.

Assuming you have the jit library installed, build the test program
using:

.. code-block:: console

  $ gcc \
      tut01-hello-world.cc \
      -o tut01-hello-world \
      -lgccjit

You should then be able to run the built program:

.. code-block:: console

  $ ./tut01-hello-world
  hello world

---

### Gcc Jit Docs Cp Intro Tutorial02 (`gcc/jit/docs/cp/intro/tutorial02.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Tutorial part 2: Creating a trivial machine code function
---------------------------------------------------------

Consider this C function:

.. code-block:: c

   int square (int i)
   {
     return i * i;
   }

How can we construct this at run-time using libgccjit's C++ API?

First we need to include the relevant header:

.. code-block:: c++

  #include <libgccjit++.h>

All state associated with compilation is associated with a
:type:`gccjit::context`, which is a thin C++ wrapper around the C API's
:c:expr:`gcc_jit_context *`.

Create one using :func:`gccjit::context::acquire`:

.. code-block:: c++

  gccjit::context ctxt;
  ctxt = gccjit::context::acquire ();

The JIT library has a system of types.  It is statically-typed: every
expression is of a specific type, fixed at compile-time.  In our example,
all of the expressions are of the C `int` type, so let's obtain this from
the context, as a :type:`gccjit::type`, using
:func:`gccjit::context::get_type`:

.. code-block:: c++

  gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);

:type:`gccjit::type` is an example of a "contextual" object: every
entity in the API is associated with a :type:`gccjit::context`.

Memory management is easy: all such "contextual" objects are automatically
cleaned up for you when the context is released, using
:func:`gccjit::context::release`:

.. code-block:: c++

  ctxt.release ();

so you don't need to manually track and cleanup all objects, just the
contexts.

All of the C++ classes in the API are thin wrappers around pointers to
types in the C API.

The C++ class hierarchy within the ``gccjit`` namespace looks like this::

  +- object
      +- location
      +- type
         +- struct
      +- field
      +- function
      +- block
      +- rvalue
          +- lvalue
             +- param

One thing you can do with a :type:`gccjit::object` is
to ask it for a human-readable description as a :type:`std::string`, using
:func:`gccjit::object::get_debug_string`:

.. code-block:: c++

   printf ("obj: %s\n", obj.get_debug_string ().c_str ());

giving this text on stdout:

.. code-block:: bash

   obj: int

This is invaluable when debugging.

Let's create the function.  To do so, we first need to construct
its single parameter, specifying its type and giving it a name,
using :func:`gccjit::context::new_param`:

.. code-block:: c++

  gccjit::param param_i = ctxt.new_param (int_type, "i");

and we can then make a vector of all of the params of the function,
in this case just one:

.. code-block:: c++

  std::vector<gccjit::param> params;
  params.push_back (param_i);

Now we can create the function, using
:cpp:func:`gccjit::context::new_function`:

.. code-block:: c++

  gccjit::function func =
    ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
                       int_type,
                       "square",
                       params,
                       0);

To define the code within the function, we must create basic blocks
containing statements.

Every basic block contains a list of statements, eventually terminated
by a statement that either returns, or jumps to another basic block.

Our function has no control-flow, so we just need one basic block:

.. code-block:: c++

  gccjit::block block = func.new_block ();

Our basic block is relatively simple: it immediately terminates by
returning the value of an expression.

We can build the expression using :func:`gccjit::context::new_binary_op`:

.. code-block:: c++

   gccjit::rvalue expr =
     ctxt.new_binary_op (
       GCC_JIT_BINARY_OP_MULT, int_type,
       param_i, param_i);

A :type:`gccjit::rvalue` is another example of a
:type:`gccjit::object` subclass.  As before, we can print it with
:func:`gccjit::object::get_debug_string`.

.. code-block:: c++

   printf ("expr: %s\n", expr.get_debug_string ().c_str ());

giving this output:

.. code-block:: bash

   expr: i * i

Note that :type:`gccjit::rvalue` provides numerous overloaded operators
which can be used to dramatically reduce the amount of typing needed.
We can build the above binary operation more directly with this one-liner:

.. code-block:: c++

   gccjit::rvalue expr = param_i * param_i;

Creating the expression in itself doesn't do anything; we have to add
this expression to a statement within the block.  In this case, we use it
to build a return statement, which terminates the basic block:

.. code-block:: c++

  block.end_with_return (expr);

OK, we've populated the context.  We can now compile it using
:func:`gccjit::context::compile`:

.. code-block:: c++

   gcc_jit_result *result;
   result = ctxt.compile ();

and get a :c:expr:`gcc_jit_result *`.

We can now use :c:func:`gcc_jit_result_get_code` to look up a specific
machine code routine within the result, in this case, the function we
created above.

.. code-block:: c++

   void *fn_ptr = gcc_jit_result_get_code (result, "square");
   if (!fn_ptr)
     {
       fprintf (stderr, "NULL fn_ptr");
       goto error;
     }

We can now cast the pointer to an appropriate function pointer type, and
then call it:

.. code-block:: c++

  typedef int (*fn_type) (int);
  fn_type square = (fn_type)fn_ptr;
  printf ("result: %d", square (5));

.. code-block:: bash

  result: 25


Options
*******

To get more information on what's going on, you can set debugging flags
on the context using :func:`gccjit::context::set_bool_option`.

.. (I'm deliberately not mentioning
    :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
    it's probably more of use to implementors than to users)

Setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE` will dump a
C-like representation to stderr when you compile (GCC's "GIMPLE"
representation):

.. code-block:: c++

   ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);
   result = ctxt.compile ();

.. code-block:: c

  square (signed int i)
  {
    signed int D.260;

    entry:
    D.260 = i * i;
    return D.260;
  }

We can see the generated machine code in assembler form (on stderr) by
setting :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE` on the context
before compiling:

.. code-block:: c++

  ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
  result = ctxt.compile ();

.. code-block:: gas

        .file   "fake.c"
        .text
        .globl  square
        .type   square, @function
  square:
  .LFB6:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -4(%rbp)
  .L14:
        movl    -4(%rbp), %eax
        imull   -4(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
  .LFE6:
        .size   square, .-square
        .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
        .section       .note.GNU-stack,"",@progbits

By default, no optimizations are performed, the equivalent of GCC's
`-O0` option.  We can turn things up to e.g. `-O3` by calling
:func:`gccjit::context::set_int_option` with
:c:macro:`GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL`:

.. code-block:: c++

  ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);

.. code-block:: gas

        .file   "fake.c"
        .text
        .p2align 4,,15
        .globl  square
        .type   square, @function
  square:
  .LFB7:
        .cfi_startproc
  .L16:
        movl    %edi, %eax
        imull   %edi, %eax
        ret
        .cfi_endproc
  .LFE7:
        .size   square, .-square
        .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
        .section        .note.GNU-stack,"",@progbits

Naturally this has only a small effect on such a trivial function.


Full example
************

Here's what the above looks like as a complete program:

   .. literalinclude:: ../../examples/tut02-square.cc
    :lines: 1-
    :language: c++

Building and running it:

.. code-block:: console

  $ gcc \
      tut02-square.cc \
      -o tut02-square \
      -lgccjit

  # Run the built program:
  $ ./tut02-square
  result: 25

---

### Gcc Jit Docs Cp Intro Tutorial03 (`gcc/jit/docs/cp/intro/tutorial03.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Tutorial part 3: Loops and variables
------------------------------------
Consider this C function:

 .. code-block:: c

  int loop_test (int n)
  {
    int sum = 0;
    for (int i = 0; i < n; i++)
      sum += i * i;
    return sum;
  }

This example demonstrates some more features of libgccjit, with local
variables and a loop.

To break this down into libgccjit terms, it's usually easier to reword
the `for` loop as a `while` loop, giving:

 .. code-block:: c

  int loop_test (int n)
  {
    int sum = 0;
    int i = 0;
    while (i < n)
    {
      sum += i * i;
      i++;
    }
    return sum;
  }

Here's what the final control flow graph will look like:

    .. figure:: ../../intro/sum-of-squares.png
      :alt: image of a control flow graph

As before, we include the libgccjit++ header and make a
:type:`gccjit::context`.

.. code-block:: c++

  #include <libgccjit++.h>

  void test (void)
  {
    gccjit::context ctxt;
    ctxt = gccjit::context::acquire ();

The function works with the C `int` type.

In the previous tutorial we acquired this via

.. code-block:: c++

  gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_INT);

though we could equally well make it work on, say, `double`:

.. code-block:: c++

  gccjit::type the_type = ctxt.get_type (ctxt, GCC_JIT_TYPE_DOUBLE);

For integer types we can use :func:`gccjit::context::get_int_type<T>`
to directly bind a specific type:

.. code-block:: c++

  gccjit::type the_type = ctxt.get_int_type <int> ();

Let's build the function:

.. code-block:: c++

  gcc_jit_param n = ctxt.new_param (the_type, "n");
  std::vector<gccjit::param> params;
  params.push_back (n);
  gccjit::function func =
    ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
                       return_type,
                       "loop_test",
                       params, 0);

Expressions: lvalues and rvalues
********************************

The base class of expression is the :type:`gccjit::rvalue`,
representing an expression that can be on the *right*-hand side of
an assignment: a value that can be computed somehow, and assigned
*to* a storage area (such as a variable).  It has a specific
:type:`gccjit::type`.

Another important class is :type:`gccjit::lvalue`.
A :type:`gccjit::lvalue`. is something that can of the *left*-hand
side of an assignment: a storage area (such as a variable).

In other words, every assignment can be thought of as:

.. code-block:: c

   LVALUE = RVALUE;

Note that :type:`gccjit::lvalue` is a subclass of
:type:`gccjit::rvalue`, where in an assignment of the form:

.. code-block:: c

   LVALUE_A = LVALUE_B;

the `LVALUE_B` implies reading the current value of that storage
area, assigning it into the `LVALUE_A`.

So far the only expressions we've seen are from the previous tutorial:

1. the multiplication `i * i`:

  .. code-block:: c++

     gccjit::rvalue expr =
       ctxt.new_binary_op (
         GCC_JIT_BINARY_OP_MULT, int_type,
         param_i, param_i);

     /* Alternatively, using operator-overloading: */
     gccjit::rvalue expr = param_i * param_i;

  which is a :type:`gccjit::rvalue`, and

2. the various function parameters: `param_i` and `param_n`, instances of
   :type:`gccjit::param`, which is a subclass of :type:`gccjit::lvalue`
   (and, in turn, of :type:`gccjit::rvalue`):
   we can both read from and write to function parameters within the
   body of a function.

Our new example has a new kind of expression: we have two local
variables.  We create them by calling
:func:`gccjit::function::new_local`, supplying a type and a name:

.. code-block:: c++

  /* Build locals:  */
  gccjit::lvalue i = func.new_local (the_type, "i");
  gccjit::lvalue sum = func.new_local (the_type, "sum");

These are instances of :type:`gccjit::lvalue` - they can be read from
and written to.

Note that there is no precanned way to create *and* initialize a variable
like in C:

.. code-block:: c

   int i = 0;

Instead, having added the local to the function, we have to separately add
an assignment of `0` to `local_i` at the beginning of the function.

Control flow
************

This function has a loop, so we need to build some basic blocks to
handle the control flow.  In this case, we need 4 blocks:

1. before the loop (initializing the locals)
2. the conditional at the top of the loop (comparing `i < n`)
3. the body of the loop
4. after the loop terminates (`return sum`)

so we create these as :type:`gccjit::block` instances within the
:type:`gccjit::function`:

.. code-block:: c++

  gccjit::block b_initial = func.new_block ("initial");
  gccjit::block b_loop_cond = func.new_block ("loop_cond");
  gccjit::block b_loop_body = func.new_block ("loop_body");
  gccjit::block b_after_loop = func.new_block ("after_loop");

We now populate each block with statements.

The entry block `b_initial` consists of initializations followed by a jump
to the conditional.  We assign `0` to `i` and to `sum`, using
:func:`gccjit::block::add_assignment` to add
an assignment statement, and using :func:`gccjit::context::zero` to get
the constant value `0` for the relevant type for the right-hand side of
the assignment:

.. code-block:: c++

  /* sum = 0; */
  b_initial.add_assignment (sum, ctxt.zero (the_type));

  /* i = 0; */
  b_initial.add_assignment (i, ctxt.zero (the_type));

We can then terminate the entry block by jumping to the conditional:

.. code-block:: c++

  b_initial.end_with_jump (b_loop_cond);

The conditional block is equivalent to the line `while (i < n)` from our
C example. It contains a single statement: a conditional, which jumps to
one of two destination blocks depending on a boolean
:type:`gccjit::rvalue`, in this case the comparison of `i` and `n`.

We could build the comparison using :func:`gccjit::context::new_comparison`:

.. code-block:: c++

   gccjit::rvalue guard =
     ctxt.new_comparison (GCC_JIT_COMPARISON_GE,
                          i, n);

and can then use this to add `b_loop_cond`'s sole statement, via
:func:`gccjit::block::end_with_conditional`:

.. code-block:: c++

  b_loop_cond.end_with_conditional (guard,
                                    b_after_loop, // on_true
                                    b_loop_body); // on_false

However :type:`gccjit::rvalue` has overloaded operators for this, so we
express the conditional as

.. code-block:: c++

   gccjit::rvalue guard = (i >= n);

and hence we can write the block more concisely as:

.. code-block:: c++

  b_loop_cond.end_with_conditional (
    i >= n,
    b_after_loop, // on_true
    b_loop_body); // on_false

Next, we populate the body of the loop.

The C statement `sum += i * i;` is an assignment operation, where an
lvalue is modified "in-place".  We use
:func:`gccjit::block::add_assignment_op` to handle these operations:

.. code-block:: c++

  /* sum += i * i */
  b_loop_body.add_assignment_op (sum,
                                 GCC_JIT_BINARY_OP_PLUS,
                                 i * i);

The `i++` can be thought of as `i += 1`, and can thus be handled in
a similar way.  We use :c:func:`gcc_jit_context_one` to get the constant
value `1` (for the relevant type) for the right-hand side
of the assignment.

.. code-block:: c++

  /* i++ */
  b_loop_body.add_assignment_op (i,
                                 GCC_JIT_BINARY_OP_PLUS,
                                 ctxt.one (the_type));

.. note::

  For numeric constants other than 0 or 1, we could use
  :func:`gccjit::context::new_rvalue`, which has overloads
  for both ``int`` and ``double``.

The loop body completes by jumping back to the conditional:

.. code-block:: c++

  b_loop_body.end_with_jump (b_loop_cond);

Finally, we populate the `b_after_loop` block, reached when the loop
conditional is false.  We want to generate the equivalent of:

.. code-block:: c++

   return sum;

so the block is just one statement:

.. code-block:: c++

  /* return sum */
  b_after_loop.end_with_return (sum);

.. note::

   You can intermingle block creation with statement creation,
   but given that the terminator statements generally include references
   to other blocks, I find it's clearer to create all the blocks,
   *then* all the statements.

We've finished populating the function.  As before, we can now compile it
to machine code:

.. code-block:: c++

   gcc_jit_result *result;
   result = ctxt.compile ();

   ctxt.release ();

   if (!result)
     {
       fprintf (stderr, "NULL result");
       return 1;
     }

   typedef int (*loop_test_fn_type) (int);
   loop_test_fn_type loop_test =
    (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
   if (!loop_test)
     {
       fprintf (stderr, "NULL loop_test");
       gcc_jit_result_release (result);
       return 1;
     }
   printf ("result: %d", loop_test (10));

.. code-block:: bash

   result: 285


Visualizing the control flow graph
**********************************

You can see the control flow graph of a function using
:func:`gccjit::function::dump_to_dot`:

.. code-block:: c++

  func.dump_to_dot ("/tmp/sum-of-squares.dot");

giving a .dot file in GraphViz format.

You can convert this to an image using `dot`:

.. code-block:: bash

   $ dot -Tpng /tmp/sum-of-squares.dot -o /tmp/sum-of-squares.png

or use a viewer (my preferred one is xdot.py; see
https://github.com/jrfonseca/xdot.py; on Fedora you can
install it with `yum install python-xdot`):

    .. figure:: ../../intro/sum-of-squares.png
      :alt: image of a control flow graph

Full example
************

   .. literalinclude:: ../../examples/tut03-sum-of-squares.cc
    :lines: 1-
    :language: c++

Building and running it:

.. code-block:: console

  $ gcc \
      tut03-sum-of-squares.cc \
      -o tut03-sum-of-squares \
      -lgccjit

  # Run the built program:
  $ ./tut03-sum-of-squares
  loop_test returned: 285

---

### Gcc Jit Docs Cp Intro Tutorial04 (`gcc/jit/docs/cp/intro/tutorial04.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Tutorial part 4: Adding JIT-compilation to a toy interpreter
------------------------------------------------------------
In this example we construct a "toy" interpreter, and add JIT-compilation
to it.

Our toy interpreter
*******************

It's a stack-based interpreter, and is intended as a (very simple) example
of the kind of bytecode interpreter seen in dynamic languages such as
Python, Ruby etc.

For the sake of simplicity, our toy virtual machine is very limited:

  * The only data type is `int`

  * It can only work on one function at a time (so that the only
    function call that can be made is to recurse).

  * Functions can only take one parameter.

  * Functions have a stack of `int` values.

  * We'll implement function call within the interpreter by calling a
    function in our implementation, rather than implementing our own
    frame stack.

  * The parser is only good enough to get the examples to work.

Naturally, a real interpreter would be much more complicated that this.

The following operations are supported:

.. list-table::
   :header-rows: 1
   :widths: 35 50 25 25

   * - Operation
     - Meaning
     - Old Stack
     - New Stack

   * - DUP
     - Duplicate top of stack.
     - ``[..., x]``
     - ``[..., x, x]``
   * - ROT
     - Swap top two elements of stack.
     - ``[..., x, y]``
     - ``[..., y, x]``
   * - BINARY_ADD
     - Add the top two elements on the stack.
     - ``[..., x, y]``
     - ``[..., (x+y)]``
   * - BINARY_SUBTRACT
     - Likewise, but subtract.
     - ``[..., x, y]``
     - ``[..., (x-y)]``
   * - BINARY_MULT
     - Likewise, but multiply.
     - ``[..., x, y]``
     - ``[..., (x*y)]``
   * - BINARY_COMPARE_LT
     - Compare the top two elements on the stack and push a nonzero/zero if (x<y).
     - ``[..., x, y]``
     - ``[..., (x<y)]``
   * - RECURSE
     - Recurse, passing the top of the stack, and popping the result.
     - ``[..., x]``
     - ``[..., fn(x)]``
   * - RETURN
     - Return the top of the stack.
     - ``[x]``
     - ``[]``
   * - PUSH_CONST `arg`
     - Push an int const.
     - ``[...]``
     - ``[..., arg]``
   * - JUMP_ABS_IF_TRUE `arg`
     - Pop; if top of stack was nonzero, jump to ``arg``.
     - ``[..., x]``
     - ``[...]``

Programs can be interpreted, disassembled, and compiled to machine code.

The interpreter reads ``.toy`` scripts.  Here's what a simple recursive
factorial program looks like, the script ``factorial.toy``.
The parser ignores lines beginning with a `#`.

   .. literalinclude:: ../../examples/tut04-toyvm/factorial.toy
    :lines: 1-
    :language: c

The interpreter is a simple infinite loop with a big ``switch`` statement
based on what the next opcode is:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Execute the given function.  */
    :end-before: /* JIT compilation.  */
    :language: c++

Compiling to machine code
*************************
We want to generate machine code that can be cast to this type and
then directly executed in-process:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Functions are compiled to this function ptr type.  */
    :end-before: enum opcode
    :language: c++

Our compiler isn't very sophisticated; it takes the implementation of
each opcode above, and maps it directly to the operations supported by
the libgccjit API.

How should we handle the stack?  In theory we could calculate what the
stack depth will be at each opcode, and optimize away the stack
manipulation "by hand".  We'll see below that libgccjit is able to do
this for us, so we'll implement stack manipulation
in a direct way, by creating a ``stack`` array and ``stack_depth``
variables, local within the generated function, equivalent to this C code:

.. code-block:: c

  int stack_depth;
  int stack[MAX_STACK_DEPTH];

We'll also have local variables ``x`` and ``y`` for use when implementing
the opcodes, equivalent to this:

.. code-block:: c

  int x;
  int y;

This means our compiler has the following state:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after:   /* State.  */
    :end-before: };
    :language: c++

Setting things up
*****************

First we create our types:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Create types.  */
    :end-before: /* The constant value 1.  */
    :language: c++

along with extracting a useful `int` constant:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* The constant value 1.  */
    :end-before: /* Create locations.  */
    :language: c++

We'll implement push and pop in terms of the ``stack`` array and
``stack_depth``.  Here are helper functions for adding statements to
a block, implementing pushing and popping values:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Stack manipulation.  */
    :end-before: /* Create the context. */
    :language: c++

We will support single-stepping through the generated code in the
debugger, so we need to create :type:`gccjit::location` instances, one
per operation in the source code.  These will reference the lines of
e.g. ``factorial.toy``.

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Create locations.  */
    :end-before: /* Creating the function.  */
    :language: c++

Let's create the function itself.  As usual, we create its parameter
first, then use the parameter to create the function:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Creating the function.  */
    :end-before: /* Create stack lvalues.  */
    :language: c++

We create the locals within the function.

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Create stack lvalues.  */
    :end-before: /* 1st pass: create blocks, one per opcode.
    :language: c++

Populating the function
***********************

There's some one-time initialization, and the API treats the first block
you create as the entrypoint of the function, so we need to create that
block first:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: first.  */
    :end-before: /* Create a block per operation.  */
    :language: c++

We can now create blocks for each of the operations.  Most of these will
be consolidated into larger blocks when the optimizer runs.

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Create a block per operation.  */
    :end-before: /* Populate the initial block.  */
    :language: c++

Now that we have a block it can jump to when it's done, we can populate
the initial block:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Populate the initial block.  */
    :end-before: /* 2nd pass: fill in instructions.  */
    :language: c++

We can now populate the blocks for the individual operations.  We loop
through them, adding instructions to their blocks:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* 2nd pass: fill in instructions.  */
    :end-before: /* Helper macros.  */
    :language: c++

We're going to have another big ``switch`` statement for implementing
the opcodes, this time for compiling them, rather than interpreting
them.  It's helpful to have macros for implementing push and pop, so that
we can make the ``switch`` statement that's coming up look as much as
possible like the one above within the interpreter:

.. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Helper macros.  */
    :end-before: block.add_comment
    :language: c++

.. note::

   A particularly clever implementation would have an *identical*
   ``switch`` statement shared by the interpreter and the compiler, with
   some preprocessor "magic".  We're not doing that here, for the sake
   of simplicity.

When I first implemented this compiler, I accidentally missed an edit
when copying and pasting the ``Y_EQUALS_POP`` macro, so that popping the
stack into ``y`` instead erroneously assigned it to ``x``, leaving ``y``
uninitialized.

To track this kind of thing down, we can use
:func:`gccjit::block::add_comment` to add descriptive comments
to the internal representation.  This is invaluable when looking through
the generated IR for, say ``factorial``:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: PUSH_RVALUE (y)
    :end-before: /* Handle the individual opcodes.  */
    :language: c++

We can now write the big ``switch`` statement that implements the
individual opcodes, populating the relevant block with statements:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Handle the individual opcodes.  */
    :end-before: /* Go to the next block.  */
    :language: c++

Every block must be terminated, via a call to one of the
``gccjit::block::end_with_`` entrypoints.  This has been done for two
of the opcodes, but we need to do it for the other ones, by jumping
to the next block.

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Go to the next block.  */
    :end-before: /* end of loop on PC locations.  */
    :language: c++

This is analogous to simply incrementing the program counter.

Verifying the control flow graph
********************************
Having finished looping over the blocks, the context is complete.

As before, we can verify that the control flow and statements are sane by
using :func:`gccjit::function::dump_to_dot`:

.. code-block:: c++

  fn.dump_to_dot ("/tmp/factorial.dot");

and viewing the result.  Note how the label names, comments, and
variable names show up in the dump, to make it easier to spot
errors in our compiler.

  .. figure:: ../../intro/factorial.png
    :alt: image of a control flow graph

Compiling the context
*********************
Having finished looping over the blocks and populating them with
statements, the context is complete.

We can now compile it, extract machine code from the result, and
run it:

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* Wrapper around a gcc_jit_result *.  */
    :end-before: /* Functions are compiled to this function ptr type.  */
    :language: c++

   .. literalinclude:: ../../examples/tut04-toyvm/toyvm.cc
    :start-after: /* JIT-compilation.  */
    :end-before: return 0;
    :language: c++

Single-stepping through the generated code
******************************************

It's possible to debug the generated code.  To do this we need to both:

  * Set up source code locations for our statements, so that we can
    meaningfully step through the code.  We did this above by
    calling :func:`gccjit::context::new_location` and using the
    results.

  * Enable the generation of debugging information, by setting
    :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` on the
    :type:`gccjit::context` via
    :func:`gccjit::context::set_bool_option`:

    .. code-block:: c++

      ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);

Having done this, we can put a breakpoint on the generated function:

.. code-block:: console

  $ gdb --args ./toyvm factorial.toy 10
  (gdb) break factorial
  Function "factorial" not defined.
  Make breakpoint pending on future shared library load? (y or [n]) y
  Breakpoint 1 (factorial) pending.
  (gdb) run
  Breakpoint 1, factorial (arg=10) at factorial.toy:14
  14	DUP

We've set up location information, which references ``factorial.toy``.
This allows us to use e.g. ``list`` to see where we are in the script:

.. code-block:: console

  (gdb) list
  9
  10    # Initial state:
  11    # stack: [arg]
  12
  13    # 0:
  14    DUP
  15    # stack: [arg, arg]
  16
  17    # 1:
  18    PUSH_CONST 2

and to step through the function, examining the data:

.. code-block:: console

  (gdb) n
  18    PUSH_CONST 2
  (gdb) n
  22    BINARY_COMPARE_LT
  (gdb) print stack
  $5 = {10, 10, 2, 0, -7152, 32767, 0, 0}
  (gdb) print stack_depth
  $6 = 3

You'll see that the parts of the ``stack`` array that haven't been
touched yet are uninitialized.

.. note::

   Turning on optimizations may lead to unpredictable results when
   stepping through the generated code: the execution may appear to
   "jump around" the source code.  This is analogous to turning up the
   optimization level in a regular compiler.

Examining the generated code
****************************

How good is the optimized code?

We can turn up optimizations, by calling
:cpp:func:`gccjit::context::set_int_option` with
:c:macro:`GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL`:

.. code-block:: c++

  ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);

One of GCC's internal representations is called "gimple".  A dump of the
initial gimple representation of the code can be seen by setting:

.. code-block:: c++

  ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1);

With optimization on and source locations displayed, this gives:

.. We'll use "c" for gimple dumps

.. code-block:: c

  factorial (signed int arg)
  {
    <unnamed type> D.80;
    signed int D.81;
    signed int D.82;
    signed int D.83;
    signed int D.84;
    signed int D.85;
    signed int y;
    signed int x;
    signed int stack_depth;
    signed int stack[8];

    try
      {
        initial:
        stack_depth = 0;
        stack[stack_depth] = arg;
        stack_depth = stack_depth + 1;
        goto instr0;
        instr0:
        /* DUP */:
        stack_depth = stack_depth + -1;
        x = stack[stack_depth];
        stack[stack_depth] = x;
        stack_depth = stack_depth + 1;
        stack[stack_depth] = x;
        stack_depth = stack_depth + 1;
        goto instr1;
        instr1:
        /* PUSH_CONST */:
        stack[stack_depth] = 2;
        stack_depth = stack_depth + 1;
        goto instr2;

        /* etc */

You can see the generated machine code in assembly form via:

.. code-block:: c++

  ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 1);
  result = ctxt.compile ();

which shows that (on this x86_64 box) the compiler has unrolled the loop
and is using MMX instructions to perform several multiplications
simultaneously:

.. code-block:: gas

          .file   "fake.c"
          .text
  .Ltext0:
          .p2align 4,,15
          .globl  factorial
          .type   factorial, @function
  factorial:
  .LFB0:
          .file 1 "factorial.toy"
          .loc 1 14 0
          .cfi_startproc
  .LVL0:
  .L2:
          .loc 1 26 0
          cmpl    $1, %edi
          jle     .L13
          leal    -1(%rdi), %edx
          movl    %edx, %ecx
          shrl    $2, %ecx
          leal    0(,%rcx,4), %esi
          testl   %esi, %esi
          je      .L14
          cmpl    $9, %edx
          jbe     .L14
          leal    -2(%rdi), %eax
          movl    %eax, -16(%rsp)
          leal    -3(%rdi), %eax
          movd    -16(%rsp), %xmm0
          movl    %edi, -16(%rsp)
          movl    %eax, -12(%rsp)
          movd    -16(%rsp), %xmm1
          xorl    %eax, %eax
          movl    %edx, -16(%rsp)
          movd    -12(%rsp), %xmm4
          movd    -16(%rsp), %xmm6
          punpckldq       %xmm4, %xmm0
          movdqa  .LC1(%rip), %xmm4
          punpckldq       %xmm6, %xmm1
          punpcklqdq      %xmm0, %xmm1
          movdqa  .LC0(%rip), %xmm0
          jmp     .L5
          # etc - edited for brevity

This is clearly overkill for a function that will likely overflow the
``int`` type before the vectorization is worthwhile - but then again, this
is a toy example.

Turning down the optimization level to 2:

.. code-block:: c++

  ctxt.set_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 2);

yields this code, which is simple enough to quote in its entirety:

.. code-block:: gas

          .file   "fake.c"
          .text
          .p2align 4,,15
          .globl  factorial
          .type   factorial, @function
  factorial:
  .LFB0:
          .cfi_startproc
  .L2:
          cmpl    $1, %edi
          jle     .L8
          movl    $1, %edx
          jmp     .L4
          .p2align 4,,10
          .p2align 3
  .L6:
          movl    %eax, %edi
  .L4:
  .L5:
          leal    -1(%rdi), %eax
          imull   %edi, %edx
          cmpl    $1, %eax
          jne     .L6
  .L3:
  .L7:
          imull   %edx, %eax
          ret
  .L8:
          movl    %edi, %eax
          movl    $1, %edx
          jmp     .L7
          .cfi_endproc
  .LFE0:
          .size   factorial, .-factorial
          .ident  "GCC: (GNU) 4.9.0 20131023 (Red Hat 0.2)"
          .section        .note.GNU-stack,"",@progbits

Note that the stack pushing and popping have been eliminated, as has the
recursive call (in favor of an iteration).

Putting it all together
***********************

The complete example can be seen in the source tree at
``gcc/jit/docs/examples/tut04-toyvm/toyvm.cc``

along with a Makefile and a couple of sample .toy scripts:

.. code-block:: console

  $ ls -al
  drwxrwxr-x. 2 david david   4096 Sep 19 17:46 .
  drwxrwxr-x. 3 david david   4096 Sep 19 15:26 ..
  -rw-rw-r--. 1 david david    615 Sep 19 12:43 factorial.toy
  -rw-rw-r--. 1 david david    834 Sep 19 13:08 fibonacci.toy
  -rw-rw-r--. 1 david david    238 Sep 19 14:22 Makefile
  -rw-rw-r--. 1 david david  16457 Sep 19 17:07 toyvm.cc

  $ make toyvm
  g++ -Wall -g -o toyvm toyvm.cc -lgccjit

  $ ./toyvm factorial.toy 10
  interpreter result: 3628800
  compiler result: 3628800

  $ ./toyvm fibonacci.toy 10
  interpreter result: 55
  compiler result: 55

Behind the curtain: How does our code get optimized?
****************************************************

Our example is done, but you may be wondering about exactly how the
compiler turned what we gave it into the machine code seen above.

We can examine what the compiler is doing in detail by setting:

.. code-block:: c++

  state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING, 1);
  state.ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES, 1);

This will dump detailed information about the compiler's state to a
directory under ``/tmp``, and keep it from being cleaned up.

The precise names and their formats of these files is subject to change.
Higher optimization levels lead to more files.
Here's what I saw (edited for brevity; there were almost 200 files):

.. code-block:: console

  intermediate files written to /tmp/libgccjit-KPQbGw
  $ ls /tmp/libgccjit-KPQbGw/
  fake.c.000i.cgraph
  fake.c.000i.type-inheritance
  fake.c.004t.gimple
  fake.c.007t.omplower
  fake.c.008t.lower
  fake.c.011t.eh
  fake.c.012t.cfg
  fake.c.014i.visibility
  fake.c.015i.early_local_cleanups
  fake.c.016t.ssa
  # etc

The gimple code is converted into Static Single Assignment form,
with annotations for use when generating the debuginfo:

.. code-block:: console

  $ less /tmp/libgccjit-KPQbGw/fake.c.016t.ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;
    signed int _56;

  initial:
    stack_depth_3 = 0;
    # DEBUG stack_depth => stack_depth_3
    stack[stack_depth_3] = arg_5(D);
    stack_depth_7 = stack_depth_3 + 1;
    # DEBUG stack_depth => stack_depth_7
    # DEBUG instr0 => NULL
    # DEBUG /* DUP */ => NULL
    stack_depth_8 = stack_depth_7 + -1;
    # DEBUG stack_depth => stack_depth_8
    x_9 = stack[stack_depth_8];
    # DEBUG x => x_9
    stack[stack_depth_8] = x_9;
    stack_depth_11 = stack_depth_8 + 1;
    # DEBUG stack_depth => stack_depth_11
    stack[stack_depth_11] = x_9;
    stack_depth_13 = stack_depth_11 + 1;
    # DEBUG stack_depth => stack_depth_13
    # DEBUG instr1 => NULL
    # DEBUG /* PUSH_CONST */ => NULL
    stack[stack_depth_13] = 2;

    /* etc; edited for brevity */

We can perhaps better see the code by turning off
:c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to suppress all those ``DEBUG``
statements, giving:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.016t.ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;
    signed int _56;

  initial:
    stack_depth_3 = 0;
    stack[stack_depth_3] = arg_5(D);
    stack_depth_7 = stack_depth_3 + 1;
    stack_depth_8 = stack_depth_7 + -1;
    x_9 = stack[stack_depth_8];
    stack[stack_depth_8] = x_9;
    stack_depth_11 = stack_depth_8 + 1;
    stack[stack_depth_11] = x_9;
    stack_depth_13 = stack_depth_11 + 1;
    stack[stack_depth_13] = 2;
    stack_depth_15 = stack_depth_13 + 1;
    stack_depth_16 = stack_depth_15 + -1;
    y_17 = stack[stack_depth_16];
    stack_depth_18 = stack_depth_16 + -1;
    x_19 = stack[stack_depth_18];
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack[stack_depth_18] = _21;
    stack_depth_23 = stack_depth_18 + 1;
    stack_depth_24 = stack_depth_23 + -1;
    x_25 = stack[stack_depth_24];
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    stack_depth_26 = stack_depth_24 + -1;
    x_27 = stack[stack_depth_26];
    stack[stack_depth_26] = x_27;
    stack_depth_29 = stack_depth_26 + 1;
    stack[stack_depth_29] = x_27;
    stack_depth_31 = stack_depth_29 + 1;
    stack[stack_depth_31] = 1;
    stack_depth_33 = stack_depth_31 + 1;
    stack_depth_34 = stack_depth_33 + -1;
    y_35 = stack[stack_depth_34];
    stack_depth_36 = stack_depth_34 + -1;
    x_37 = stack[stack_depth_36];
    _38 = x_37 - y_35;
    stack[stack_depth_36] = _38;
    stack_depth_40 = stack_depth_36 + 1;
    stack_depth_41 = stack_depth_40 + -1;
    x_42 = stack[stack_depth_41];
    _44 = factorial (x_42);
    stack[stack_depth_41] = _44;
    stack_depth_46 = stack_depth_41 + 1;
    stack_depth_47 = stack_depth_46 + -1;
    y_48 = stack[stack_depth_47];
    stack_depth_49 = stack_depth_47 + -1;
    x_50 = stack[stack_depth_49];
    _51 = x_50 * y_48;
    stack[stack_depth_49] = _51;
    stack_depth_53 = stack_depth_49 + 1;

    # stack_depth_1 = PHI <stack_depth_24(2), stack_depth_53(3)>
  instr9:
  /* RETURN */:
    stack_depth_54 = stack_depth_1 + -1;
    x_55 = stack[stack_depth_54];
    _56 = x_55;
    stack ={v} {CLOBBER};
    return _56;

  }

Note in the above how all the :type:`gccjit::block` instances we
created have been consolidated into just 3 blocks in GCC's internal
representation: ``initial``, ``instr4`` and ``instr9``.

Optimizing away stack manipulation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Recall our simple implementation of stack operations.  Let's examine
how the stack operations are optimized away.

After a pass of constant-propagation, the depth of the stack at each
opcode can be determined at compile-time:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.021t.ccp1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack[0] = arg_5(D);
    x_9 = stack[0];
    stack[0] = x_9;
    stack[1] = x_9;
    stack[2] = 2;
    y_17 = stack[2];
    x_19 = stack[1];
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack[1] = _21;
    x_25 = stack[1];
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    x_27 = stack[0];
    stack[0] = x_27;
    stack[1] = x_27;
    stack[2] = 1;
    y_35 = stack[2];
    x_37 = stack[1];
    _38 = x_37 - y_35;
    stack[1] = _38;
    x_42 = stack[1];
    _44 = factorial (x_42);
    stack[1] = _44;
    y_48 = stack[1];
    x_50 = stack[0];
    _51 = x_50 * y_48;
    stack[0] = _51;

  instr9:
  /* RETURN */:
    x_55 = stack[0];
    x_56 = x_55;
    stack ={v} {CLOBBER};
    return x_56;

  }

Note how, in the above, all those ``stack_depth`` values are now just
constants: we're accessing specific stack locations at each opcode.

The "esra" pass ("Early Scalar Replacement of Aggregates") breaks
out our "stack" array into individual elements:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.024t.esra

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  Created a replacement for stack offset: 0, size: 32: stack$0
  Created a replacement for stack offset: 32, size: 32: stack$1
  Created a replacement for stack offset: 64, size: 32: stack$2

  Symbols to be put in SSA form
  { D.89 D.90 D.91 }
  Incremental SSA update started at block: 0
  Number of blocks in CFG: 5
  Number of blocks to update: 4 ( 80%)


  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack$0_45 = arg_5(D);
    x_9 = stack$0_45;
    stack$0_39 = x_9;
    stack$1_32 = x_9;
    stack$2_30 = 2;
    y_17 = stack$2_30;
    x_19 = stack$1_32;
    _20 = x_19 < y_17;
    _21 = (signed int) _20;
    stack$1_28 = _21;
    x_25 = stack$1_28;
    if (x_25 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    x_27 = stack$0_39;
    stack$0_22 = x_27;
    stack$1_14 = x_27;
    stack$2_12 = 1;
    y_35 = stack$2_12;
    x_37 = stack$1_14;
    _38 = x_37 - y_35;
    stack$1_10 = _38;
    x_42 = stack$1_10;
    _44 = factorial (x_42);
    stack$1_6 = _44;
    y_48 = stack$1_6;
    x_50 = stack$0_22;
    _51 = x_50 * y_48;
    stack$0_1 = _51;

    # stack$0_52 = PHI <stack$0_39(2), stack$0_1(3)>
  instr9:
  /* RETURN */:
    x_55 = stack$0_52;
    x_56 = x_55;
    stack ={v} {CLOBBER};
    return x_56;

  }

Hence at this point, all those pushes and pops of the stack are now
simply assignments to specific temporary variables.

After some copy propagation, the stack manipulation has been completely
optimized away:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.026t.copyprop1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int _44;
    signed int _51;

  initial:
    stack$0_39 = arg_5(D);
    _20 = arg_5(D) <= 1;
    _21 = (signed int) _20;
    if (_21 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _38 = arg_5(D) + -1;
    _44 = factorial (_38);
    _51 = arg_5(D) * _44;
    stack$0_1 = _51;

    # stack$0_52 = PHI <arg_5(D)(2), _51(3)>
  instr9:
  /* RETURN */:
    stack ={v} {CLOBBER};
    return stack$0_52;

  }

Later on, another pass finally eliminated ``stack_depth`` local and the
unused parts of the `stack`` array altogether:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.036t.release_ssa

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)

  Released 44 names, 314.29%, removed 44 holes
  factorial (signed int arg)
  {
    signed int stack$0;
    signed int mult_acc_1;
    <unnamed type> _5;
    signed int _6;
    signed int _7;
    signed int mul_tmp_10;
    signed int mult_acc_11;
    signed int mult_acc_13;

    # arg_9 = PHI <arg_8(D)(0)>
    # mult_acc_13 = PHI <1(0)>
  initial:

    <bb 5>:
    # arg_4 = PHI <arg_9(2), _7(3)>
    # mult_acc_1 = PHI <mult_acc_13(2), mult_acc_11(3)>
    _5 = arg_4 <= 1;
    _6 = (signed int) _5;
    if (_6 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _7 = arg_4 + -1;
    mult_acc_11 = mult_acc_1 * arg_4;
    goto <bb 5>;

    # stack$0_12 = PHI <arg_4(5)>
  instr9:
  /* RETURN */:
    mul_tmp_10 = mult_acc_1 * stack$0_12;
    return mul_tmp_10;

  }


Elimination of tail recursion
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another significant optimization is the detection that the call to
``factorial`` is tail recursion, which can be eliminated in favor of
an iteration:

.. code-block:: console

  $ less /tmp/libgccjit-1Hywc0/fake.c.030t.tailr1

.. code-block:: c

  ;; Function factorial (factorial, funcdef_no=0, decl_uid=53, symbol_order=0)


  Symbols to be put in SSA form
  { D.88 }
  Incremental SSA update started at block: 0
  Number of blocks in CFG: 5
  Number of blocks to update: 4 ( 80%)


  factorial (signed int arg)
  {
    signed int stack$2;
    signed int stack$1;
    signed int stack$0;
    signed int stack[8];
    signed int stack_depth;
    signed int x;
    signed int y;
    signed int mult_acc_1;
    <unnamed type> _20;
    signed int _21;
    signed int _38;
    signed int mul_tmp_44;
    signed int mult_acc_51;

    # arg_5 = PHI <arg_39(D)(0), _38(3)>
    # mult_acc_1 = PHI <1(0), mult_acc_51(3)>
  initial:
    _20 = arg_5 <= 1;
    _21 = (signed int) _20;
    if (_21 != 0)
      goto <bb 4> (instr9);
    else
      goto <bb 3> (instr4);

  instr4:
  /* DUP */:
    _38 = arg_5 + -1;
    mult_acc_51 = mult_acc_1 * arg_5;
    goto <bb 2> (initial);

    # stack$0_52 = PHI <arg_5(2)>
  instr9:
  /* RETURN */:
    stack ={v} {CLOBBER};
    mul_tmp_44 = mult_acc_1 * stack$0_52;
    return mul_tmp_44;

  }

---

### Gcc Jit Docs Cp Topics Asm (`gcc/jit/docs/cp/topics/asm.rst`)

.. Copyright (C) 2020-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Using Assembly Language with libgccjit++
========================================

libgccjit has some support for directly embedding assembler instructions.
This is based on GCC's support for inline ``asm`` in C code, and the
following assumes a familiarity with that functionality.  See
`How to Use Inline Assembly Language in C Code <https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html>`_
in GCC's documentation, the "Extended Asm" section in particular.

These entrypoints were added in :ref:`LIBGCCJIT_ABI_15`; you can test
for their presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_ASM_STATEMENTS

Adding assembler instructions within a function
***********************************************

.. class:: gccjit::extended_asm

   A `gccjit::extended_asm` represents an extended ``asm`` statement: a
   series of low-level instructions inside a function that convert inputs
   to outputs.

   :class:`gccjit::extended_asm` is a subclass of :class:`gccjit::object`.
   It is a thin wrapper around the C API's :c:expr:`gcc_jit_extended_asm *`.

   To avoid having an API entrypoint with a very large number of
   parameters, an extended ``asm`` statement is made in stages:
   an initial call to create the :type:`gccjit::extended_asm`,
   followed by calls to add operands and set other properties of the
   statement.

   There are two API entrypoints for creating a :type:`gccjit::extended_asm`:

   * :func:`gccjit::block::add_extended_asm` for an ``asm`` statement with
     no control flow, and

   * :func:`gccjit::block::end_with_extended_asm_goto` for an ``asm goto``.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: // Quote from here in docs/cp/topics/asm.rst: example 1: C
      :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 1: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 1: jit.  */
      :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 1: jit.  */
      :language: c

   .. warning::  When considering the numbering of operands within an
		 extended ``asm`` statement (e.g. the ``%0`` and ``%1``
		 above), the equivalent to the C syntax is followed i.e. all
		 output operands, then all input operands, regardless of
		 what order the calls to
		 :func:`gccjit::extended_asm::add_output_operand` and
		 :func:`gccjit::extended_asm::add_input_operand` were made in.

   As in the C syntax, operands can be given symbolic names to avoid having
   to number them.  For example, to create the equivalent of:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: // Quote from here in docs/cp/topics/asm.rst: example 2: C
      :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 2: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 2: jit.  */
      :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 2: jit.  */
      :language: c

.. function:: extended_asm \
	      gccjit::block::add_extended_asm (const std::string &asm_template,\
                                               gccjit::location loc = location ())

   Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
   with no control flow (i.e. without the ``goto`` qualifier).

   The parameter ``asm_template`` corresponds to the `AssemblerTemplate`
   within C's extended ``asm`` syntax.  It must be non-NULL.  The call takes
   a copy of the underlying string, so it is valid to pass in a pointer to
   an on-stack buffer.

.. function:: extended_asm\
              gccjit::block::end_with_extended_asm_goto (const std::string &asm_template,\
                                                         std::vector<block> goto_blocks,\
                                                         block *fallthrough_block,\
                                                         location loc = location ())

   Create a :type:`gccjit::extended_asm` for an extended ``asm`` statement
   that may perform jumps, and use it to terminate the given block.
   This is equivalent to the ``goto`` qualifier in C's extended ``asm``
   syntax.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: // Quote from here in docs/cp/topics/asm.rst: example 3b: C
      :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 3b: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 3: jit.  */
      :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 3: jit.  */
      :language: c

   here referencing a :type:`gcc_jit_block` named "carry".

   ``num_goto_blocks`` corresponds to the ``GotoLabels`` parameter within C's
   extended ``asm`` syntax.  The block names can be referenced within the
   assembler template.

   ``fallthrough_block`` can be NULL.  If non-NULL, it specifies the block
   to fall through to after the statement.

   .. note:: This is needed since each :type:`gccjit::block` must have a
	     single exit point, as a basic block: you can't jump from the
	     middle of a block.  A "goto" is implicitly added after the
	     asm to handle the fallthrough case, which is equivalent to what
	     would have happened in the C case.

.. function:: gccjit::extended_asm &\
	      gccjit::extended_asm::set_volatile_flag (bool flag)

   Set whether the :type:`gccjit::extended_asm` has side-effects, equivalent to the
   `volatile <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile>`_
   qualifier in C's extended asm syntax.

   For example, to create the equivalent of:

   .. code-block:: c

      asm volatile ("rdtsc\n\t"    // Returns the time in EDX:EAX.
                     "shl $32, %%rdx\n\t"  // Shift the upper bits left.
                     "or %%rdx, %0"        // 'Or' in the lower bits.
                     : "=a" (msr)
                     :
                     : "rdx");

   the following API calls could be used:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 4: jit.  */
      :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 4: jit.  */
      :language: c

   where the :type:`gccjit::extended_asm` is flagged as volatile.

.. function::  gccjit::extended_asm &\
	       gccjit::extended_asm::set_inline_flag (bool flag)

   Set the equivalent of the
   `inline <https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html#Size-of-an-asm>`_
   qualifier in C's extended ``asm`` syntax.

.. function:: gccjit::extended_asm&\
	      gccjit::extended_asm::add_output_operand (const std::string &asm_symbolic_name,\
                                                        const std::string &constraint,\
                                                        gccjit::lvalue dest)

   Add an output operand to the extended ``asm`` statement.  See the
   `Output Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands>`_
   section of the documentation of the C syntax.

   ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component of
   C's extended ``asm`` syntax, and specifies the symbolic name for the operand.
   See the overload below for an alternative that does not supply a symbolic
   name.

   ``constraint`` corresponds to the ``constraint`` component of C's extended
   ``asm`` syntax.

   ``dest`` corresponds to the ``cvariablename`` component of C's extended
   ``asm`` syntax.

   .. code-block:: c++

      // Example with a symbolic name ("aIndex"), the equivalent of:
      //   : [aIndex] "=r" (index)
      ext_asm.add_output_operand ("aIndex", "=r", index);

   This function can't be called on an ``asm goto`` as such instructions can't
   have outputs; see the
   `Goto Labels <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels>`_
   section of GCC's "Extended Asm" documentation.

.. function:: gccjit::extended_asm&\
              gccjit::extended_asm::add_output_operand (const std::string &constraint,\
                                                        gccjit::lvalue dest)

   As above, but don't supply a symbolic name for the operand.

   .. code-block:: c++

      // Example without a symbolic name, the equivalent of:
      //   : "=r" (dst)
      ext_asm.add_output_operand ("=r", dst);

.. function:: gccjit::extended_asm&\
              gccjit::extended_asm::add_input_operand (const std::string &asm_symbolic_name, \
                                                       const std::string &constraint, \
                                                       gccjit::rvalue src)

   Add an input operand to the extended ``asm`` statement.  See the
   `Input Operands <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#InputOperands>`_
   section of the documentation of the C syntax.

   ``asm_symbolic_name`` corresponds to the ``asmSymbolicName`` component
   of C's extended ``asm`` syntax.  See the overload below for an alternative
   that does not supply a symbolic name.

   ``constraint`` corresponds to the ``constraint`` component of C's extended
   ``asm`` syntax.

   ``src`` corresponds to the ``cexpression`` component of C's extended
   ``asm`` syntax.

   .. code-block:: c++

      // Example with a symbolic name ("aMask"), the equivalent of:
      //   : [aMask] "r" (Mask)
      ext_asm.add_input_operand ("aMask", "r", mask);

.. function:: gccjit::extended_asm&\
              gccjit::extended_asm::add_input_operand (const std::string &constraint,\
                                                       gccjit::rvalue src)

   As above, but don't supply a symbolic name for the operand.

   .. code-block:: c++

      // Example without a symbolic name, the equivalent of:
      //   : "r" (src)
      ext_asm.add_input_operand ("r", src);

.. function:: gccjit::extended_asm&\
              gccjit::extended_asm::add_clobber (const std::string &victim)

   Add `victim` to the list of registers clobbered by the extended ``asm``
   statement.  See the
   `Clobbers and Scratch Registers <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers#>`_
   section of the documentation of the C syntax.

   Statements with multiple clobbers will require multiple calls, one per
   clobber.

   For example:

   .. code-block:: c++

     ext_asm.add_clobber ("r0").add_clobber ("cc").add_clobber ("memory");


Adding top-level assembler statements
*************************************

In addition to creating extended ``asm`` instructions within a function,
there is support for creating "top-level" assembler statements, outside
of any function.

.. function:: void\
              gccjit::context::add_top_level_asm (const char *asm_stmts,\
                                                  gccjit::location loc = location ())

   Create a set of top-level asm statements, analogous to those created
   by GCC's "basic" ``asm`` syntax in C at file scope.

   For example, to create the equivalent of:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: // Quote from here in docs/cp/topics/asm.rst: example 5: C
      :end-before: // Quote up to here in docs/cp/topics/asm.rst: example 5: C
      :language: c

   the following API calls could be used:

   .. literalinclude:: ../../../../testsuite/jit.dg/test-asm.cc
      :start-after: /* Quote from here in docs/cp/topics/asm.rst: example 5: jit.  */
      :end-before: /* Quote up to here in docs/cp/topics/asm.rst: example 5: jit.  */
      :language: c

---

### Gcc Jit Docs Cp Topics Compilation (`gcc/jit/docs/cp/topics/compilation.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Compiling a context
===================

Once populated, a :class:`gccjit::context` can be compiled to
machine code, either in-memory via :func:`gccjit::context::compile` or
to disk via :func:`gccjit::context::compile_to_file`.

You can compile a context multiple times (using either form of
compilation), although any errors that occur on the context will
prevent any future compilation of that context.

In-memory compilation
*********************

.. function:: gcc_jit_result *\
              gccjit::context::compile ()

   This calls into GCC and builds the code, returning a
   `gcc_jit_result *`.

   This is a thin wrapper around the
   :c:func:`gcc_jit_context_compile` API entrypoint.

Ahead-of-time compilation
*************************

Although libgccjit is primarily aimed at just-in-time compilation, it
can also be used for implementing more traditional ahead-of-time
compilers, via the :func:`gccjit::context::compile_to_file` method.

.. function:: void \
              gccjit::context::compile_to_file (enum gcc_jit_output_kind,\
                                                const char *output_path)

   Compile the :class:`gccjit::context` to a file of the given
   kind.

   This is a thin wrapper around the
   :c:func:`gcc_jit_context_compile_to_file` API entrypoint.

---

### Gcc Jit Docs Cp Topics Contexts (`gcc/jit/docs/cp/topics/contexts.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Compilation contexts
====================

.. class:: gccjit::context

The top-level of the C++ API is the :class:`gccjit::context` type.

A :class:`gccjit::context` instance encapsulates the state of a
compilation.

You can set up options on it, and add types, functions and code.
Invoking :func:`gccjit::context::compile` on it gives you a
:c:expr:`gcc_jit_result *`.

It is a thin wrapper around the C API's :c:expr:`gcc_jit_context *`.

Lifetime-management
-------------------
Contexts are the unit of lifetime-management within the API: objects
have their lifetime bounded by the context they are created within, and
cleanup of such objects is done for you when the context is released.

.. function:: gccjit::context gccjit::context::acquire ()

  This function acquires a new :class:`gccjit::context` instance,
  which is independent of any others that may be present within this
  process.

.. function:: void gccjit::context::release ()

  This function releases all resources associated with the given context.
  Both the context itself and all of its :expr:`gccjit::object *`
  instances are cleaned up.  It should be called exactly once on a given
  context.

  It is invalid to use the context or any of its "contextual" objects
  after calling this.

  .. code-block:: c++

    ctxt.release ();

.. function:: gccjit::context \
              gccjit::context::new_child_context ()

   Given an existing JIT context, create a child context.

   The child inherits a copy of all option-settings from the parent.

   The child can reference objects created within the parent, but not
   vice-versa.

   The lifetime of the child context must be bounded by that of the
   parent: you should release a child context before releasing the parent
   context.

   If you use a function from a parent context within a child context,
   you have to compile the parent context before you can compile the
   child context, and the gccjit::result of the parent context must
   outlive the gccjit::result of the child context.

   This allows caching of shared initializations.  For example, you could
   create types and declarations of global functions in a parent context
   once within a process, and then create child contexts whenever a
   function or loop becomes hot. Each such child context can be used for
   JIT-compiling just one function or loop, but can reference types
   and helper functions created within the parent context.

   Contexts can be arbitrarily nested, provided the above rules are
   followed, but it's probably not worth going above 2 or 3 levels, and
   there will likely be a performance hit for such nesting.


Thread-safety
-------------
Instances of :class:`gccjit::context` created via
:func:`gccjit::context::acquire` are independent from each other:
only one thread may use a given context at once, but multiple threads
could each have their own contexts without needing locks.

Contexts created via :func:`gccjit::context::new_child_context` are
related to their parent context.  They can be partitioned by their
ultimate ancestor into independent "family trees".   Only one thread
within a process may use a given "family tree" of such contexts at once,
and if you're using multiple threads you should provide your own locking
around entire such context partitions.


Error-handling
--------------
.. FIXME: How does error-handling work for C++ API?

You can only compile and get code from a context if no errors occur.

In general, if an error occurs when using an API entrypoint, it returns
NULL.  You don't have to check everywhere for NULL results, since the
API gracefully handles a NULL being passed in for any argument.

Errors are printed on stderr and can be queried using
:func:`gccjit::context::get_first_error`.

.. function:: const char *\
              gccjit::context::get_first_error (gccjit::context *ctxt)

   Returns the first error message that occurred on the context.

   The returned string is valid for the rest of the lifetime of the
   context.

   If no errors occurred, this will be NULL.

Debugging
---------

.. function:: void\
              gccjit::context::dump_to_file (const std::string &path, \
                                             int update_locations)

   To help with debugging: dump a C-like representation to the given path,
   describing what's been set up on the context.

   If "update_locations" is true, then also set up :class:`gccjit::location`
   information throughout the context, pointing at the dump file as if it
   were a source file.  This may be of use in conjunction with
   :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to allow stepping through the
   code in a debugger.

.. function:: void\
              gccjit::context::dump_reproducer_to_file (gcc_jit_context *ctxt,\
                                                        const char *path)

   This is a thin wrapper around the C API
   :c:func:`gcc_jit_context_dump_reproducer_to_file`, and hence works the
   same way.

   Note that the generated source is C code, not C++; this might be of use
   for seeing what the C++ bindings are doing at the C level.

Options
-------

String Options
**************

.. function:: void \
              gccjit::context::set_str_option (enum gcc_jit_str_option, \
                                               const char *value)

   Set a string option of the context.

   This is a thin wrapper around the C API
   :c:func:`gcc_jit_context_set_str_option`; the options have the same
   meaning.

Boolean options
***************

.. function:: void \
              gccjit::context::set_bool_option(enum gcc_jit_bool_option, \
                                               int value)

  Set a boolean option of the context.

  This is a thin wrapper around the C API
  :c:func:`gcc_jit_context_set_bool_option`; the options have the same
  meaning.

.. function:: void \
              gccjit::context::set_bool_allow_unreachable_blocks (int bool_value)

   By default, libgccjit will issue an error about unreachable blocks
   within a function.

   This entrypoint can be used to disable that error; it is a thin wrapper
   around the C API
   :c:func:`gcc_jit_context_set_bool_allow_unreachable_blocks`.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_2`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks

.. function:: void \
              gccjit::context::set_bool_use_external_driver (int bool_value)

   libgccjit internally generates assembler, and uses "driver" code
   for converting it to other formats (e.g. shared libraries).

   By default, libgccjit will use an embedded copy of the driver
   code.

   This option can be used to instead invoke an external driver executable
   as a subprocess; it is a thin wrapper around the C API
   :c:func:`gcc_jit_context_set_bool_use_external_driver`.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_5`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_use_external_driver

Integer options
***************

.. function:: void \
              gccjit::context::set_int_option (enum gcc_jit_int_option, \
                                               int value)

  Set an integer option of the context.

  This is a thin wrapper around the C API
  :c:func:`gcc_jit_context_set_int_option`; the options have the same
  meaning.

Additional command-line options
*******************************

.. function:: void \
              gccjit::context::add_command_line_option (const char *optname)

   Add an arbitrary gcc command-line option to the context for use
   when compiling.

   This is a thin wrapper around the C API
   :c:func:`gcc_jit_context_add_command_line_option`.

   This entrypoint was added in :ref:`LIBGCCJIT_ABI_1`; you can test for
   its presence using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option

---

### Gcc Jit Docs Cp Topics Expressions (`gcc/jit/docs/cp/topics/expressions.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Expressions
===========

Rvalues
-------
.. class:: gccjit::rvalue

A :class:`gccjit::rvalue` is an expression that can be computed.  It is a
subclass of :class:`gccjit::object`, and is a thin wrapper around
:c:expr:`gcc_jit_rvalue *` from the C API.

It can be simple, e.g.:

  * an integer value e.g. `0` or `42`
  * a string literal e.g. `"Hello world"`
  * a variable e.g. `i`.  These are also lvalues (see below).

or compound e.g.:

  * a unary expression e.g. `!cond`
  * a binary expression e.g. `(a + b)`
  * a function call e.g. `get_distance (&player_ship, &target)`
  * etc.

Every rvalue has an associated type, and the API will check to ensure
that types match up correctly (otherwise the context will emit an error).

.. function:: gccjit::type gccjit::rvalue::get_type ()

  Get the type of this rvalue.


Simple expressions
******************

.. function:: gccjit::rvalue \
              gccjit::context::new_rvalue (gccjit::type numeric_type, \
                                           int value) const

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`int` value.

.. function:: gccjit::rvalue \
              gccjit::context::new_rvalue (gccjit::type numeric_type, \
                                           long value) const

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`long` value.

.. function::  gccjit::rvalue \
               gccjit::context::zero (gccjit::type numeric_type) const

   Given a numeric type (integer or floating point), get the rvalue for
   zero.  Essentially this is just a shortcut for:

   .. code-block:: c++

      ctxt.new_rvalue (numeric_type, 0)

.. function::  gccjit::rvalue \
               gccjit::context::one (gccjit::type numeric_type) const

   Given a numeric type (integer or floating point), get the rvalue for
   one.  Essentially this is just a shortcut for:

   .. code-block:: c++

      ctxt.new_rvalue (numeric_type, 1)

.. function::  gccjit::rvalue \
               gccjit::context::new_rvalue (gccjit::type numeric_type, \
                                            double value) const

   Given a numeric type (integer or floating point), build an rvalue for
   the given constant :expr:`double` value.

.. function:: gccjit::rvalue \
              gccjit::context::new_rvalue (gccjit::type pointer_type, \
                                           void *value) const

   Given a pointer type, build an rvalue for the given address.

.. function:: gccjit::rvalue \
              gccjit::context::new_rvalue (const std::string &value) const

   Generate an rvalue of type :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` for
   the given string.  This is akin to a string literal.

Vector expressions
******************

.. function:: gccjit::rvalue \
	      gccjit::context::new_rvalue (gccjit::type vector_type, \
	                                   std::vector<gccjit::rvalue> elements) const

   Given a vector type, and a vector of scalar rvalue elements, generate a
   vector rvalue.

   The number of elements needs to match that of the vector type.

Unary Operations
****************

.. function:: gccjit::rvalue  \
              gccjit::context::new_unary_op (enum gcc_jit_unary_op, \
                                             gccjit::type result_type, \
                                             gccjit::rvalue rvalue, \
                                             gccjit::location loc)

   Build a unary operation out of an input rvalue.

   Parameter ``loc`` is optional.

   This is a thin wrapper around the C API's
   :c:func:`gcc_jit_context_new_unary_op` and the available unary
   operations are documented there.

There are shorter ways to spell the various specific kinds of unary
operation:

.. function:: gccjit::rvalue \
              gccjit::context::new_minus (gccjit::type result_type, \
                                          gccjit::rvalue a, \
                                          gccjit::location loc)

   Negate an arithmetic value; for example:

   .. code-block:: c++

      gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);

   builds the equivalent of this C expression:

   .. code-block:: c

      -pi

.. function:: gccjit::rvalue \
              new_bitwise_negate (gccjit::type result_type, \
                                  gccjit::rvalue a, \
                                  gccjit::location loc)

   Bitwise negation of an integer value (one's complement); for example:

   .. code-block:: c++

      gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);

   builds the equivalent of this C expression:

   .. code-block:: c

      ~a

.. function:: gccjit::rvalue \
              new_logical_negate (gccjit::type result_type, \
                                  gccjit::rvalue a, \
                                  gccjit::location loc)

   Logical negation of an arithmetic or pointer value; for example:

   .. code-block:: c++

      gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);

   builds the equivalent of this C expression:

   .. code-block:: c

      !cond


The most concise way to spell them is with overloaded operators:

.. function:: gccjit::rvalue operator- (gccjit::rvalue a)

   .. code-block:: c++

     gccjit::rvalue negpi = -pi;


.. function:: gccjit::rvalue operator~ (gccjit::rvalue a)

   .. code-block:: c++

      gccjit::rvalue mask = ~a;

.. function:: gccjit::rvalue operator! (gccjit::rvalue a)

   .. code-block:: c++

      gccjit::rvalue guard = !cond;


Binary Operations
*****************

.. function:: gccjit::rvalue\
              gccjit::context::new_binary_op (enum gcc_jit_binary_op, \
                                              gccjit::type result_type, \
                                              gccjit::rvalue a, \
                                              gccjit::rvalue b, \
                                              gccjit::location loc)

   Build a binary operation out of two constituent rvalues.

   Parameter ``loc`` is optional.

   This is a thin wrapper around the C API's
   :c:func:`gcc_jit_context_new_binary_op` and the available binary
   operations are documented there.

There are shorter ways to spell the various specific kinds of binary
operation:

.. function:: gccjit::rvalue \
              gccjit::context::new_plus (gccjit::type result_type, \
                                         gccjit::rvalue a, gccjit::rvalue b, \
                                         gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_minus (gccjit::type result_type, \
                                          gccjit::rvalue a, gccjit::rvalue b, \
                                          gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_mult (gccjit::type result_type, \
                                         gccjit::rvalue a, gccjit::rvalue b, \
                                         gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_divide (gccjit::type result_type, \
                                           gccjit::rvalue a, gccjit::rvalue b, \
                                           gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_modulo (gccjit::type result_type, \
                                           gccjit::rvalue a, gccjit::rvalue b, \
                                           gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_bitwise_and (gccjit::type result_type, \
                                                gccjit::rvalue a, gccjit::rvalue b, \
                                                gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_bitwise_xor (gccjit::type result_type, \
                                                gccjit::rvalue a, gccjit::rvalue b, \
                                                gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_bitwise_or (gccjit::type result_type, \
                                               gccjit::rvalue a, gccjit::rvalue b, \
                                               gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_logical_and (gccjit::type result_type, \
                                                gccjit::rvalue a, gccjit::rvalue b, \
                                                gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_logical_or (gccjit::type result_type, \
                                               gccjit::rvalue a, gccjit::rvalue b, \
                                               gccjit::location loc)

The most concise way to spell them is with overloaded operators:

.. function:: gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue sum = a + b;

.. function:: gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue diff = a - b;

.. function:: gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue prod = a * b;

.. function:: gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue result = a / b;

.. function:: gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue mod = a % b;

.. function:: gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue x = a & b;

.. function:: gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue x = a ^ b;

.. function:: gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue x = a | b;

.. function:: gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = a && b;

.. function:: gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = a || b;

These can of course be combined, giving a terse way to build compound
expressions:

   .. code-block:: c++

      gccjit::rvalue discriminant = (b * b) - (four * a * c);


Comparisons
***********

.. function:: gccjit::rvalue \
              gccjit::context::new_comparison (enum gcc_jit_comparison,\
                                               gccjit::rvalue a, \
                                               gccjit::rvalue b, \
                                               gccjit::location loc)

   Build a boolean rvalue out of the comparison of two other rvalues.

   Parameter ``loc`` is optional.

   This is a thin wrapper around the C API's
   :c:func:`gcc_jit_context_new_comparison` and the available kinds
   of comparison are documented there.

There are shorter ways to spell the various specific kinds of binary
operation:

.. function:: gccjit::rvalue \
              gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)
              gccjit::rvalue \
              gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, \
                                       gccjit::location loc)

The most concise way to spell them is with overloaded operators:

.. function:: gccjit::rvalue \
              operator== (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = (a == ctxt.zero (t_int));

.. function:: gccjit::rvalue \
              operator!= (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = (i != j);

.. function:: gccjit::rvalue \
              operator< (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = i < n;

.. function:: gccjit::rvalue \
              operator<= (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = i <= n;

.. function:: gccjit::rvalue \
              operator> (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = (ch > limit);

.. function:: gccjit::rvalue \
              operator>= (gccjit::rvalue a, gccjit::rvalue b)

   .. code-block:: c++

      gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));

.. TODO: beyond this point

Function calls
**************
.. function:: gcc_jit_rvalue *\
              gcc_jit_context_new_call (gcc_jit_context *ctxt,\
                                        gcc_jit_location *loc,\
                                        gcc_jit_function *func,\
                                        int numargs , gcc_jit_rvalue **args)

   Given a function and the given table of argument rvalues, construct a
   call to the function, with the result as an rvalue.

   .. note::

      :func:`gccjit::context::new_call` merely builds a
      :class:`gccjit::rvalue` i.e. an expression that can be evaluated,
      perhaps as part of a more complicated expression.
      The call *won't* happen unless you add a statement to a function
      that evaluates the expression.

      For example, if you want to call a function and discard the result
      (or to call a function with ``void`` return type), use
      :func:`gccjit::block::add_eval`:

      .. code-block:: c++

         /* Add "(void)printf (arg0, arg1);".  */
         block.add_eval (ctxt.new_call (printf_func, arg0, arg1));

Function pointers
*****************

.. function:: gccjit::rvalue \
	      gccjit::function::get_address (gccjit::location loc)

   Get the address of a function as an rvalue, of function pointer
   type.

Type-coercion
*************

.. function:: gccjit::rvalue \
              gccjit::context::new_cast (gccjit::rvalue rvalue,\
                                         gccjit::type type, \
                                         gccjit::location loc)

   Given an rvalue of T, construct another rvalue of another type.

   Currently only a limited set of conversions are possible:

     * int <-> float
     * int <-> bool
     * P*  <-> Q*, for pointer types P and Q

Lvalues
-------

.. class:: gccjit::lvalue

An lvalue is something that can of the *left*-hand side of an assignment:
a storage area (such as a variable).  It is a subclass of
:class:`gccjit::rvalue`, where the rvalue is computed by reading from the
storage area.

It iss a thin wrapper around :c:expr:`gcc_jit_lvalue *` from the C API.

.. function:: gccjit::rvalue \
              gccjit::lvalue::get_address (gccjit::location loc)

   Take the address of an lvalue; analogous to:

   .. code-block:: c

     &(EXPR)

   in C.

   Parameter "loc" is optional.

Global variables
****************

.. function:: gccjit::lvalue \
              gccjit::context::new_global (enum gcc_jit_global_kind,\
                                           gccjit::type type, \
                                           const char *name, \
                                           gccjit::location loc)

   Add a new global variable of the given type and name to the context.

   This is a thin wrapper around :c:func:`gcc_jit_context_new_global` from
   the C API; the "kind" parameter has the same meaning as there.

Working with pointers, structs and unions
-----------------------------------------

.. function:: gccjit::lvalue \
              gccjit::rvalue::dereference (gccjit::location loc)

   Given an rvalue of pointer type ``T *``, dereferencing the pointer,
   getting an lvalue of type ``T``.  Analogous to:

   .. code-block:: c++

     *(EXPR)

   in C.

   Parameter "loc" is optional.

If you don't need to specify the location, this can also be expressed using
an overloaded operator:

.. function:: gccjit::lvalue \
              gccjit::rvalue::operator* ()

   .. code-block:: c++

      gccjit::lvalue content = *ptr;

Field access is provided separately for both lvalues and rvalues:

.. function:: gccjit::lvalue \
              gccjit::lvalue::access_field (gccjit::field field, \
                                            gccjit::location loc)

   Given an lvalue of struct or union type, access the given field,
   getting an lvalue of the field's type.  Analogous to:

   .. code-block:: c++

      (EXPR).field = ...;

   in C.

.. function:: gccjit::rvalue \
              gccjit::rvalue::access_field (gccjit::field field, \
                                            gccjit::location loc)

   Given an rvalue of struct or union type, access the given field
   as an rvalue.  Analogous to:

   .. code-block:: c++

      (EXPR).field

   in C.

.. function:: gccjit::lvalue \
              gccjit::rvalue::dereference_field (gccjit::field field, \
                                                 gccjit::location loc)

   Given an rvalue of pointer type ``T *`` where T is of struct or union
   type, access the given field as an lvalue.  Analogous to:

   .. code-block:: c++

      (EXPR)->field

   in C, itself equivalent to ``(*EXPR).FIELD``.

.. function:: gccjit::lvalue \
              gccjit::context::new_array_access (gccjit::rvalue ptr, \
                                                 gccjit::rvalue index, \
                                                 gccjit::location loc)

   Given an rvalue of pointer type ``T *``, get at the element `T` at
   the given index, using standard C array indexing rules i.e. each
   increment of ``index`` corresponds to ``sizeof(T)`` bytes.
   Analogous to:

   .. code-block:: c++

      PTR[INDEX]

   in C (or, indeed, to ``PTR + INDEX``).

   Parameter "loc" is optional.

For array accesses where you don't need to specify a :class:`gccjit::location`,
two overloaded operators are available:

    gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)

    .. code-block:: c++

       gccjit::lvalue element = array[idx];

    gccjit::lvalue gccjit::rvalue::operator[] (int index)

    .. code-block:: c++

       gccjit::lvalue element = array[0];

---

### Gcc Jit Docs Cp Topics Functions (`gcc/jit/docs/cp/topics/functions.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Creating and using functions
============================

Params
------
.. class:: gccjit::param

   A `gccjit::param` represents a parameter to a function.

.. function:: gccjit::param \
              gccjit::context::new_param (gccjit::type type,\
                                          const char *name, \
                                          gccjit::location loc)

   In preparation for creating a function, create a new parameter of the
   given type and name.

:class:`gccjit::param` is a subclass of :class:`gccjit::lvalue` (and thus
of :class:`gccjit::rvalue` and :class:`gccjit::object`).  It is a thin
wrapper around the C API's :c:expr:`gcc_jit_param *`.

Functions
---------

.. class:: gccjit::function

   A `gccjit::function` represents a function - either one that we're
   creating ourselves, or one that we're referencing.

.. function::  gccjit::function \
               gccjit::context::new_function (enum gcc_jit_function_kind,\
                                              gccjit::type return_type, \
                                              const char *name, \
                                              std::vector<param> &params, \
                                              int is_variadic, \
                                              gccjit::location loc)

   Create a gcc_jit_function with the given name and parameters.

   Parameters "is_variadic" and "loc" are optional.

   This is a wrapper around the C API's :c:func:`gcc_jit_context_new_function`.

.. function::  gccjit::function \
               gccjit::context::get_builtin_function (const char *name)

   This is a wrapper around the C API's
   :c:func:`gcc_jit_context_get_builtin_function`.

.. function::  gccjit::param \
               gccjit::function::get_param (int index) const

   Get the param of the given index (0-based).

.. function::  void \
               gccjit::function::dump_to_dot (const char *path)

   Emit the function in graphviz format to the given path.

.. function:: gccjit::lvalue \
              gccjit::function::new_local (gccjit::type type,\
                                           const char *name, \
                                           gccjit::location loc)

   Create a new local variable within the function, of the given type and
   name.

Blocks
------
.. class:: gccjit::block

   A `gccjit::block` represents a basic block within a function  i.e. a
   sequence of statements with a single entry point and a single exit
   point.

   :class:`gccjit::block` is a subclass of :class:`gccjit::object`.

   The first basic block that you create within a function will
   be the entrypoint.

   Each basic block that you create within a function must be
   terminated, either with a conditional, a jump, a return, or
   a switch.

   It's legal to have multiple basic blocks that return within
   one function.

.. function::  gccjit::block \
               gccjit::function::new_block (const char *name)

   Create a basic block of the given name.  The name may be NULL, but
   providing meaningful names is often helpful when debugging: it may
   show up in dumps of the internal representation, and in error
   messages.

Statements
----------

.. function:: void\
              gccjit::block::add_eval (gccjit::rvalue rvalue, \
                                       gccjit::location loc)

   Add evaluation of an rvalue, discarding the result
   (e.g. a function call that "returns" void).

   This is equivalent to this C code:

   .. code-block:: c

     (void)expression;

.. function:: void\
              gccjit::block::add_assignment (gccjit::lvalue lvalue, \
                                             gccjit::rvalue rvalue, \
                                             gccjit::location loc)

   Add evaluation of an rvalue, assigning the result to the given
   lvalue.

   This is roughly equivalent to this C code:

   .. code-block:: c

     lvalue = rvalue;

.. function:: void\
              gccjit::block::add_assignment_op (gccjit::lvalue lvalue, \
                                                enum gcc_jit_binary_op, \
                                                gccjit::rvalue rvalue, \
                                                gccjit::location loc)

   Add evaluation of an rvalue, using the result to modify an
   lvalue.

   This is analogous to "+=" and friends:

   .. code-block:: c

     lvalue += rvalue;
     lvalue *= rvalue;
     lvalue /= rvalue;

   etc.  For example:

   .. code-block:: c

     /* "i++" */
     loop_body.add_assignment_op (
       i,
       GCC_JIT_BINARY_OP_PLUS,
       ctxt.one (int_type));

.. function:: void\
              gccjit::block::add_comment (const char *text, \
	                                  gccjit::location loc)

   Add a no-op textual comment to the internal representation of the
   code.  It will be optimized away, but will be visible in the dumps
   seen via :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE`
   and :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE`,
   and thus may be of use when debugging how your project's internal
   representation gets converted to the libgccjit IR.

   Parameter "loc" is optional.

.. function:: void\
              gccjit::block::end_with_conditional (gccjit::rvalue boolval,\
                                                   gccjit::block on_true,\
                                                   gccjit::block on_false, \
                                                   gccjit::location loc)

   Terminate a block by adding evaluation of an rvalue, branching on the
   result to the appropriate successor block.

   This is roughly equivalent to this C code:

   .. code-block:: c

     if (boolval)
       goto on_true;
     else
       goto on_false;

   block, boolval, on_true, and on_false must be non-NULL.

.. function:: void\
              gccjit::block::end_with_jump (gccjit::block target, \
                                            gccjit::location loc)

   Terminate a block by adding a jump to the given target block.

   This is roughly equivalent to this C code:

   .. code-block:: c

      goto target;

.. function:: void\
              gccjit::block::end_with_return (gccjit::rvalue rvalue, \
                                              gccjit::location loc)

   Terminate a block.

   Both params are optional.

   An rvalue must be provided for a function returning non-void, and
   must not be provided by a function "returning" `void`.

   If an rvalue is provided, the block is terminated by evaluating the
   rvalue and returning the value.

   This is roughly equivalent to this C code:

   .. code-block:: c

      return expression;

   If an rvalue is not provided, the block is terminated by adding a
   valueless return, for use within a function with "void" return type.

   This is equivalent to this C code:

   .. code-block:: c

      return;

.. class:: gccjit::case_

   A `gccjit::case_` represents a case within a switch statement, and
   is created within a particular :class:`gccjit::context` using
   :func:`gccjit::context::new_case`.  It is a subclass of
   :class:`gccjit::object`.

   Each case expresses a multivalued range of integer values.  You
   can express single-valued cases by passing in the same value for
   both `min_value` and `max_value`.

.. function:: gccjit::case_ *\
               gccjit::context::new_case (gccjit::rvalue min_value,\
                                          gccjit::rvalue max_value,\
                                          gccjit::block dest_block)

    Create a new gccjit::case for use in a switch statement.
    `min_value` and `max_value` must be constants of an integer type,
    which must match that of the expression of the switch statement.

    `dest_block` must be within the same function as the switch
    statement.

.. function:: void\
              gccjit::block::end_with_switch (gccjit::rvalue expr,\
                                              gccjit::block default_block,\
                                              std::vector <gccjit::case_> cases,\
                                              gccjit::location loc)

   Terminate a block by adding evaluation of an rvalue, then performing
   a multiway branch.

   This is roughly equivalent to this C code:

   .. code-block:: c

     switch (expr)
       {
       default:
         goto default_block;

       case C0.min_value ... C0.max_value:
         goto C0.dest_block;

       case C1.min_value ... C1.max_value:
         goto C1.dest_block;

       ...etc...

       case C[N - 1].min_value ... C[N - 1].max_value:
         goto C[N - 1].dest_block;
     }

   ``expr`` must be of the same integer type as all of the ``min_value``
   and ``max_value`` within the cases.

   The ranges of the cases must not overlap (or have duplicate
   values).

   The API entrypoints relating to switch statements and cases:

      * :func:`gccjit::block::end_with_switch`

      * :func:`gccjit::context::new_case`

   were added in :ref:`LIBGCCJIT_ABI_3`; you can test for their presence
   using

   .. code-block:: c

      #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS

   Here's an example of creating a switch statement:

     .. literalinclude:: ../../../../testsuite/jit.dg/test-switch.cc
       :start-after: /* Quote from here in docs/cp/topics/functions.rst.  */
       :end-before: /* Quote up to here in docs/cp/topics/functions.rst.  */
       :language: c++

---

### Gcc Jit Docs Cp Topics Index (`gcc/jit/docs/cp/topics/index.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

Topic Reference
===============

.. toctree::
   :maxdepth: 2

   contexts.rst
   objects.rst
   types.rst
   expressions.rst
   functions.rst
   locations.rst
   compilation.rst
   asm.rst

---

### Gcc Jit Docs Cp Topics Locations (`gcc/jit/docs/cp/topics/locations.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Source Locations
================

.. class:: gccjit::location

   A `gccjit::location` encapsulates a source code location, so that
   you can (optionally) associate locations in your language with
   statements in the JIT-compiled code, allowing the debugger to
   single-step through your language.

   `gccjit::location` instances are optional: you can always omit them
   from any C++ API entrypoint accepting one.

   You can construct them using :func:`gccjit::context::new_location`.

   You need to enable :c:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` on the
   :class:`gccjit::context` for these locations to actually be usable by
   the debugger:

   .. code-block:: cpp

     ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);

.. function:: gccjit::location \
              gccjit::context::new_location (const char *filename, \
                                             int line, \
                                             int column)

   Create a `gccjit::location` instance representing the given source
   location.

Faking it
---------
If you don't have source code for your internal representation, but need
to debug, you can generate a C-like representation of the functions in
your context using :func:`gccjit::context::dump_to_file()`:

.. code-block:: cpp

  ctxt.dump_to_file ("/tmp/something.c",
                     1 /* update_locations */);

This will dump C-like code to the given path.  If the `update_locations`
argument is true, this will also set up `gccjit::location` information
throughout the context, pointing at the dump file as if it were a source
file, giving you *something* you can step through in the debugger.

---

### Gcc Jit Docs Cp Topics Objects (`gcc/jit/docs/cp/topics/objects.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Objects
=======

.. class:: gccjit::object

Almost every entity in the API (with the exception of
:class:`gccjit::context` and :c:expr:`gcc_jit_result *`) is a
"contextual" object, a :class:`gccjit::object`.

A JIT object:

  * is associated with a :class:`gccjit::context`.

  * is automatically cleaned up for you when its context is released so
    you don't need to manually track and cleanup all objects, just the
    contexts.

The C++ class hierarchy within the ``gccjit`` namespace looks like this::

  +- object
      +- location
      +- type
         +- struct
      +- field
      +- function
      +- block
      +- rvalue
          +- lvalue
             +- param
      +- case_

The :class:`gccjit::object` base class has the following operations:

.. function:: gccjit::context gccjit::object::get_context () const

  Which context is the obj within?

.. function:: std::string gccjit::object::get_debug_string () const

  Generate a human-readable description for the given object.

  For example,

  .. code-block:: c++

     printf ("obj: %s\n", obj.get_debug_string ().c_str ());

  might give this text on stdout:

  .. code-block:: bash

     obj: 4.0 * (float)i

---

### Gcc Jit Docs Cp Topics Types (`gcc/jit/docs/cp/topics/types.rst`)

.. Copyright (C) 2014-2026 Free Software Foundation, Inc.
   Originally contributed by David Malcolm <dmalcolm@redhat.com>

   This is free software: you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT 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
   along with this program.  If not, see
   <https://www.gnu.org/licenses/>.

.. default-domain:: cpp

Types
=====

.. class:: gccjit::type

   gccjit::type represents a type within the library.  It is a subclass
   of :class:`gccjit::object`.

Types can be created in several ways:

* fundamental types can be accessed using
  :func:`gccjit::context::get_type`:

  .. code-block:: c++

      gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);

  or using the :func:`gccjit::context::get_int_type<T>` template:

  .. code-block:: c++

      gccjit::type t = ctxt.get_int_type <unsigned short> ();

  See :c:func:`gcc_jit_context_get_type` for the available types.

* derived types can be accessed by using functions such as
  :func:`gccjit::type::get_pointer` and :func:`gccjit::type::get_const`:

  .. code-block:: c++

    gccjit::type const_int_star = int_type.get_const ().get_pointer ();
    gccjit::type int_const_star = int_type.get_pointer ().get_const ();

* by creating structures (see below).

Standard types
--------------

.. function:: gccjit::type gccjit::context::get_type (enum gcc_jit_types)

   Access a specific type.  This is a thin wrapper around
   :c:func:`gcc_jit_context_get_type`; the parameter has the same meaning.

.. function:: gccjit::type \
              gccjit::context::get_int_type (size_t num_bytes, int is_signed)

   Access the integer type of the given size.

.. function:: template<typename T> gccjit::type \
              gccjit::context::get_int_type <T> ()

   Access the given integer type.  For example, you could map the
   ``unsigned short`` type into a gccjit::type via:

   .. code-block:: c++

      gccjit::type t = ctxt.get_int_type <unsigned short> ();

Pointers, `const`, and `volatile`
---------------------------------

.. function::  gccjit::type gccjit::type::get_pointer ()

   Given type "T", get type "T*".

.. function::  gccjit::type gccjit::type::get_const ()

   Given type "T", get type "const T".

.. function::  gccjit::type gccjit::type::get_volatile ()

   Given type "T", get type "volatile T".

.. function::  gccjit::type gccjit::type::get_aligned (size_t alignment_in_bytes)

   Given type "T", get type:

   .. code-block:: c

      T __attribute__ ((aligned (ALIGNMENT_IN_BYTES)))

   The alignment must be a power of two.

.. function::  gccjit::type \
               gccjit::context::new_array_type (gccjit::type element_type, \
                                                int num_elements, \
			                        gccjit::location loc)

   Given type "T", get type "T[N]" (for a constant N).
   Param "loc" is optional.


Vector types
------------

.. function::  gccjit::type gccjit::type::get_vector (size_t num_units)

   Given type "T", get type:

   .. code-block:: c

      T  __attribute__ ((vector_size (sizeof(T) * num_units))

   T must be integral or floating point; num_units must be a power of two.


Structures and unions
---------------------

.. class:: gccjit::struct_

A compound type analogous to a C `struct`.

:class:`gccjit::struct_` is a subclass of :class:`gccjit::type` (and thus
of :class:`gccjit::object` in turn).

.. class:: gccjit::field

A field within a :class:`gccjit::struct_`.

:class:`gccjit::field` is a subclass of :class:`gccjit::object`.

You can model C `struct` types by creating :class:`gccjit::struct_` and
:class:`gccjit::field` instances, in either order:

* by creating the fields, then the structure.  For example, to model:

  .. code-block:: c

    struct coord {double x; double y; };

  you could call:

  .. code-block:: c++

    gccjit::field field_x = ctxt.new_field (double_type, "x");
    gccjit::field field_y = ctxt.new_field (double_type, "y");
    std::vector fields;
    fields.push_back (field_x);
    fields.push_back (field_y);
    gccjit::struct_ coord = ctxt.new_struct_type ("coord", fields);

* by creating the structure, then populating it with fields, typically
  to allow modelling self-referential structs such as:

  .. code-block:: c

    struct node { int m_hash; struct node *m_next; };

  like this:

  .. code-block:: c++

    gccjit::struct_ node = ctxt.new_opaque_struct_type ("node");
    gccjit::type node_ptr = node.get_pointer ();
    gccjit::field field_hash = ctxt.new_field (int_type, "m_hash");
    gccjit::field field_next = ctxt.new_field (node_ptr, "m_next");
    std::vector fields;
    fields.push_back (field_hash);
    fields.push_back (field_next);
    node.set_fields (fields);

.. FIXME: the above API doesn't seem to exist yet

.. function:: gccjit::field \
              gccjit::context::new_field (gccjit::type type,\
                                          const char *name, \
                                          gccjit::location loc)

   Construct a new field, with the given type and name.

.. function:: gccjit::struct_ \
   gccjit::context::new_struct_type (const std::string &name,\
                                     std::vector<field> &fields,\
                                     gccjit::location loc)

     Construct a new struct type, with the given name and fields.

.. function:: gccjit::struct_ \
              gccjit::context::new_opaque_struct (const std::string &name, \
                                                  gccjit::location loc)

     Construct a new struct type, with the given name, but without
     specifying the fields.   The fields can be omitted (in which case the
     size of the struct is not known), or later specified using
     :c:func:`gcc_jit_struct_set_fields`.

---

--- METRICS ---
- Files Extracted: 96
- Estimated Token Budget: ~596112 tokens
- Canonical Reference: https://codewiki.google/github.com/gcc-mirror/gcc
